refactor(streams): use directives for auth

comment out any auth logic within the streams resolvers and add auth
directives to the graphql schema instead

test:server all pass for me with this, so hoping everything is ok here!!
This commit is contained in:
izzy lyseggen
2020-08-14 15:32:06 +01:00
parent 6b8bb65dc5
commit ee532b2b96
2 changed files with 59 additions and 23 deletions
+29 -18
View File
@@ -16,21 +16,24 @@ const {
const { validateServerRole, validateScopes, authorizeResolver, pubsub } = require( `${appRoot}/modules/shared` )
// subscription events
const STREAM_CREATED = 'STREAM_CREATED'
const STREAM_UPDATED = 'STREAM_UPDATED'
const STREAM_DELETED = 'STREAM_DELETED'
const STREAM_PERMISSION_GRANTED = 'STREAM_PERMISSION_GRANTED'
const STREAM_PERMISSION_REVOKED = 'STREAM_PERMISSION_REVOKED'
module.exports = {
Query: {
async stream( parent, args, context, info ) {
await validateScopes( context.scopes, 'streams:read' )
await authorizeResolver( context.userId, args.id, 'stream:reviewer' )
// await validateScopes( context.scopes, 'streams:read' )
// await authorizeResolver( context.userId, args.id, 'stream:reviewer' )
let stream = await getStream( { streamId: args.id } )
return stream
},
async streams( parent, args, context, info ) {
await validateScopes( context.scopes, 'streams:read' )
// await validateScopes( context.scopes, 'streams:read' )
if ( args.limit && args.limit > 100 )
throw new UserInputError( 'Cannot return more than 100 items, please use pagination.' )
@@ -65,8 +68,8 @@ module.exports = {
},
Mutation: {
async streamCreate( parent, args, context, info ) {
await validateServerRole( context, 'server:user' )
await validateScopes( context.scopes, 'streams:write' )
// await validateServerRole( context, 'server:user' )
// await validateScopes( context.scopes, 'streams:write' )
let id = await createStream( { ...args.stream, ownerId: context.userId } )
await pubsub.publish( STREAM_CREATED, { streamCreated: { id: id, ...args.stream }, ownerId: context.userId } )
@@ -74,9 +77,9 @@ module.exports = {
},
async streamUpdate( parent, args, context, info ) {
await validateServerRole( context, 'server:user' )
await validateScopes( context.scopes, 'streams:write' )
await authorizeResolver( context.userId, args.stream.id, 'stream:owner' )
// await validateServerRole( context, 'server:user' )
// await validateScopes( context.scopes, 'streams:write' )
// await authorizeResolver( context.userId, args.stream.id, 'stream:owner' )
let update = { streamId: args.stream.id, name: args.stream.name, description: args.stream.description }
await updateStream( update )
@@ -85,9 +88,9 @@ module.exports = {
},
async streamDelete( parent, args, context, info ) {
await validateServerRole( context, 'server:user' )
await validateScopes( context.scopes, 'streams:write' )
await authorizeResolver( context.userId, args.id, 'stream:owner' )
// await validateServerRole( context, 'server:user' )
// await validateScopes( context.scopes, 'streams:write' )
// await authorizeResolver( context.userId, args.id, 'stream:owner' )
await deleteStream( { streamId: args.id } )
await pubsub.publish( STREAM_DELETED, { streamDeleted: { streamId: args.id }, ownerId: context.userId } )
@@ -95,19 +98,21 @@ module.exports = {
},
async streamGrantPermission( parent, args, context, info ) {
await validateServerRole( context, 'server:user' )
await validateScopes( context.scopes, 'streams:write' )
await authorizeResolver( context.userId, args.streamId, 'stream:owner' )
// await validateServerRole( context, 'server:user' )
// await validateScopes( context.scopes, 'streams:write' )
// await authorizeResolver( context.userId, args.streamId, 'stream:owner' )
if ( context.userId === args.userId ) throw new Error( 'You cannot set roles for yourself.' )
return await grantPermissionsStream( { streamId: args.streamId, userId: args.userId, role: args.role.toLowerCase( ) || 'read' } )
let permissionParams = { streamId: args.streamId, userId: args.userId, role: args.role.toLowerCase() || 'read' }
await pubsub.publish( STREAM_PERMISSION_GRANTED, { streamPermissionGranted: permissionParams, userId: args.userId } )
return await grantPermissionsStream( permissionParams )
},
async streamRevokePermission( parent, args, context, info ) {
await validateServerRole( context, 'server:user' )
await validateScopes( context.scopes, 'streams:write' )
await authorizeResolver( context.userId, args.streamId, 'stream:owner' )
// await validateServerRole( context, 'server:user' )
// await validateScopes( context.scopes, 'streams:write' )
// await authorizeResolver( context.userId, args.streamId, 'stream:owner' )
return await revokePermissionsStream( { ...args } )
}
@@ -130,6 +135,12 @@ module.exports = {
( payload, variables ) => {
return payload.ownerId === variables.ownerId
} )
},
streamPermissionGranted: {
subscribe: withFilter( () => pubsub.asyncIterator( [ STREAM_PERMISSION_GRANTED ] ),
( payload, variables ) => {
return payload.userId === variables.userId
} )
}
}
}
+30 -5
View File
@@ -1,9 +1,12 @@
extend type Query {
stream( id: String! ): Stream
@isAuthorizedForStream(role: "stream:reviewer")
@hasScope(scope: "streams:read")
"""
All the streams of the current user, pass in the `query` parameter to seach by name, description or ID.
"""
streams( query: String!, limit: Int! = 25, cursor: String ): StreamCollection
streams( query: String!, limit: Int! = 25, cursor: String ): StreamCollection
@hasScope(scope: "streams:read")
}
type Stream {
@@ -20,7 +23,7 @@ extend type User {
"""
All the streams that a user has access to.
"""
streams( limit: Int! = 25, cursor: String ): StreamCollection
streams( limit: Int! = 25, cursor: String ): StreamCollection
}
type StreamCollaborator {
@@ -41,22 +44,36 @@ extend type Mutation {
Creates a new stream.
"""
streamCreate( stream: StreamCreateInput! ): String
@hasScope(scope: "streams:write")
@hasRole(role: "server:user")
"""
Updates an existing stream.
"""
streamUpdate( stream: StreamUpdateInput! ): Boolean!
@isAuthorizedForStream(role: "stream:owner")
@hasScope(scope: "streams:write")
@hasRole(role: "server:user")
"""
Deletes an existing stream.
"""
streamDelete( id: String! ): Boolean!
@isAuthorizedForStream(role: "stream:owner")
@hasScope(scope: "streams:write")
@hasRole(role: "server:user")
"""
Grants permissions to a user on a given stream.
"""
streamGrantPermission( streamId: String!, userId: String!, role: String! ): Boolean
@isAuthorizedForStream(role: "stream:owner")
@hasScope(scope: "streams:write")
@hasRole(role: "server:user")
"""
Revokes the permissions of a user on a given stream.
"""
streamRevokePermission( streamId: String!, userId: String! ): Boolean
@isAuthorizedForStream(role: "stream:owner")
@hasScope(scope: "streams:write")
@hasRole(role: "server:user")
}
@@ -64,15 +81,23 @@ extend type Subscription {
"""
Subscribes to new stream created event.
"""
streamCreated( ownerId: String! ): JSONObject! @hasRole(role: "server:user") @hasScope(scope: "streams:read")
streamCreated( ownerId: String! ): JSONObject
@isAuthorizedForStream(role: "stream:reviewer")
"""
Subscribes to stream updated event.
"""
streamUpdated( streamId: String! ): JSONObject! @hasRole(role: "server:user") @hasScope(scope: "streams:read")
streamUpdated( streamId: String! ): JSONObject
@isAuthorizedForStream(role: "stream:reviewer")
"""
Subscribes to stream deleted event. (do we want this for streamId?)
"""
streamDeleted( ownerId: String! ): JSONObject! @hasRole(role: "server:user") @hasScope(scope: "streams:read")
streamDeleted( ownerId: String! ): JSONObject
# @isAuthorizedForStream(role: "stream:reviewer") ah this doesn't work b/c deleted before auth gets checked
"""
Subscribes to stream permission granted event.
"""
streamPermissionGranted( userId: String! ): JSONObject
@isAuthorizedForStream(role: "stream:reviewer")
}
input StreamCreateInput {