Merge pull request #1726 from specklesystems/gergo/serverGuestRole

refactor(server graphlq): migrate hasRole directive to hasServerRole
This commit is contained in:
Gergő Jedlicska
2023-07-26 14:31:58 +02:00
committed by GitHub
15 changed files with 94 additions and 125 deletions
@@ -3,7 +3,7 @@ extend type Query {
Get authed user's stream access request
"""
streamAccessRequest(streamId: String!): StreamAccessRequest
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
}
extend type Stream {
@@ -21,13 +21,13 @@ extend type Mutation {
requestId: String!
accept: Boolean!
role: StreamRole! = STREAM_CONTRIBUTOR
): Boolean! @hasRole(role: "server:user") @hasScope(scope: "users:invite")
): Boolean! @hasServerRole(role: SERVER_USER) @hasScope(scope: "users:invite")
"""
Request access to a specific stream
"""
streamAccessRequestCreate(streamId: String!): StreamAccessRequest!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "users:invite")
}
@@ -8,7 +8,7 @@ extend type User {
before: DateTime
cursor: DateTime
limit: Int! = 25
): ActivityCollection @hasRole(role: "server:user") @hasScope(scope: "users:read")
): ActivityCollection @hasServerRole(role: SERVER_USER) @hasScope(scope: "users:read")
"""
The user's timeline in chronological order
@@ -19,7 +19,7 @@ extend type User {
cursor: DateTime
limit: Int! = 25
): ActivityCollection
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScopes(scopes: ["users:read", "streams:read"])
}
@@ -33,7 +33,7 @@ extend type LimitedUser {
before: DateTime
cursor: DateTime
limit: Int! = 25
): ActivityCollection @hasRole(role: "server:user") @hasScope(scope: "users:read")
): ActivityCollection @hasServerRole(role: SERVER_USER) @hasScope(scope: "users:read")
"""
The user's timeline in chronological order
@@ -44,7 +44,7 @@ extend type LimitedUser {
cursor: DateTime
limit: Int! = 25
): ActivityCollection
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScopes(scopes: ["users:read", "streams:read"])
}
@@ -58,7 +58,9 @@ extend type Stream {
before: DateTime
cursor: DateTime
limit: Int! = 25
): ActivityCollection @hasRole(role: "server:user") @hasScope(scope: "streams:read")
): ActivityCollection
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
}
extend type Branch {
@@ -71,7 +73,9 @@ extend type Branch {
before: DateTime
cursor: DateTime
limit: Int! = 25
): ActivityCollection @hasRole(role: "server:user") @hasScope(scope: "streams:read")
): ActivityCollection
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
}
extend type Commit {
@@ -84,7 +88,9 @@ extend type Commit {
before: DateTime
cursor: DateTime
limit: Int! = 25
): ActivityCollection @hasRole(role: "server:user") @hasScope(scope: "streams:read")
): ActivityCollection
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
}
type ActivityCollection {
@@ -47,13 +47,15 @@ extend type User {
Returns the apps you have authorized.
"""
authorizedApps: [ServerAppListItem]
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "apps:read")
"""
Returns the apps you have created.
"""
createdApps: [ServerApp!] @hasRole(role: "server:user") @hasScope(scope: "apps:read")
createdApps: [ServerApp!]
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "apps:read")
}
extend type Mutation {
@@ -61,28 +63,28 @@ extend type Mutation {
Register a new third party application.
"""
appCreate(app: AppCreateInput!): String!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "apps:write")
"""
Update an existing third party application. **Note: This will invalidate all existing tokens, refresh tokens and access codes and will require existing users to re-authorize it.**
"""
appUpdate(app: AppUpdateInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "apps:write")
"""
Deletes a thirty party application.
"""
appDelete(appId: String!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "apps:write")
"""
Revokes (de-authorizes) an application that you have previously authorized.
"""
appRevokeAccess(appId: String!): Boolean
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "apps:write")
}
@@ -334,7 +334,7 @@ extend type Mutation {
resourceId: String!
data: JSONObject
): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@deprecated(reason: "Use broadcastViewerUserActivity")
"""
@@ -345,14 +345,14 @@ extend type Mutation {
commentId: String!
data: JSONObject
): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@deprecated(reason: "Use broadcastViewerUserActivity")
"""
Creates a comment
"""
commentCreate(input: CommentCreateInput!): String!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
@deprecated(reason: "Use commentMutations version")
@@ -360,7 +360,7 @@ extend type Mutation {
Flags a comment as viewed by you (the logged in user).
"""
commentView(streamId: String!, commentId: String!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
@deprecated(reason: "Use commentMutations version")
@@ -372,7 +372,7 @@ extend type Mutation {
commentId: String!
archived: Boolean! = true
): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
@deprecated(reason: "Use commentMutations version")
@@ -380,7 +380,7 @@ extend type Mutation {
Edits a comment.
"""
commentEdit(input: CommentEditInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
@deprecated(reason: "Use commentMutations version")
@@ -388,7 +388,7 @@ extend type Mutation {
Adds a reply to a comment.
"""
commentReply(input: ReplyCreateInput!): String!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
@deprecated(reason: "Use commentMutations version")
}
@@ -457,7 +457,7 @@ extend type Subscription {
- for a specific resource/set of resources: pass in a list of resourceIds (commit or object ids); this sub will get called when *any* of the resources provided get a comment.
"""
commentActivity(streamId: String!, resourceIds: [String]): CommentActivityMessage!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
@deprecated(reason: "Use projectCommentsUpdated")
@@ -470,7 +470,7 @@ extend type Subscription {
streamId: String!
commentId: String!
): CommentThreadActivityMessage!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
@deprecated(
reason: "Use projectCommentsUpdated or viewerUserActivityBroadcasted for reply status"
@@ -2,7 +2,9 @@ extend type User {
"""
Returns a list of your personal api tokens.
"""
apiTokens: [ApiToken] @hasRole(role: "server:user") @hasScope(scope: "tokens:read")
apiTokens: [ApiToken]
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "tokens:read")
}
type ApiToken {
@@ -26,12 +28,12 @@ extend type Mutation {
Creates an personal api token.
"""
apiTokenCreate(token: ApiTokenCreateInput!): String!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "tokens:write")
"""
Revokes (deletes) an personal api token.
"""
apiTokenRevoke(token: String!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "tokens:write")
}
@@ -48,7 +48,7 @@ type Commit {
Will throw an authorization error if active user isn't authorized to see it, for example,
if a stream isn't public and the user doesn't have the appropriate rights.
"""
stream: Stream! @hasRole(role: "server:user") @hasScope(scope: "streams:read")
stream: Stream! @hasServerRole(role: SERVER_USER) @hasScope(scope: "streams:read")
}
type BranchCollection {
@@ -65,40 +65,40 @@ type CommitCollection {
extend type Mutation {
branchCreate(branch: BranchCreateInput!): String!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
branchUpdate(branch: BranchUpdateInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
branchDelete(branch: BranchDeleteInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
commitCreate(commit: CommitCreateInput!): String!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
commitUpdate(commit: CommitUpdateInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
commitReceive(input: CommitReceivedInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
commitDelete(commit: CommitDeleteInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
"""
Move a batch of commits to a new branch
"""
commitsMove(input: CommitsMoveInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
"""
Delete a batch of commits
"""
commitsDelete(input: CommitsDeleteInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
}
@@ -108,38 +108,38 @@ extend type Subscription {
Subscribe to branch created event
"""
branchCreated(streamId: String!): JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
Subscribe to branch updated event.
"""
branchUpdated(streamId: String!, branchId: String): JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
Subscribe to branch deleted event
"""
branchDeleted(streamId: String!): JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
Subscribe to commit created event
"""
commitCreated(streamId: String!): JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
Subscribe to commit updated event.
"""
commitUpdated(streamId: String!, commitId: String): JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
Subscribe to commit deleted event
"""
commitDeleted(streamId: String!): JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
}
@@ -37,7 +37,7 @@ type Scope {
extend type Mutation {
serverInfoUpdate(info: ServerInfoUpdateInput!): Boolean
@hasRole(role: "server:admin")
@hasServerRole(role: SERVER_ADMIN)
@hasScope(scope: "server:setup")
}
@@ -10,7 +10,7 @@ extend type Query {
Pass in the `query` parameter to search by name, description or ID.
"""
streams(query: String, limit: Int = 25, cursor: String): StreamCollection
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
@@ -22,7 +22,7 @@ extend type Query {
orderBy: String
visibility: String
limit: Int = 25
): StreamCollection @hasRole(role: "server:admin")
): StreamCollection @hasServerRole(role: SERVER_ADMIN)
"""
All of the discoverable streams of the server
@@ -77,7 +77,7 @@ extend type User {
authenticated user, then this will only return discoverable streams.
"""
streams(limit: Int! = 25, cursor: String): StreamCollection!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
@@ -85,7 +85,7 @@ extend type User {
Note: You can't use this to retrieve another user's favorite streams.
"""
favoriteStreams(limit: Int! = 25, cursor: String): StreamCollection!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
@@ -99,7 +99,7 @@ extend type LimitedUser {
Returns all discoverable streams that the user is a collaborator on
"""
streams(limit: Int! = 25, cursor: String): StreamCollection!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
@@ -150,43 +150,43 @@ extend type Mutation {
Creates a new stream.
"""
streamCreate(stream: StreamCreateInput!): String
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
"""
Updates an existing stream.
"""
streamUpdate(stream: StreamUpdateInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
"""
Deletes an existing stream.
"""
streamDelete(id: String!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
streamsDelete(ids: [String!]): Boolean! @hasRole(role: "server:admin")
streamsDelete(ids: [String!]): Boolean! @hasServerRole(role: SERVER_ADMIN)
"""
Update permissions of a user on a given stream.
"""
streamUpdatePermission(permissionParams: StreamUpdatePermissionInput!): Boolean
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
"""
Revokes the permissions of a user on a given stream.
"""
streamRevokePermission(permissionParams: StreamRevokePermissionInput!): Boolean
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
# Favorite/unfavorite the given stream
streamFavorite(streamId: String!, favorited: Boolean!): Stream
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
"""
Remove yourself from stream collaborators (not possible for the owner)
"""
streamLeave(streamId: String!): Boolean! @hasRole(role: "server:user")
streamLeave(streamId: String!): Boolean! @hasServerRole(role: SERVER_USER)
}
extend type Subscription {
@@ -200,7 +200,7 @@ extend type Subscription {
**NOTE**: If someone shares a stream with you, this subscription will be triggered with an extra value of `sharedBy` in the payload.
"""
userStreamAdded: JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "profile:read")
"""
@@ -208,7 +208,7 @@ extend type Subscription {
**NOTE**: If someone revokes your permissions on a stream, this subscription will be triggered with an extra value of `revokedBy` in the payload.
"""
userStreamRemoved: JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "profile:read")
#
@@ -220,14 +220,14 @@ extend type Subscription {
Subscribes to stream updated event. Use this in clients/components that pertain only to this stream.
"""
streamUpdated(streamId: String): JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
"""
Subscribes to stream deleted event. Use this in clients/components that pertain only to this stream.
"""
streamDeleted(streamId: String): JSONObject
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
}
@@ -8,7 +8,7 @@ extend type Query {
Get the (limited) profile information of another server user
"""
otherUser(id: String!): LimitedUser
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "users:read")
"""
@@ -28,7 +28,7 @@ extend type Query {
offset: Int! = 0
query: String = null
): AdminUsersListCollection
@hasRole(role: "server:admin")
@hasServerRole(role: SERVER_ADMIN)
@hasScope(scope: "users:read")
"""
@@ -153,18 +153,19 @@ extend type Mutation {
Delete a user's account.
"""
userDelete(userConfirmation: UserDeleteInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "profile:delete")
adminDeleteUser(userConfirmation: UserDeleteInput!): Boolean!
@hasRole(role: "server:admin")
@hasServerRole(role: SERVER_ADMIN)
userRoleChange(userRoleInput: UserRoleInput!): Boolean! @hasRole(role: "server:admin")
userRoleChange(userRoleInput: UserRoleInput!): Boolean!
@hasServerRole(role: SERVER_ADMIN)
"""
Various Active User oriented mutations
"""
activeUserMutations: ActiveUserMutations! @hasRole(role: "server:user")
activeUserMutations: ActiveUserMutations! @hasServerRole(role: SERVER_USER)
}
input UserRoleInput {
@@ -9,5 +9,5 @@ extend type Mutation {
"""
(Re-)send the account verification e-mail
"""
requestVerification: Boolean! @hasRole(role: "server:user")
requestVerification: Boolean! @hasServerRole(role: SERVER_USER)
}
@@ -4,5 +4,5 @@ extend type User {
extend type Mutation {
userNotificationPreferencesUpdate(preferences: JSONObject!): Boolean
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
}
@@ -3,49 +3,49 @@ extend type Mutation {
Invite a new user to the speckle server and return the invite ID
"""
serverInviteCreate(input: ServerInviteCreateInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "users:invite")
"""
Invite a new or registered user to the specified stream
"""
streamInviteCreate(input: StreamInviteCreateInput!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "users:invite")
serverInviteBatchCreate(input: [ServerInviteCreateInput!]!): Boolean!
@hasRole(role: "server:admin")
@hasServerRole(role: SERVER_ADMIN)
@hasScope(scope: "users:invite")
streamInviteBatchCreate(input: [StreamInviteCreateInput!]!): Boolean!
@hasRole(role: "server:admin")
@hasServerRole(role: SERVER_ADMIN)
@hasScope(scope: "users:invite")
"""
Accept or decline a stream invite
"""
streamInviteUse(accept: Boolean!, streamId: String!, token: String!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
"""
Cancel a pending stream invite. Can only be invoked by a stream owner.
"""
streamInviteCancel(streamId: String!, inviteId: String!): Boolean!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "users:invite")
"""
Re-send a pending invite
"""
inviteResend(inviteId: String!): Boolean!
@hasRole(role: "server:admin")
@hasServerRole(role: SERVER_ADMIN)
@hasScope(scope: "users:invite")
"""
Delete a pending invite
"""
inviteDelete(inviteId: String!): Boolean!
@hasRole(role: "server:admin")
@hasServerRole(role: SERVER_ADMIN)
@hasScope(scope: "users:invite")
}
@@ -66,7 +66,7 @@ extend type Query {
Get all invitations to streams that the active user has
"""
streamInvites: [PendingStreamCollaborator!]!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:read")
}
@@ -1,6 +1,6 @@
extend type Stream {
webhooks(id: String): WebhookCollection
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
}
@@ -9,21 +9,21 @@ extend type Mutation {
Creates a new webhook on a stream
"""
webhookCreate(webhook: WebhookCreateInput!): String!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
"""
Updates an existing webhook
"""
webhookUpdate(webhook: WebhookUpdateInput!): String!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
"""
Deletes an existing webhook
"""
webhookDelete(webhook: WebhookDeleteInput!): String!
@hasRole(role: "server:user")
@hasServerRole(role: SERVER_USER)
@hasScope(scope: "streams:write")
}
@@ -48,41 +48,6 @@ module.exports = {
}
},
/**
* Ensure that the user has the specified SERVER role (e.g. server user, admin etc.)
* @deprecated Use `hasServerRole` instead, as it relies on proper GQL enums
* @type {import('@/modules/core/graph/helpers/directiveHelper').GraphqlDirectiveBuilder}
*/
hasRole: () => {
const directiveName = 'hasRole'
return {
typeDefs: `
"""
Ensure that the user has the specified SERVER role (e.g. server user, admin etc.)
"""
directive @${directiveName}(role: String!) on FIELD_DEFINITION
`,
schemaTransformer: (schema) =>
mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: (fieldConfig) => {
const directive = getDirective(schema, fieldConfig, directiveName)?.[0]
if (!directive) return undefined
const { role: requiredRole } = directive
const { resolve = defaultFieldResolver } = fieldConfig
fieldConfig.resolve = async function (...args) {
const context = args[2]
await validateServerRole(context, requiredRole)
return await resolve.apply(this, args)
}
return fieldConfig
}
})
}
},
/**
* Ensure that the user has the specified STREAM role for a target stream (e.g. owner)
*
@@ -3009,12 +3009,6 @@ export type ResolversParentTypes = {
WebhookUpdateInput: WebhookUpdateInput;
};
export type HasRoleDirectiveArgs = {
role: Scalars['String'];
};
export type HasRoleDirectiveResolver<Result, Parent, ContextType = GraphQLContext, Args = HasRoleDirectiveArgs> = DirectiveResolverFn<Result, Parent, ContextType, Args>;
export type HasScopeDirectiveArgs = {
scope: Scalars['String'];
};
@@ -3992,7 +3986,6 @@ export type Resolvers<ContextType = GraphQLContext> = {
};
export type DirectiveResolvers<ContextType = GraphQLContext> = {
hasRole?: HasRoleDirectiveResolver<any, any, ContextType>;
hasScope?: HasScopeDirectiveResolver<any, any, ContextType>;
hasScopes?: HasScopesDirectiveResolver<any, any, ContextType>;
hasServerRole?: HasServerRoleDirectiveResolver<any, any, ContextType>;