feat: added OIDC management mutations

This commit is contained in:
Wyatt Johnson
2018-10-24 16:54:07 -06:00
parent 0bb64f1d97
commit 45cbac7972
11 changed files with 524 additions and 69 deletions
@@ -2,15 +2,21 @@ import { isNull, omitBy } from "lodash";
import TenantContext from "talk-server/graph/tenant/context";
import {
GQLCreateOIDCAuthIntegrationInput,
GQLDeleteOIDCAuthIntegrationInput,
GQLDiscoverOIDCConfigurationInput,
GQLOIDCConfiguration,
GQLSettingsInput,
GQLUpdateOIDCAuthIntegrationInput,
} from "talk-server/graph/tenant/schema/__generated__/types";
import { Tenant } from "talk-server/models/tenant";
import {
createOIDCAuthIntegration,
deleteOIDCAuthIntegration,
discoverOIDCConfiguration,
regenerateSSOKey,
update,
updateOIDCAuthIntegration,
} from "talk-server/services/tenant";
export default ({ mongo, redis, tenantCache, tenant }: TenantContext) => ({
@@ -21,4 +27,29 @@ export default ({ mongo, redis, tenantCache, tenant }: TenantContext) => ({
discoverOIDCConfiguration: (
input: GQLDiscoverOIDCConfigurationInput
): Promise<GQLOIDCConfiguration> => discoverOIDCConfiguration(input.issuer),
createOIDCAuthIntegration: (
input: GQLCreateOIDCAuthIntegrationInput
): Promise<Tenant | null> =>
createOIDCAuthIntegration(
mongo,
redis,
tenantCache,
tenant,
input.configuration
),
updateOIDCAuthIntegration: (
input: GQLUpdateOIDCAuthIntegrationInput
): Promise<Tenant | null> =>
updateOIDCAuthIntegration(
mongo,
redis,
tenantCache,
tenant,
input.id,
input.configuration
),
deleteOIDCAuthIntegration: (
input: GQLDeleteOIDCAuthIntegrationInput
): Promise<Tenant | null> =>
deleteOIDCAuthIntegration(mongo, redis, tenantCache, tenant, input.id),
});
@@ -8,6 +8,7 @@ import AuthIntegrations from "./auth_integrations";
import Comment from "./comment";
import CommentCounts from "./comment_counts";
import Mutation from "./mutation";
import OIDCAuthIntegration from "./oidc_auth_integration";
import Profile from "./profile";
import Query from "./query";
import User from "./user";
@@ -19,10 +20,11 @@ const Resolvers: GQLResolver = {
CommentCounts,
Cursor,
Mutation,
OIDCAuthIntegration,
Profile,
Query,
User,
Time,
User,
};
export default Resolvers;
@@ -55,6 +55,18 @@ const Mutation: GQLMutationTypeResolver<void> = {
configuration: await ctx.mutators.Settings.discoverOIDCConfiguration(input),
clientMutationId: input.clientMutationId,
}),
createOIDCAuthIntegration: async (source, { input }, ctx) => ({
settings: await ctx.mutators.Settings.createOIDCAuthIntegration(input),
clientMutationId: input.clientMutationId,
}),
updateOIDCAuthIntegration: async (source, { input }, ctx) => ({
settings: await ctx.mutators.Settings.updateOIDCAuthIntegration(input),
clientMutationId: input.clientMutationId,
}),
deleteOIDCAuthIntegration: async (source, { input }, ctx) => ({
settings: await ctx.mutators.Settings.deleteOIDCAuthIntegration(input),
clientMutationId: input.clientMutationId,
}),
};
export default Mutation;
@@ -0,0 +1,26 @@
import { reconstructTenantURL, reconstructURL } from "talk-server/app/url";
import {
GQLOIDCAuthIntegration,
GQLOIDCAuthIntegrationTypeResolver,
} from "talk-server/graph/tenant/schema/__generated__/types";
const OIDCAuthIntegration: GQLOIDCAuthIntegrationTypeResolver<
GQLOIDCAuthIntegration
> = {
callbackURL: (integration, args, ctx) => {
const path = `/api/tenant/auth/oidc/${integration.id}`;
// If the request is available, then prefer it over building from the tenant
// as the tenant does not include the port number. This should only really
// be a problem if the graph API is called internally.
if (ctx.req) {
return reconstructURL(ctx.req, path);
}
// Note that when constructing the callback url with the tenant, the port
// information is lost.
return reconstructTenantURL(ctx.tenant, path);
},
};
export default OIDCAuthIntegration;
@@ -317,6 +317,14 @@ OIDCAuthIntegration provides a way to store Open ID Connect credentials. This
will be used in the admin to provide staff logins for users.
"""
type OIDCAuthIntegration {
"""
id is the identifier of the OIDCAuthIntegration.
"""
id: ID!
"""
enabled, when true, allows the integration to be enabled.
"""
enabled: Boolean!
"""
@@ -330,12 +338,20 @@ type OIDCAuthIntegration {
name is the label assigned to reference the provider of the OIDC integration.
"""
name: String
clientID: String @auth(roles: [ADMIN])
clientSecret: String @auth(roles: [ADMIN])
authorizationURL: String @auth(roles: [ADMIN])
tokenURL: String @auth(roles: [ADMIN])
jwksURI: String @auth(roles: [ADMIN])
issuer: String @auth(roles: [ADMIN])
"""
callbackURL is the URL that the user should be redirected to in order to start
an authentication flow with the given integration. This field is not stored,
and is instead computed from the Tenant.
"""
callbackURL: String!
clientID: String! @auth(roles: [ADMIN])
clientSecret: String! @auth(roles: [ADMIN])
authorizationURL: String! @auth(roles: [ADMIN])
tokenURL: String! @auth(roles: [ADMIN])
jwksURI: String! @auth(roles: [ADMIN])
issuer: String! @auth(roles: [ADMIN])
"""
displayNameEnable when enabled, will allow Users to set and view their
@@ -383,7 +399,7 @@ type FacebookAuthIntegration {
type AuthIntegrations {
local: LocalAuthIntegration!
sso: SSOAuthIntegration!
oidc: OIDCAuthIntegration!
oidc: [OIDCAuthIntegration!]!
google: GoogleAuthIntegration!
facebook: FacebookAuthIntegration!
}
@@ -1349,33 +1365,33 @@ input SettingsSSOAuthIntegrationInput {
displayNameEnable: Boolean
}
input SettingsOIDCAuthIntegrationInput {
enabled: Boolean
# input SettingsOIDCAuthIntegrationInput {
# enabled: Boolean
"""
targetFilter will restrict where the authentication integration should be
displayed. If the value of targetFilter is null, then the authentication
integration should be displayed in all targets.
"""
targetFilter: SettingsAuthenticationTargetFilterInput
# """
# targetFilter will restrict where the authentication integration should be
# displayed. If the value of targetFilter is null, then the authentication
# integration should be displayed in all targets.
# """
# targetFilter: SettingsAuthenticationTargetFilterInput
"""
name is the label assigned to reference the provider of the OIDC integration.
"""
name: String
clientID: String
clientSecret: String
authorizationURL: String
tokenURL: String
jwksURI: String
issuer: String
# """
# name is the label assigned to reference the provider of the OIDC integration.
# """
# name: String
# clientID: String
# clientSecret: String
# authorizationURL: String
# tokenURL: String
# jwksURI: String
# issuer: String
"""
displayNameEnable when enabled, will allow Users to set and view their
displayName's.
"""
displayNameEnable: Boolean
}
# """
# displayNameEnable when enabled, will allow Users to set and view their
# displayName's.
# """
# displayNameEnable: Boolean
# }
input SettingsGoogleAuthIntegrationInput {
enabled: Boolean
@@ -1408,7 +1424,6 @@ input SettingsFacebookAuthIntegrationInput {
input SettingsAuthIntegrationsInput {
local: SettingsLocalAuthIntegrationInput
sso: SettingsSSOAuthIntegrationInput
oidc: SettingsOIDCAuthIntegrationInput
google: SettingsGoogleAuthIntegrationInput
facebook: SettingsFacebookAuthIntegrationInput
}
@@ -1917,6 +1932,7 @@ input DiscoverOIDCConfigurationInput {
}
type OIDCConfiguration {
issuer: String!
authorizationURL: String
tokenURL: String
jwksURI: String
@@ -1935,6 +1951,117 @@ type DiscoverOIDCConfigurationPayload {
clientMutationId: String!
}
##################
# createOIDCAuthIntegration
##################
input CreateOIDCAuthIntegrationConfigurationInput {
name: String!
clientID: String!
clientSecret: String!
authorizationURL: String!
tokenURL: String!
jwksURI: String!
issuer: String!
}
input CreateOIDCAuthIntegrationInput {
"""
configuration contains the configuration to be used to create the auth integration.
"""
configuration: CreateOIDCAuthIntegrationConfigurationInput!
"""
clientMutationId is required for Relay support.
"""
clientMutationId: String!
}
type CreateOIDCAuthIntegrationPayload {
"""
settings is the Settings that the OIDCAuthIntegration was created on.
"""
settings: Settings
"""
clientMutationId is required for Relay support.
"""
clientMutationId: String!
}
##################
# updateOIDCAuthIntegration
##################
input UpdateOIDCAuthIntegrationConfigurationInput {
enabled: Boolean
name: String
clientID: String
clientSecret: String
authorizationURL: String
tokenURL: String
jwksURI: String
issuer: String
}
input UpdateOIDCAuthIntegrationInput {
"""
id is the ID of the specific OpenID Connect integration that we are updating.
"""
id: ID!
"""
configuration contains the configuration to be used to update the OpenID
Connect integration.
"""
configuration: UpdateOIDCAuthIntegrationConfigurationInput!
"""
clientMutationId is required for Relay support.
"""
clientMutationId: String!
}
type UpdateOIDCAuthIntegrationPayload {
"""
settings is the Settings that the OIDCAuthIntegration was updated on.
"""
settings: Settings
"""
clientMutationId is required for Relay support.
"""
clientMutationId: String!
}
##################
# deleteOIDCAuthIntegration
##################
input DeleteOIDCAuthIntegrationInput {
"""
id is the ID of the specific OpenID Connect integration that we are deleting.
"""
id: ID!
"""
clientMutationId is required for Relay support.
"""
clientMutationId: String!
}
type DeleteOIDCAuthIntegrationPayload {
"""
settings is the Settings that the OIDCAuthIntegration was deleted on.
"""
settings: Settings
"""
clientMutationId is required for Relay support.
"""
clientMutationId: String!
}
##################
## Mutation
##################
@@ -1964,10 +2091,36 @@ type Mutation {
regenerateSSOKey(input: RegenerateSSOKeyInput!): RegenerateSSOKeyPayload
@auth(roles: [ADMIN])
"""
discoverOIDCConfiguration will discover the OpenID Connect configuration based
on the provided input.
"""
discoverOIDCConfiguration(
input: DiscoverOIDCConfigurationInput!
): DiscoverOIDCConfigurationPayload @auth(roles: [ADMIN])
"""
createOIDCAuthIntegration will create a OpenID Connect auth integration.
"""
createOIDCAuthIntegration(
input: CreateOIDCAuthIntegrationInput!
): CreateOIDCAuthIntegrationPayload @auth(roles: [ADMIN])
"""
updateOIDCAuthIntegration will update a given OpenID Connect auth integration.
"""
updateOIDCAuthIntegration(
input: UpdateOIDCAuthIntegrationInput!
): UpdateOIDCAuthIntegrationPayload @auth(roles: [ADMIN])
"""
deleteOIDCAuthIntegration will delete the specified OpenID Connect auth
integration.
"""
deleteOIDCAuthIntegration(
input: DeleteOIDCAuthIntegrationInput!
): DeleteOIDCAuthIntegrationPayload @auth(roles: [ADMIN])
"""
createCommentReaction will create a Reaction authored by the current logged in
User on a Comment.