Hasura permissions to fetch data depending on users block status - postgresql

I've got these tables:
Table blocked_users
id (pk) | initiator_id (fk) | target_id (fk)
1 | a | b
Table post
id (pk) | author_profile (fk)
1 | a
2 | b
3 | c
4 | d
I'm trying to get my head around the proper select permissions, I've tried many combinations and I cannot get the desired result -> Get the posts and exclude the users that either I have blocked or they have blocked me.
This is one of the many permissions I've tried:
blocked_by_me is blocked_users.initiator_id → author_profile.id
been_blocked_by is blocked_users.target_id → author_profile.id
{
"_and": [
{ "deleted_at": { "_is_null": true } },
{ "author_profile": { "deleted_at": { "_is_null": true } } },
{
"_and": [
{
"author_profile": {
"been_blocked_by": {
"initiator_id": {
"_eq": "X-Hasura-User-Id"
}
}
}
},
{
"author_profile": {
"blocked_by_me": {
"initiator_id": {
"_eq": "X-Hasura-User-Id"
}
}
}
}
]
}
]
}
And one of the many queries I tried: (with no permissions on post)
query GetPosts(
$created_at: order_by = desc
$limit: Int! = 12
$offset: Int! = 0
) {
post(
limit: $limit
offset: $offset
order_by: { created_at: $created_at }
where: {
_not: {
author_profile: {
_or: [
{
been_blocked_by: { initiator_id: { _eq: "a" } }
blocked_by_me: { target_id: { _neq: "b" } }
}
]
}
}
_and: {
deleted_at: { _is_null: true }
author_profile: { deleted_at: { _is_null: true } }
}
}
) {
author_profile {
id
first_name
}
}
}
With the query above, if a user has made a post and that user's id does not exist on blocked_users then the post of that user won't be returned by the query, in other words, the query returns only the posts of the users that have at least one record on blocked_users (not blocked by me or that user have not blocked me).

Get the posts and exclude the users that either I have blocked or they have blocked me.
You want your select permission exclude the posts from users who either blocked you or are blocked by you. Using the same array relationships that you have, we can write a permission for post like:
{
"_not": {
"_or": [
{
"author_profile": {
"been_blocked_by": { "initiator_id": { "_eq": "X-Hasura-User-Id" } }
}
},
{
"author_profile": {
"blocked_by_me": { "target_id": { "_eq": "X-Hasura-User-Id" } }
}
}
]
}
}
We are basically telling Hasura to only show the posts that are _not by authors who have been_blocked_by us _or by authors who blocked us.

Related

filter a table with multiple association table column with sequelize node.js

I have given a function, where I want to filter gigs with multiple association table column(actually when I will select Business column name it will show gigs associate with Business and also select GigType column name, gigs will be shown with both association(Business and GigType table) ).
async advanceGigSearch(category, data=null, limit=10, offset=0) {
try {
if(Object.keys(data).length == 0) {
return await Gig.findAndCountAll();
} else {
return await Gig.findAndCountAll({
include:[
{
model:Business,
where: {
...data,
name: {
[Op.iLike]:`%${data.name ? data.name: ""}%`
}
}
},
{
model: GigType,
where: {
...data,
name: {
[Op.iLike]:`%${data.name ? data.name: ""}%`
}
}
},
{
model: GigDetails,
where: {
...data,
name: {
[Op.iLike]:`%${data.name ? data.name: ""}%`
}
}
},
],
order: [["title", "DESC"]],
distinct: true,
limit,
offset,
});
}
} catch(err) {
console(err, `${this.model.name} get`)
throw createError(500);
}
}
I want to filter with multiple association table.

get github issues by their ids through graphql endpoints

