Hi all I was looking on the graphcool example but ...
# prisma-whats-new
d
Hi all I was looking on the graphcool example but I'm not sure how to implement it...What I would to do is:
given the authenticated user (token) I would like to retrieve all the companies related to his organization
. I know that I can write a filter on apollo-client but I would like to do that on the graphcool. The question is I have to do a query or a handler function?
i
You can:
Copy code
{
  allUsers(filter: { username: "some-username" }) {
    companies {
      id
      companyName
      # etc
    }
  }
}
d
hi @iamclaytonray
but this is in the graphcool or in the appollo-client?
i
So when you query
allUsers
or even just a
User
, filter the User and just query the companies
This is just a normal GraphQL query. This can be implemented either on the server or client
d
sorry but is the opposite
I want to display all the companies that the user can see
my schema is : Oranization, Companies
i
One sec
Actually, what is the “User”? The Organization?
Or do you also have a User in the Schema?
d
Copy code
type Organization @model {
  id: ID! @isUnique
  name: String!
  companies: [Company!]! @relation(name: "CompanyOnOrganization")
}

type Company @model {
  id: ID! @isUnique
  name: String!
  color: String
  logo: String
  organization: Organization @relation(name: "CompanyOnOrganization")
  users: [User!]! @relation(name: "UserOnCompany")
}
i
That’s your entire Schema?
If so, your relationship for
UserOnCompany
shouldn’t work, if you don’t have a User type
d
@iamclaytonray sorry but I don't think I'm explaining properly the problem
let's say that we have 4 companies, 2 for the 1 organization and 2 for the second one....what I want to achieve is that the logged in user have to be able to see only 2 companies and not the other 2
the entire schema is:
Copy code
type Organization @model {
  id: ID! @isUnique
  name: String!
  companies: [Company!]! @relation(name: "CompanyOnOrganization")
}

type Company @model {
  id: ID! @isUnique
  name: String!
  color: String
  logo: String
  organization: Organization @relation(name: "CompanyOnOrganization")
  users: [User!]! @relation(name: "UserOnCompany")
}

type User @model {
  id: ID! @isUnique
  createdAt: DateTime!
  updatedAt: DateTime!
  email: String! @isUnique
  password: String!
  name: String!
  surname: String!
  company: Company @relation(name: "UserOnCompany")
}
i
Give me a few minutes and I’ll get something back to you 🙂
d
awesome thanks
i
Sorry - crazy day
d
don't worry @iamclaytonray I can wait
l
Hi there, we probably have the same problem. I guess you could do it with a simple filter, but is it also possible via permission query? Since it would be pretty easy to manipulate the query from the frontend in order to see organisations the User do not actually belong to. greetings 🙂
i
I just woke up so I’ll finish the example. Yesterday was thanksgiving
So…
If the response payload from the
Copy code
{
  allOrganizations {
    id
    name
    companies {
      id
      name
    }
  }
}
query looks like this:
Copy code
{
  "data": {
    "allOrganizations": [
      {
        "id": "cjachl8h83x490109479olvfh",
        "name": "Org 1",
        "companies": [
          {
            "id": "cjachk82xdvhs0173qw3cjdah",
            "name": "Company 1"
          },
          {
            "id": "cjachkbjqdvig01732ymepajy",
            "name": "Company 2"
          }
        ]
      },
      {
        "id": "cjachlbtu3x4s0109rbmd5pkr",
        "name": "Org 2",
        "companies": [
          {
            "id": "cjacjejpudm8e0112px5j3a06",
            "name": "Company 3"
          },
          {
            "id": "cjacjelebdm8k0112anbcbh2d",
            "name": "Company 4"
          }
        ]
      }
    ]
  }
}
But we wanted to only get the User’s company he/she belongs to:
Copy code
{
  User(email: "<mailto:john@gmail.com|john@gmail.com>") {
    name
    company {
      name
      organization {
        name
      }
    }
  }
}
And the payload would look like:
Copy code
{
  "data": {
    "User": {
      "name": "John Doe",
      "company": {
        "name": "Company 1",
        "organization": {
          "name": "Org 1"
        }
      }
    }
  }
}
I don’t really want to set up permissions but the same concept applies
You could just query
currentUser
As long as you set up the relationships correctly, you shouldn’t need to do anything crazy with filtering or anything like that. As it stands right now, I can only access other Users’ companies/orgs if I replaced the email with their email. If I set up permissions, then I would only be able to query my (
<mailto:john@gmail.com|john@gmail.com>
) account and other relevant data
The only time I see filtering being necessary is on
allUsers
Obviously, when you query a single User, there is no need for filtering the User’s company. (Based on the schema, the User only has 1 company)
Copy code
{
  allUsers(filter: { company: { users_every: { email: "<mailto:john@gmail.com|john@gmail.com>" } } }) {
    id
    company {
      name
      organization {
        name
      }
    }
  }
}
would return:
Copy code
{
  "data": {
    "allUsers": [
      {
        "id": "cja0zkue9mo540143kcvmbvdq",
        "company": {
          "name": "Company 1",
          "organization": {
            "name": "Org 1"
          }
        }
      }
    ]
  }
}
^ You could mis-match queries. For example, query the User. Company. Organization. Then you would just change up the data requirements based on the resource you are asking for
d
hey @iamclaytonray I saw your queries and they make sense...but what about if I do something like that instead:
Copy code
- operation: 'Company.read'
    authenticated: true
    query: src/permissions/Company.graphql:RetrieveCompanyData
