Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add createSamlAuthProvider graphQL mutation #1195

Merged
merged 1 commit into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Knex } from 'knex';

const getPermissionForRole = (
roleId: string,
subject: string,
actions: string[]
) =>
actions.map((action) => ({
role_id: roleId,
subject,
action,
conditions: [],
}));

export async function up(knex: Knex): Promise<void> {
const role = (await knex('roles')
.first(['id', 'key'])
.where({ key: 'admin' })
.limit(1)) as { id: string; key: string };

await knex('permissions').insert(
getPermissionForRole(role.id, 'SamlAuthProvider', [
'create',
'read',
'delete',
'update',
])
);
}

export async function down(knex: Knex): Promise<void> {
await knex('permissions').where({ subject: 'SamlAuthProvider' }).delete();
}
2 changes: 2 additions & 0 deletions packages/backend/src/graphql/mutation-resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import updateRole from './mutations/update-role.ee';
import updateStep from './mutations/update-step';
import updateUser from './mutations/update-user.ee';
import verifyConnection from './mutations/verify-connection';
import createSamlAuthProvider from './mutations/create-saml-auth-provider.ee';

const mutationResolvers = {
createConnection,
Expand Down Expand Up @@ -54,6 +55,7 @@ const mutationResolvers = {
updateRole,
updateStep,
verifyConnection,
createSamlAuthProvider,
};

export default mutationResolvers;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type { SamlConfig } from '@node-saml/passport-saml';
import SamlAuthProvider from '../../models/saml-auth-provider.ee';
import Context from '../../types/express/context';

type Params = {
input: {
name: string;
certificate: string;
signatureAlgorithm: SamlConfig['signatureAlgorithm'];
issuer: string;
entryPoint: string;
firstnameAttributeName: string;
surnameAttributeName: string;
emailAttributeName: string;
roleAttributeName: string;
defaultRoleId: string;
active: boolean;
};
};

const createSamlAuthProvider = async (
_parent: unknown,
params: Params,
context: Context
) => {
context.currentUser.can('create', 'SamlAuthProvider');

const samlAuthProviderPayload: Partial<SamlAuthProvider> = {
...params.input,
};

const existingSamlAuthProvider = await SamlAuthProvider.query()
.limit(1)
.first();

let samlAuthProvider: SamlAuthProvider;

if (!existingSamlAuthProvider) {
samlAuthProvider = await SamlAuthProvider.query().insert(
samlAuthProviderPayload
);

return samlAuthProvider;
}

samlAuthProvider = await SamlAuthProvider.query().patchAndFetchById(
existingSamlAuthProvider.id,
samlAuthProviderPayload
);

return samlAuthProvider;
};

export default createSamlAuthProvider;
34 changes: 30 additions & 4 deletions packages/backend/src/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,7 @@ type Query {
getTrialStatus: GetTrialStatus
getSubscriptionStatus: GetSubscriptionStatus
getSamlAuthProviders: [GetSamlAuthProviders]
getUsers(
limit: Int!
offset: Int!
): UserConnection
getUsers(limit: Int!, offset: Int!): UserConnection
getUser(id: String!): User
getRoles: [Role]
getRole(id: String!): Role
Expand Down Expand Up @@ -81,6 +78,7 @@ type Mutation {
updateStep(input: UpdateStepInput): Step
updateUser(input: UpdateUserInput): User
verifyConnection(input: VerifyConnectionInput): Connection
createSamlAuthProvider(input: CreateSamlAuthProviderInput): SamlAuthProvider
}

"""
Expand Down Expand Up @@ -292,6 +290,20 @@ type Execution {
flow: Flow
}

type SamlAuthProvider {
id: String
name: String
certificate: String
signatureAlgorithm: String
issuer: String
entryPoint: String
firstnameAttributeName: String
surnameAttributeName: String
emailAttributeName: String
roleAttributeName: String
active: Boolean
}

type UserConnection {
edges: [UserEdge]
pageInfo: PageInfo
Expand Down Expand Up @@ -323,6 +335,20 @@ input VerifyConnectionInput {
id: String!
}

input CreateSamlAuthProviderInput {
name: String!
certificate: String!
signatureAlgorithm: String!
issuer: String!
entryPoint: String!
firstnameAttributeName: String!
surnameAttributeName: String!
emailAttributeName: String!
roleAttributeName: String!
defaultRoleId: String!
active: Boolean!
}

input DeleteConnectionInput {
id: String!
}
Expand Down
9 changes: 6 additions & 3 deletions packages/backend/src/models/saml-auth-provider.ee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class SamlAuthProvider extends Base {
id!: string;
name: string;
certificate: string;
signatureAlgorithm: SamlConfig["signatureAlgorithm"];
signatureAlgorithm: SamlConfig['signatureAlgorithm'];
issuer: string;
entryPoint: string;
firstnameAttributeName: string;
Expand Down Expand Up @@ -39,7 +39,10 @@ class SamlAuthProvider extends Base {
id: { type: 'string', format: 'uuid' },
name: { type: 'string', minLength: 1 },
certificate: { type: 'string', minLength: 1 },
signatureAlgorithm: { type: 'string', enum: ['sha1', 'sha256', 'sha512'] },
signatureAlgorithm: {
type: 'string',
enum: ['sha1', 'sha256', 'sha512'],
},
issuer: { type: 'string', minLength: 1 },
entryPoint: { type: 'string', minLength: 1 },
firstnameAttributeName: { type: 'string', minLength: 1 },
Expand Down Expand Up @@ -74,7 +77,7 @@ class SamlAuthProvider extends Base {
entryPoint: this.entryPoint,
issuer: this.issuer,
signatureAlgorithm: this.signatureAlgorithm,
}
};
}
}

Expand Down
22 changes: 10 additions & 12 deletions packages/backend/src/models/user.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import bcrypt from 'bcrypt';
import { DateTime } from 'luxon';
import crypto from 'node:crypto';
import {
ModelOptions,
QueryContext
} from 'objection';
import { ModelOptions, QueryContext } from 'objection';

import appConfig from '../config/app';
import checkLicense from '../helpers/check-license.ee';
Expand Down Expand Up @@ -164,8 +161,8 @@ class User extends Base {
join: {
from: 'identities.user_id',
to: 'users.id',
}
}
},
},
});

login(password: string) {
Expand Down Expand Up @@ -299,8 +296,10 @@ class User extends Base {
if (Array.isArray(this.permissions)) {
this.permissions = this.permissions.filter((permission) => {
const isRolePermission = permission.subject === 'Role';
const isSamlAuthProviderPermission =
permission.subject === 'SamlAuthProvider';

return !isRolePermission;
return !isRolePermission && !isSamlAuthProviderPermission;
});
}

Expand All @@ -318,11 +317,10 @@ class User extends Base {

const relevantRule = this.ability.relevantRuleFor(action, subject);

const conditions = relevantRule?.conditions as string[] || [];
const conditionMap: Record<string, true> = Object
.fromEntries(
conditions.map((condition) => [condition, true])
)
const conditions = (relevantRule?.conditions as string[]) || [];
const conditionMap: Record<string, true> = Object.fromEntries(
conditions.map((condition) => [condition, true])
);

return conditionMap;
}
Expand Down
Loading