I am trying to get the list of issues by their ids from Github using graphql, but looks like I am missing something or its not possible.
query ($ids:['517','510']!) {
repository(owner:"owner", name:"repo") {
issues(last:20, states:CLOSED) {
edges {
node {
title
url
body
author{
login
}
labels(first:5) {
edges {
node {
name
}
}
}
}
}
}
}
}
The above query is giving me response as below,
{
"errors": [
{
"message": "Parse error on \"'\" (error) at [1, 14]",
"locations": [
{
"line": 1,
"column": 14
}
]
}
]
}
Kindly help me identify if its possible or that I am doing something wrong here.
You can use aliases in order to build a single request requesting multiple issue object :
{
repository(name: "material-ui", owner: "mui-org") {
issue1: issue(number: 2) {
title
createdAt
}
issue2: issue(number: 3) {
title
createdAt
}
issue3: issue(number: 10) {
title
createdAt
}
}
}
Try it in the explorer
which gives :
{
"data": {
"repository": {
"issue1": {
"title": "Support for ref's on Input component",
"createdAt": "2014-10-15T15:49:13Z"
},
"issue2": {
"title": "Unable to pass onChange event to Input component",
"createdAt": "2014-10-15T16:23:28Z"
},
"issue3": {
"title": "Is it possible for me to make this work if I'm using React version 0.12.0?",
"createdAt": "2014-10-30T14:11:59Z"
}
}
}
}
This request can also be simplified using fragments to prevent repetition:
{
repository(name: "material-ui", owner: "mui-org") {
issue1: issue(number: 2) {
...IssueFragment
}
issue2: issue(number: 3) {
...IssueFragment
}
issue3: issue(number: 10) {
...IssueFragment
}
}
}
fragment IssueFragment on Issue {
title
createdAt
}
The request can be built programmatically, such as in this example python script :
import requests
token = "YOUR_TOKEN"
issueIds = [2,3,10]
repoName = "material-ui"
repoOwner = "mui-org"
query = """
query($name: String!, $owner: String!) {
repository(name: $name, owner: $owner) {
%s
}
}
fragment IssueFragment on Issue {
title
createdAt
}
"""
issueFragments = "".join([
"""
issue%d: issue(number: %d) {
...IssueFragment
}""" % (t,t) for t in issueIds
])
r = requests.post("https://api.github.com/graphql",
headers = {
"Authorization": f"Bearer {token}"
},
json = {
"query": query % issueFragments,
"variables": {
"name": repoName,
"owner": repoOwner
}
}
)
print(r.json()["data"]["repository"])
I don't think you can fetch for issues and pass in an array of integers for their ids.
But you can search for a single issue by id like so (this works for me)
query ($n: Int!) {
repository(owner:"owner", name:"repo-name") {
issue (number: $n) {
state
title
author {
url
}
}
}
}
where $n is {"n": <your_number>} defined.
If you have an array of ids, then you can just make multiple queries to GitHub.
Sadly, with this approach, you cannot specify what the state of the issue to be. But I think the logic is that once you know the issue Id, you shouldn't care what state it is, since you have that exact id.

GraphQL query to get file info from GitHub repository