Is your logic still valid?
so we put inside Company.graphql
{ allUsers(filter: { company: { users_every: { email: "john@gmail.com" } } }) { id company { name organization { name } } } }
there's no way to retrieve the user form the
Authorization
token?
i
It should with the correct token
Let me try it out real quick
❤️ 1
Sorry, the console is going super slow 😕
Well, not really working, haha
d
ugh
i
If I can’t get it to work, I’ll just upgrade it and test it out locally
d
@iamclaytonray any news?
i
Local isn’t working for me right now 😕
d
oh but you don't have a docker? I'm doing everthing there
I just deployed in my docker container
i
I have Docker
It’s just not working
d
ugh
weird
and online?
i
Nope
Today just isn’t my day, haha
d
😂
Hey @iamclaytonray any luck?
i
Yep
Sorry
The query still works as long as the User has the token
d
but I need to pass the email?
Copy code
{
  allUsers(filter: { company: { users_every: { email: "<mailto:john@gmail.com|john@gmail.com>" } } }) {
    id
    company {
      name
      organization {
        name
      }
    }
  }
}
it can't retrieve from the
Authorization token
i
That was actually a bad example.
d
sorry for bothering you so much I'm just trying to understand the best way to do it and try to became independent after that
so just to recap the idea was to use that:
Copy code
- operation: 'Company.read'
    authenticated: true
    query: src/permissions/Company.graphql:RetrieveCompanyData
and what I don't know how to do properly
src/permissions/Company.graphql:RetrieveCompanyData
i
Replace
query
with:
Copy code
handler:
      code: src/RetrieveCompanyData.ts
Or whatever the actual file is
d
fine
and the file contain?
i
Oh, sorry… 😕
One sec, haha
Remove the
:RetrieveCompanyData
from your
query
Actually… Ahh
I’m actually not sure, haha
d
Ok I'm confused...do you remember the requirements right? Otherwise I'll give you back
i
Yeah, I remember. I just never quite get stuff right in my
graphcool.yml
😕
Haha
d
🙂
i
Maybe @nilan or @agartha could help out
Heading to the doctor and doing this on my phone is hard
d
😞
<https://www.graph.cool/forum/t/filter-companies-by-organizations/1713>
I posted on the forum as well
i
🙂
a
What defines which companies a user can see?
All the companies in the same organization as the company that the user belongs to?
@daniele ^
d
@agartha
Copy code
type Organization @model {
  id: ID! @isUnique
  name: String!
  companies: [Company!]! @relation(name: "CompanyOnOrganization")
}

type Company @model {
  id: ID! @isUnique
  name: String!
  color: String
  logo: String
  organization: Organization @relation(name: "CompanyOnOrganization")
  users: [User!]! @relation(name: "UserOnCompany")
}

