Skip to content

Commit 457e8f0

Browse files
committed
wip - JWT claims with explicit SQL predicate
1 parent af380b2 commit 457e8f0

File tree

6 files changed

+170
-0
lines changed

6 files changed

+170
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Pulling field arguments from JWT claims
2+
3+
Run the [sample operations](operations.graphql):
4+
5+
JWT with `regions: IN`.
6+
```
7+
stepzen request -f operations.graphql --operation-name=Customers \
8+
--header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1IiwicmVnaW9ucyI6WyJJTiJdfQ.hDi3-qaIOSFKzlFvaXwSh0trXC3vjiOehSKE0OxgOdE"
9+
```
10+
11+
12+
JWT with `regions: IN, UK`.
13+
```
14+
stepzen request -f operations.graphql --operation-name=Customers \
15+
--header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1IiwicmVnaW9ucyI6WyJJTiJdfQ.hDi3-qaIOSFKzlFvaXwSh0trXC3vjiOehSKE0OxgOdE"
16+
```
17+
18+
JWT with `regions: US, UK`.
19+
```
20+
stepzen request -f operations.graphql --operation-name=Customers \
21+
--header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1IiwicmVnaW9ucyI6WyJVUyIsIlVLIl19.pf0-A6TN_hT-ldCvsZyqYGv4Twjm9s6wO1aatCjK9Aw"
22+
```
23+
24+
JWT with `regions: US, UK` and user supplied filter
25+
```
26+
stepzen request -f operations.graphql --operation-name=Customers \
27+
--var f='{"city": {"eq":"London"}}' \
28+
--header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1IiwicmVnaW9ucyI6WyJVUyIsIlVLIl19.pf0-A6TN_hT-ldCvsZyqYGv4Twjm9s6wO1aatCjK9Aw"
29+
```
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
deployment:
2+
identity:
3+
keys:
4+
- algorithm: HS256
5+
key: development-only
6+
access:
7+
policies:
8+
- type: Query
9+
policyDefault:
10+
condition: false
11+
rules:
12+
- name: "jwt-control"
13+
fields: [customers]
14+
condition: "?$jwt"
15+
- name: "introspection"
16+
fields: [__schema, __type]
17+
condition: true
18+
configurationset:
19+
- configuration:
20+
name: postgresql_config
21+
uri: postgresql://postgresql.introspection.stepzen.net/introspection?user=testUserIntrospection&password=HurricaneStartingSample1934
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
schema
2+
@sdl(
3+
files: ["paging.graphql"]
4+
# visibilty controls how fields included through files in this directive
5+
# are visible outside the scope of this directive to GraphQL introspection
6+
# and field references through @materializer etc.
7+
#
8+
# types and fields are regular expressions that match type and field names.
9+
# Like field access rules if aat least one visibility pattern is present then by default
10+
# root operation type (Query, Mutation, Subscription) fields are not exposed.
11+
visibility: [{ expose: true, types: "Query", fields: ".*" }]
12+
) {
13+
query: Query
14+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
query Customers($f:CustomerFilter) {
2+
customers(filter:$f) {
3+
id
4+
name
5+
city
6+
region
7+
}
8+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
type Customer {
2+
id: ID!
3+
name: String
4+
email: String
5+
street: String
6+
city: String
7+
region: String
8+
}
9+
10+
"""
11+
`CustomerConnection` is the connection type for `Customer` pagination.
12+
In StepZen, a field returning a connection type must have arguments
13+
`first` (number of nodes to fetch) and `after` (opaque cursor indicating
14+
the starting point).
15+
"""
16+
type CustomerConnection {
17+
edges: [CustomerEdge]
18+
pageInfo: PageInfo!
19+
}
20+
21+
"""
22+
`CustomerEdge` provides access to the node and its cursor.
23+
"""
24+
type CustomerEdge {
25+
node: Customer
26+
cursor: String
27+
}
28+
29+
input StringFilter {
30+
eq: String
31+
ne: String
32+
}
33+
34+
input CustomerFilter {
35+
name: StringFilter
36+
email: StringFilter
37+
city: StringFilter
38+
}
39+
40+
extend type Query {
41+
# customers is the exposed field that limits the caller to regions
42+
# based upon the regions claim in the request's JWT.
43+
customers(
44+
first: Int! = 10
45+
filter: CustomerFilter
46+
): [Customer]
47+
@sequence(
48+
steps: [
49+
{ query: "_regions" }
50+
{
51+
query: "_customers_flatten"
52+
arguments: [
53+
{ name: "first", argument: "first" }
54+
{ name: "filter", argument: "filter" }
55+
]
56+
}
57+
]
58+
)
59+
60+
# extracts the regions visible to the request from the JWT.
61+
_regions: [String]! @value(script: { src: "$jwt.regions" })
62+
63+
# this flattens the customer connection pagination structure
64+
# into a simple list of Customer objects.
65+
# This is needed as @sequence is not supported for connection types.
66+
_customers_flatten(
67+
first: Int! = 10
68+
filter: CustomerFilter
69+
regions: [String]!
70+
): [Customer] @materializer(query: "_customers { edges { node }}")
71+
72+
# Standard paginated field for a customers table in a database.
73+
# Additional regions argument that is used to limit customer
74+
# visibility based upon the 'regions' claim in a JWT.
75+
# The regions allows a list of regions and uses SQL ANY to match rows.
76+
_customers(
77+
first: Int! = 10
78+
after: String! = ""
79+
filter: CustomerFilter # regions: [String]!
80+
regions: [String]!
81+
): CustomerConnection
82+
@dbquery(
83+
type: "postgresql"
84+
schema: "public"
85+
query: """
86+
SELECT C.id, C.name, C.email, A.street, A.city, A.countryregion AS region
87+
FROM customer C, address A, customeraddress CA
88+
WHERE
89+
CA.customerid = C.id AND
90+
CA.addressid = A.id AND
91+
A.countryregion = ANY(CAST($1 AS VARCHAR ARRAY))
92+
"""
93+
configuration: "postgresql_config"
94+
)
95+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"endpoint": "api/miscellaneous"
3+
}

0 commit comments

Comments
 (0)