I would like to use GitHub repository for posts in my Gatsby site. Right now I'm using two queries, first to get the names of the files:
{
viewer {
repository(name: "repository-name") {
object(expression: "master:") {
id
... on Tree {
entries {
name
}
}
}
pushedAt
}
}
}
And the second to get the contents of the files:
{
viewer {
repository(name: "repository-name") {
object(expression: "master:file.md") {
... on Blob {
text
}
}
}
}
}
Is there any way to get information about when each file was created and last updated with GraphQL? Right now I can get only pushedAt for the whole repository and not individual files.
You can use the following query to get the file content and at the same time getting the last commit for this file. This way you also get the fields pushedAt, committedDate and authorDate depending on what you need :
{
repository(owner: "torvalds", name: "linux") {
content: object(expression: "master:Makefile") {
... on Blob {
text
}
}
info: ref(qualifiedName: "master") {
target {
... on Commit {
history(first: 1, path: "Makefile") {
nodes {
author {
email
}
message
pushedDate
committedDate
authoredDate
}
pageInfo {
endCursor
}
totalCount
}
}
}
}
}
}
Note that we need to also get the endCursor field in order to get the first commit on the file (to get the file creation date)
For instance on the Linux repo, for the Makefile file it gives:
"pageInfo": {
"endCursor": "b29482fde649c72441d5478a4ea2c52c56d97a5e 0"
}
"totalCount": 1806
So there are 1806 commit for this file
In order to get the first commit, a query referencing the last cursor which would be b29482fde649c72441d5478a4ea2c52c56d97a5e 1804:
{
repository(owner: "torvalds", name: "linux") {
info: ref(qualifiedName: "master") {
target {
... on Commit {
history(first: 1, after:"b29482fde649c72441d5478a4ea2c52c56d97a5e 1804", path: "Makefile") {
nodes {
author {
email
}
message
pushedDate
committedDate
authoredDate
}
}
}
}
}
}
}
which returns the first commit of this file.
I don't have any source about the cursor string format "b29482fde649c72441d5478a4ea2c52c56d97a5e 1804", I've tested with some other repositories with files with more than 1000 commits and it seems that it's always formatted like :
<static hash> <incremented_number>
which avoid to iterate over all the commits in case that there is more than 100 commits referencing your file
Here is an implementation in javascript using graphql.js :
const graphql = require('graphql.js');
const token = "YOUR_TOKEN";
const queryVars = { name: "linux", owner: "torvalds" };
const file = "Makefile";
const branch = "master";
var graph = graphql("https://api.github.com/graphql", {
headers: {
"Authorization": `Bearer ${token}`,
'User-Agent': 'My Application'
},
asJSON: true
});
graph(`
query ($name: String!, $owner: String!){
repository(owner: $owner, name: $name) {
content: object(expression: "${branch}:${file}") {
... on Blob {
text
}
}
info: ref(qualifiedName: "${branch}") {
target {
... on Commit {
history(first: 1, path: "${file}") {
nodes {
author {
email
}
message
pushedDate
committedDate
authoredDate
}
pageInfo {
endCursor
}
totalCount
}
}
}
}
}
}
`)(queryVars).then(function(response) {
console.log(JSON.stringify(response, null, 2));
var totalCount = response.repository.info.target.history.totalCount;
if (totalCount > 1) {
var cursorPrefix = response.repository.info.target.history.pageInfo.endCursor.split(" ")[0];
var nextCursor = `${cursorPrefix} ${totalCount-2}`;
console.log(`total count : ${totalCount}`);
console.log(`cursorPrefix : ${cursorPrefix}`);
console.log(`get element after cursor : ${nextCursor}`);
graph(`
query ($name: String!, $owner: String!){
repository(owner: $owner, name: $name) {
info: ref(qualifiedName: "${branch}") {
target {
... on Commit {
history(first: 1, after:"${nextCursor}", path: "${file}") {
nodes {
author {
email
}
message
pushedDate
committedDate
authoredDate
}
}
}
}
}
}
}`)(queryVars).then(function(response) {
console.log("first commit info");
console.log(JSON.stringify(response, null, 2));
}).catch(function(error) {
console.log(error);
});
}
}).catch(function(error) {
console.log(error);
});

Github API - How to know if an issue was closed by a fork pull request?

