diff --git a/services/api/src/resolvers.js b/services/api/src/resolvers.js index b62b5128e9..756c236762 100644 --- a/services/api/src/resolvers.js +++ b/services/api/src/resolvers.js @@ -207,6 +207,7 @@ const { const { getMe, getUserBySshKey, + getUserBySshFingerprint, addUser, updateUser, deleteUser, @@ -464,6 +465,7 @@ const resolvers = { me: getMe, lagoonVersion: getLagoonVersion, userBySshKey: getUserBySshKey, + userBySshFingerprint: getUserBySshFingerprint, projectByGitUrl: getProjectByGitUrl, projectByName: getProjectByName, environmentsByKubernetes: getEnvironmentsByKubernetes, diff --git a/services/api/src/resources/user/resolvers.ts b/services/api/src/resources/user/resolvers.ts index 364004617e..bd613765cf 100644 --- a/services/api/src/resources/user/resolvers.ts +++ b/services/api/src/resources/user/resolvers.ts @@ -15,6 +15,13 @@ class SearchInputError extends Error { } } +class UserNotFoundError extends Error { + constructor(message: string) { + super(message); + this.name = 'UserNotFoundError'; + } +} + export const getUserBySshKey: ResolverFn = async ( _root, @@ -44,6 +51,29 @@ export const getUserBySshKey: ResolverFn = async ( return user; }; +export const getUserBySshFingerprint: ResolverFn = async ( + _root, + { fingerprint }, + { sqlClientPool, models, hasPermission }, +) => { + await hasPermission('user', 'getBySshKey'); + + if(!fingerprint) { + throw new SearchInputError("Malformed ssh key fingerprint provided"); + } + try { + const rows = await query( + sqlClientPool, + Sql.selectUserIdBySshFingerprint({keyFingerprint: fingerprint}), + ); + const userId = R.map(R.prop('usid'), rows); + const user = await models.UserModel.loadUserById(userId); + return user; + } catch (err) { + throw new UserNotFoundError("No user found matching provided fingerprint"); + } +}; + // query to get all users, with some inputs to limit the search to specific email, id, or gitlabId export const getAllUsers: ResolverFn = async ( _root, diff --git a/services/api/src/resources/user/sql.ts b/services/api/src/resources/user/sql.ts index 1e3143b754..a5b2ed46c4 100644 --- a/services/api/src/resources/user/sql.ts +++ b/services/api/src/resources/user/sql.ts @@ -14,4 +14,14 @@ export default { .andWhere('sk.key_type', keyType) .select('user_ssh_key.usid') .toString(), + selectUserIdBySshFingerprint: ({ + keyFingerprint, + }: { + keyFingerprint: string; + }): string => + knex('user_ssh_key') + .join('ssh_key as sk', 'sk.id', '=', 'user_ssh_key.skid') + .where('sk.key_fingerprint', keyFingerprint) + .select('user_ssh_key.usid') + .toString(), }; diff --git a/services/api/src/typeDefs.js b/services/api/src/typeDefs.js index eb4bfb3af9..4cc7336c0a 100644 --- a/services/api/src/typeDefs.js +++ b/services/api/src/typeDefs.js @@ -1098,6 +1098,10 @@ const typeDefs = gql` """ userBySshKey(sshKey: String!): User """ + Returns User Object by a given sshKey Fingerprint + """ + userBySshFingerprint(fingerprint: String!): User + """ Returns User Object by a given email address """ userByEmail(email: String!): User