type User @model {
  id: ID! @isUnique
  createdAt: DateTime!
  updatedAt: DateTime!
  email: String! @isUnique
  password: String!
  name: String!
  surname: String!
  company: Company @relation(name: "UserOnCompany")
}
1 Organization has multiple companies, 1 user belong to 1 company
a
Yes I got that part. My question is: which companies is a user allowed to see? Only his own company? Or all companies in the organization of his own company? What's the exact requirement?
d
all the companies in this organization
👍🏻 1
a
Seems like
Company.read
should be something like:
Copy code
SomeCompanyExists(filter: { organization: { companies_some: { users_some: { id: $user_id } } } })
Translated: For every company, check if the organization it belongs to has any company that has any user with the id of our current user
d
correct
the only thing is that I would like to use the Authorization token
instead to pass the email
a
Did you see email anywhere in my permission query?
I'm using
$user_id
, which is the user id from the Authorization token
d
sorry my bad I was looking the other one
👍🏻 1
but we pass in any case the $user id
a
That comes from the token
No need to pass it manually
d
oh so just to recap:
Copy code
- operation: 'Company.read'
    authenticated: true
    query: src/permissions/Company.graphql:RetrieveCompanyData
where
RetrieveCompanyData
is:
Copy code
RetrieveCompanyData(filter: { organization: { companies_some: { users_some: { id: $user_id } } } })
and it magically work
a
Copy code
query RetrieveCompanyData($user_id: ID!) {
   SomeCompanyExists(filter: { organization: { companies_some: { users_some: { id: $user_id } } } })
}
You mixed up the syntax a bit
^^ That's what you put in Company.graphql
d
oh ok .. and it will take the $user_id automatically
so I'll just do
allCompanies { id , name}
and that's all
( from my client - apollo )
a
Yes, the only problem with permission queries is that they don't 'really' filter the results, just precent access to them
So you will get insufficient permissions errors
That you need to ignore on the client
d
got it
I just need to extract the object with the result and ignore the other part
a
Yes, the best thing to do is check the error code, so you only ignore permission errors, and not any other errors
d
and using a handler function doesn't help right?
a
Handler function?
d
Copy code
handler:
      code: src/RetrieveCompanyData.ts
something like that
a
No, because you cannot return model types from extension functions
d
got it thanks
👍🏻 1
I think that it didn't like it...I'm still receiving all the companies
from my apollo-client:
Copy code
private getAirlines = gql`{
        allCompanies {
            id
            name
            color
        }
    }`;
I'm receiving 2 companies instead one
and without errors
just to show you the data from my console:
doing a query for all Users:
Copy code
{
  "data": {
    "allUsers": [
      {
        "id": "cja5p7jqj00n401489881zjsh",
        "name": "Daniele",
        "email": "<mailto:superAdmin@admin.com|superAdmin@admin.com>",
        "company": null
      },
      {
        "id": "cja5pc1eb00oa0148jt5c8ehv",
        "name": "Daniele",
        "email": "<mailto:IAGAdmin@admin.com|IAGAdmin@admin.com>",
        "company": {
          "name": "Iberia",
          "id": "cja5f6uh400vc0148jowhza3i"
        }
      },
      {
        "id": "cja5pc9a600ok0148nhtalk42",
        "name": "Daniele",
        "email": "<mailto:GateAdmin@admin.com|GateAdmin@admin.com>",
        "company": {
          "name": "Air Canada",
          "id": "cja5pfodm00ow01489pvn2gwn"
        }
      }
    ]
  }
}
I've loggedin as
<mailto:GateAdmin@admin.com|GateAdmin@admin.com>
and I'm receiving instead:
Copy code
{
  "data": {
    "allCompanies": [
      {
        "id": "cja5f6uh400vc0148jowhza3i",
        "name": "Iberia",
        "color": "#fd272f",
        "__typename": "Company"
      },
      {
        "id": "cja5pfodm00ow01489pvn2gwn",
        "name": "Air Canada",
        "color": "#ee2c30",
        "__typename": "Company"
      }
    ]
  }
}
@agartha
a
And they belong to a different organization?
d
Si I give you the other queries as well
Copy code
{
  "data": {
    "allOrganizations": [
      {
        "id": "cja5f3h1j00v001489mtj7s81",
        "name": "IAG"
      },
      {
        "id": "cja5f3pl300v40148fu0xb1n1",
        "name": "Gate Gourmet"
      }
    ]
  }
}
Copy code
{
  "data": {
    "allCompanies": [
      {
        "name": "Iberia",
        "organization": {
          "name": "IAG"
        }
      },
      {
        "name": "Air Canada",
        "organization": {
          "name": "Gate Gourmet"
        }
      }
    ]
  }
}
Copy code
{
  "data": {
    "allUsers": [
      {
        "id": "cja5p7jqj00n401489881zjsh",
        "name": "Daniele",
        "email": "<mailto:superAdmin@admin.com|superAdmin@admin.com>",
        "company": null
      },
      {
        "id": "cja5pc1eb00oa0148jt5c8ehv",
        "name": "Daniele",
        "email": "<mailto:IAGAdmin@admin.com|IAGAdmin@admin.com>",
        "company": {
          "name": "Iberia",
          "id": "cja5f6uh400vc0148jowhza3i"
        }
      },
      {
        "id": "cja5pc9a600ok0148nhtalk42",
        "name": "Daniele",
        "email": "<mailto:GateAdmin@admin.com|GateAdmin@admin.com>",
        "company": {
          "name": "Air Canada",
          "id": "cja5pfodm00ow01489pvn2gwn"
        }
      }
    ]
  }
}
it's enough?
my schema:
a
Did you deploy your changes?
d
I did
Copy code
permissions:
  - operation: 'Company.read'
    authenticated: true
    query: src/permissions/Company.graphql:RetrieveCompanyData