How can I know given an closed issue, if it was closed through a pull request, specifically through a fork pull request, and how can I get the Id of the fork?
I've been reading in the issues/pull request/events API docs but haven't found anything.
It's possible using GraphQL API v4 using timelineItems and filtering on event with state CLOSED_EVENT
{
repository(name: "material-ui", owner: "mui-org") {
issue(number: 19641) {
timelineItems(itemTypes: CLOSED_EVENT, last: 1) {
nodes {
... on ClosedEvent {
createdAt
closer {
...on PullRequest {
baseRefName
baseRepository {
nameWithOwner
}
headRefName
headRepository {
nameWithOwner
}
}
}
}
}
}
}
}
}
Try it in the explorer
The closer field contains the source of the closing :
via pull request: PullRequest
via commit messages: Commit
or via the closed button: null
The following requests are example for the 3 types of closing
Closing via pull request
This pull request closed this issue
{
repository(name: "material-ui", owner: "mui-org") {
issue(number: 19641) {
timelineItems(itemTypes: CLOSED_EVENT, last: 1) {
nodes {
... on ClosedEvent {
createdAt
closer {
__typename
}
}
}
}
}
}
}
Output
{
"data": {
"repository": {
"issue": {
"timelineItems": {
"nodes": [
{
"createdAt": "2020-05-20T09:06:11Z",
"closer": {
"__typename": "PullRequest"
}
}
]
}
}
}
}
}
Closing via commit message
This commit closed this issue
{
repository(name: "rubinius", owner: "rubinius") {
issue(number: 1536) {
timelineItems(itemTypes: CLOSED_EVENT, last: 1) {
nodes {
... on ClosedEvent {
createdAt
closer {
__typename
}
}
}
}
}
}
}
Output
{
"data": {
"repository": {
"issue": {
"timelineItems": {
"nodes": [
{
"createdAt": "2012-01-30T22:33:11Z",
"closer": {
"__typename": "Commit"
}
}
]
}
}
}
}
}
Closing via button
This issue was closed via the close button :
{
repository(name: "rubinius", owner: "rubinius") {
issue(number: 3830) {
timelineItems(itemTypes: CLOSED_EVENT, last: 1) {
nodes {
... on ClosedEvent {
createdAt
closer {
__typename
}
}
}
}
}
}
}
Output
{
"data": {
"repository": {
"issue": {
"timelineItems": {
"nodes": [
{
"createdAt": "2020-02-02T22:31:05Z",
"closer": null
}
]
}
}
}
}
}

GitHub Graphql : Getting sponsor tier information for the sponsors of a user

I am using the GitHub graphql for getting the sponsor information of a user. While I am able to get the sponsors for a particular user, I am unable to get the sponsorship-tier information for the sponsors. The graphql query that I have written is as follows:
{
user(login: <<loginID>>) {
name
sponsorshipsAsMaintainer(first: 1) {
totalCount
nodes {
createdAt
privacyLevel
tier {
createdAt
name
description
}
sponsor {
login
}
}
}
}
}
The results i get for a user are as follows. Ideally, in the query I was hoping to get the tier information but the result returns a null for the tier field.
{
"data": {
"user": {
"name": "XXX",
"sponsorshipsAsMaintainer": {
"totalCount": 11,
"nodes": [
{
"createdAt": "2020-02-16T10:39:14Z",
"privacyLevel": "PUBLIC",
"tier": null,
"sponsor": {
"login": "XXX"
}
}
]
}
}
}
}
Any help or information to get the tier information for a sponsor would be appreciated. Thank you very much.
To date tier is still null and I haven't figured out what's the issue with that.
However I managed to fetch the tiers information using the following query:
query getTiers($login: String!) {
user(login: $login) {
sponsorshipsAsSponsor(first: 1) {
nodes {
sponsorable {
sponsorsListing {
tiers(first: 5) {
nodes {
id
}
}
}
}
}
}
}
}
I'm using the following query to look up sponsors, and I only get tier information for my own tiers. I assume the viewer's databaseId must match the sponsorable databaseId to see this information
query {
user(login: "${login}") {
sponsorshipsAsSponsor(first: 100) {
nodes {
privacyLevel
tier {
monthlyPriceInDollars
}
sponsorable {
... on User {
databaseId
}
... on Organization {
databaseId
}
}
}
}
}
}
Here is a user that is sponsoring three other projects besides mine (I replaced the other project's databaseIds)
{
"data": {
"user": {
"sponsorshipsAsSponsor": {
"nodes": [
{
"privacyLevel": "PUBLIC",
"tier": {
"monthlyPriceInDollars": 3
},
"sponsorable": {
"databaseId": 220908 <--- Me
}
},
{
"privacyLevel": "PUBLIC",
"tier": null,
"sponsorable": {
"databaseId": 1
}
},
{
"privacyLevel": "PUBLIC",
"tier": null,
"sponsorable": {
"databaseId": 1
}
},
{
"privacyLevel": "PUBLIC",
"tier": null,
"sponsorable": {
"databaseId": 1
}
}
]
}
}
}
}