Skip to content

Commit

Permalink
Merge pull request #3761 from uselagoon/refactor-last-accessed-db
Browse files Browse the repository at this point in the history
refactor: use api to store last accessed for user
  • Loading branch information
tobybellwood authored Dec 29, 2024
2 parents f425c21 + 3383894 commit 1fdfc9a
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = async function(knex) {
userTable = await knex.schema.hasTable('user');
if (!userTable) {
return knex.schema
.createTable('user', function (table) {
table.specificType('usid', 'CHAR(36)');
table.datetime('last_accessed');
table.primary(['usid']);
})
}
else {
return knex.schema
}
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = async function(knex) {
return knex.schema.dropTable('user');
};
36 changes: 24 additions & 12 deletions services/api/src/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Group, GroupType, KeycloakLagoonGroup } from './group';
import { Sql } from '../resources/user/sql';
import { getConfigFromEnv } from '../util/config';
import { Helpers as groupHelpers } from '../resources/group/helpers';
import { logger } from '../loggers/logger';

interface IUserAttributes {
comment?: [string];
Expand All @@ -20,6 +21,7 @@ export interface User {
firstName?: string;
lastName?: string;
comment?: string;
created?: string;
lastAccessed?: string;
gitlabId?: string;
attributes?: IUserAttributes;
Expand Down Expand Up @@ -178,23 +180,22 @@ export const User = (clients: {
R.pipe(
R.pick(['id', 'email', 'username', 'firstName', 'lastName', 'attributes', 'admin', 'owner', 'organizationRole', 'platformRoles']),
// @ts-ignore
R.set(commentLens, R.view(attrCommentLens, keycloakUser))
R.set(commentLens, R.view(attrCommentLens, keycloakUser)),
// set the user created time
R.set(R.lensPath(['created']), new Date(keycloakUser.createdTimestamp).toISOString().slice(0, 19).replace('T', ' ') || null),
)(keycloakUser)
);

let usersWithGitlabIdFetch = [];

for (const user of users) {
// set the lastaccessed attribute
// @TODO: no op last accessed for the time being due to raciness
// @TODO: refactor later
/*
let date = null;
if (user['attributes'] && user['attributes']['last_accessed']) {
date = new Date(user['attributes']['last_accessed']*1000).toISOString()
user.lastAccessed = date
const userdate = await query(
sqlClientPool,
Sql.selectLastAccessed(user.id)
);
if (userdate.length) {
user.lastAccessed = userdate[0].lastAccessed
}
*/
usersWithGitlabIdFetch.push({
...user,
gitlabId: await fetchGitlabId(user)
Expand Down Expand Up @@ -648,8 +649,14 @@ export const User = (clients: {

const userLastAccessed = async (userInput: User): Promise<Boolean> => {
// set the last accessed as a unix timestamp on the user attributes
// @TODO: no op last accessed for the time being due to raciness
// @TODO: refactor later
try {
await query(
sqlClientPool,
Sql.updateLastAccessed(userInput.id)
);
} catch (err) {
logger.warn(`Error updating user: ${err.message}`);
}
return true
};

Expand Down Expand Up @@ -754,6 +761,11 @@ export const User = (clients: {
sqlClientPool,
Sql.deleteFromUserSshKeys(id)
);
// delete from the user table
await query(
sqlClientPool,
Sql.deleteFromUser(id)
);

await keycloakAdminClient.users.del({ id });
} catch (err) {
Expand Down
19 changes: 19 additions & 0 deletions services/api/src/resources/user/sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,23 @@ export const Sql = {
.where('sk.key_fingerprint', keyFingerprint)
.select('user_ssh_key.usid')
.toString(),
updateLastAccessed: (id: string) =>
knex('user')
.insert({
usid: id,
lastAccessed: knex.fn.now(),
})
.onConflict('usid')
.merge()
.toString(),
selectLastAccessed: (id: string) =>
knex('user')
.select('last_accessed')
.where('usid','=',id)
.toString(),
deleteFromUser: (id: string) =>
knex('user')
.where('usid', id)
.delete()
.toString(),
};
5 changes: 2 additions & 3 deletions services/api/src/typeDefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,9 @@ const typeDefs = gql`
# This just returns the group name, id and the role the user has in that group.
# This is a neat way to visualize a users specific access without having to get all members of a group
groupRoles: [GroupRoleInterface]
# @TODO: no op last accessed for the time being due to raciness
# @TODO: refactor later
# lastAccessed: String
platformRoles: [PlatformRole]
created: String
lastAccessed: String
}
enum PlatformRole {
Expand Down

0 comments on commit 1fdfc9a

Please sign in to comment.