Merge pull request #1195 from automatisch/saml-configuration-create
feat: Add createSamlAuthProvider graphQL mutation
This commit is contained in:
@@ -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();
|
||||
}
|
@@ -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,
|
||||
@@ -54,6 +55,7 @@ const mutationResolvers = {
|
||||
updateRole,
|
||||
updateStep,
|
||||
verifyConnection,
|
||||
createSamlAuthProvider,
|
||||
};
|
||||
|
||||
export default mutationResolvers;
|
||||
|
@@ -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;
|
@@ -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
|
||||
@@ -81,6 +78,7 @@ type Mutation {
|
||||
updateStep(input: UpdateStepInput): Step
|
||||
updateUser(input: UpdateUserInput): User
|
||||
verifyConnection(input: VerifyConnectionInput): Connection
|
||||
createSamlAuthProvider(input: CreateSamlAuthProviderInput): SamlAuthProvider
|
||||
}
|
||||
|
||||
"""
|
||||
@@ -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
|
||||
@@ -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!
|
||||
}
|
||||
|
@@ -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;
|
||||
@@ -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 },
|
||||
@@ -74,7 +77,7 @@ class SamlAuthProvider extends Base {
|
||||
entryPoint: this.entryPoint,
|
||||
issuer: this.issuer,
|
||||
signatureAlgorithm: this.signatureAlgorithm,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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';
|
||||
@@ -164,8 +161,8 @@ class User extends Base {
|
||||
join: {
|
||||
from: 'identities.user_id',
|
||||
to: 'users.id',
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
login(password: string) {
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user