Copy code
query RetrieveCompanyData($user_id: ID!) {
   SomeCompanyExists(filter: 
        { 
            organization: { 
                companies_some: { 
                    users_some: { 
                        id: $user_id 
                    } 
                } 
            } 
        }
    )
}
Copy code
Permissions

  Wildcard Permission
   - The wildcard permission for all types is removed.

Here are your GraphQL Endpoints:

  Simple API:        <http://localhost:60000/simple/v1/cj9n8k2ua00040148cpfxjp6p>
  Relay API:         <http://localhost:60000/relay/v1/cj9n8k2ua00040148cpfxjp6p>
  Subscriptions API: <ws://localhost:60000/subscriptions/v1/cj9n8k2ua00040148cpfxjp6p>
a
Ow wait
The permission query is wrong after all
Copy code
query RetrieveCompanyData($user_id: ID!, $node_id: ID!) {
   SomeCompanyExists(filter: 
        { 
            id: $node_id
            organization: { 
                companies_some: { 
                    users_some: { 
                        id: $user_id 
                    } 
                } 
            } 
        }
    )
}
The previous permission query was always true, sorry...
d
well now is always false
Copy code
{
  "data": null,
  "errors": [
    {
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ],
      "path": [
        "allCompanies",
        1,
        "id"
      ],
      "code": 3008,
      "message": "Insufficient Permissions",
      "requestId": "eu-west-1:simple:cjafidkc201vo0148gbdjp84z"
    },
    {
      "locations": [
        {
          "line": 4,
          "column": 5
        }
      ],
      "path": [
        "allCompanies",
        1,
        "name"
      ],
      "code": 3008,
      "message": "Insufficient Permissions",
      "requestId": "eu-west-1:simple:cjafidkc201vo0148gbdjp84z"
    },
    {
      "locations": [
        {
          "line": 5,
          "column": 5
        }
      ],
      "path": [
        "allCompanies",
        1,
        "color"
      ],
      "code": 3008,
      "message": "Insufficient Permissions",
      "requestId": "eu-west-1:simple:cjafidkc201vo0148gbdjp84z"
    }
  ]
}
@agartha
@nilan CC ( I replied on the forum as well)
@nilan I posted all the info that you asked
a
@nilan and I both came to the same conclusion about adding the id filter. I have no idea why it isn't returning any data now
d
I don't know what to say... I shared all my schema and data
and I added
Copy code
- operation: 'Organization.read'
    authenticated: true
in case was that one the problem
but nothing
hi @nilan I replied to your questions on the forum ... I still stuck and no idea what is caused what https://www.graph.cool/forum/t/filter-companies-by-organizations/1713