Skip to content

Commit

Permalink
wip: ADDING post route
Browse files Browse the repository at this point in the history
  • Loading branch information
hexaltation committed Nov 25, 2024
1 parent 7fe8709 commit 626dcc1
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 41 deletions.
2 changes: 2 additions & 0 deletions app/common/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export enum UserTypes {
'service'
}

export type UserTypesStrings = keyof typeof UserTypes;

/**
* Information about a user, including any user attributes.
*/
Expand Down
29 changes: 29 additions & 0 deletions app/gen-server/ApiServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,35 @@ export class ApiServer {
if (data) { this._logDeleteUserEvents(req, data); }
return sendReply(req, res, result);
}));

// POST /service-accounts/
// Creates a new service account attached to the user making the api call.
this._app.post('/api/service-accounts', expressWrap(async (req, res) => {
const userId = getAuthorizedUserId(req);
const serviceAccount: any = await this._dbManager.createServiceAccount(req.body);
return sendOkReply(req, res, {
key:serviceAccount.key,
});
throw new ApiError(`${userId} post Not implemented yet ;)`, 501);
}));

// GET /service-accounts/
// Reads all service accounts attached to the user making the api call.
this._app.get('/api/service-accounts', expressWrap(async (req, res) => {
throw new ApiError('get Not implemented yet ;)', 501);
}));

// GET /service-accounts/:said
// Reads one particular service account of the user making the api call.
this._app.get('/api/service-accounts/:said', expressWrap(async (req, res) => {
throw new ApiError('get by id Not implemented yet ;)', 501);
}));

// DELETE /service-accounts/:said
// Deletes one particular service account of the user making the api call.
this._app.delete('/api/service-accounts/:said', expressWrap(async (req, res) => {
throw new ApiError('delete by id Not implemented yet ;)', 501);
}));
}

private async _getFullUser(req: Request, options: {includePrefs?: boolean} = {}): Promise<FullUser> {
Expand Down
17 changes: 7 additions & 10 deletions app/gen-server/entity/ServiceAccount.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import {BaseEntity, Column, Entity, JoinTable, ManyToOne, PrimaryGeneratedColumn} from "typeorm";
import { User } from './User';
import {BaseEntity, Column, Entity, PrimaryGeneratedColumn} from "typeorm";

@Entity({name: 'service_accounts'})
export class ServiceAccount extends BaseEntity {

@PrimaryGeneratedColumn()
public id: number;

@Column({type: Number})
public owner_id: number;

@Column({type: Number})
public service_user_id: number;

@Column({type: String})
public description: string;

@Column({type: Date, nullable: false})
public endOfLife: string;

@ManyToOne(type => User)
@JoinTable({
name: 'service_account_user',
joinColumn: {name: 'service_account_id'},
inverseJoinColumn: {name: 'user_id'}
})
public service_account_owner: User;
}
4 changes: 2 additions & 2 deletions app/gen-server/entity/User.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {UserOptions} from 'app/common/UserAPI';
import {UserTypes} from 'app/common/User';
import {UserTypesStrings} from 'app/common/User';
import {nativeValues} from 'app/gen-server/lib/values';
import {makeId} from 'app/server/lib/idUtils';
import {BaseEntity, BeforeInsert, Column, Entity, JoinTable, ManyToMany, OneToMany, OneToOne,
Expand Down Expand Up @@ -74,7 +74,7 @@ export class User extends BaseEntity {
public ref: string;

@Column({name: 'type', type: String, default: 'login'})
public type: UserTypes | null;
public type: UserTypesStrings | null;

@BeforeInsert()
public async beforeInsert() {
Expand Down
14 changes: 14 additions & 0 deletions app/gen-server/lib/homedb/HomeDBManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import {
WhereExpressionBuilder
} from "typeorm";
import {v4 as uuidv4} from "uuid";
import { ServiceAccountsManager } from './ServiceAccountsManager';

// Support transactions in Sqlite in async code. This is a monkey patch, affecting
// the prototypes of various TypeORM classes.
Expand Down Expand Up @@ -258,6 +259,7 @@ export type BillingOptions = Partial<Pick<BillingAccount,
*/
export class HomeDBManager extends EventEmitter {
private _usersManager = new UsersManager(this, this._runInTransaction.bind(this));
private _serviceAccountsManager = new ServiceAccountsManager(this);
private _connection: DataSource;
private _exampleWorkspaceId: number;
private _exampleOrgId: number;
Expand Down Expand Up @@ -3104,6 +3106,18 @@ export class HomeDBManager extends EventEmitter {
return query.getOne();
}

public async deleteAllServiceAccounts(){
return this._serviceAccountsManager.deleteAllServiceAccounts();
}

public async createServiceAccount(
ownerId: number,
description?: string,
endOfLife?: Date
){
return this._serviceAccountsManager.createServiceAccount(ownerId, description, endOfLife);
}

private _installConfig(
key: ConfigKey,
{ manager }: { manager?: EntityManager }
Expand Down
55 changes: 55 additions & 0 deletions app/gen-server/lib/homedb/ServiceAccountsManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { HomeDBManager } from 'app/gen-server/lib/homedb/HomeDBManager';
//import { UsersManager } from 'app/gen-server/lib/homedb/UsersManager';
import { EntityManager } from 'typeorm';
import { User } from 'app/gen-server/entity/User';
import {v4 as uuidv4} from 'uuid';
//import { ServiceAccount } from 'app/gen-server/entity/ServiceAccount';

export class ServiceAccountsManager {

private get _connection () {
return this._homeDb.connection;
}

public constructor(
private readonly _homeDb: HomeDBManager,
//private _runInTransaction: RunInTransaction
) {}

// This method is implemented for test purpose only
// Using it outside of tests context will lead to partial db
// destruction
public async deleteAllServiceAccounts(optManager?: EntityManager){
const manager = optManager || new EntityManager(this._connection);
const queryBuilder = manager.createQueryBuilder()
.delete()
.from(User, 'users')
.where('users.type ="service"');
return await queryBuilder.execute();
}

public async createServiceAccount(
ownerId: number,
description?: string,
endOfLife?: Date,
){
await this._connection.transaction(async manager => {
//TODO create new service user in order to have its
//id to insert
const uuid = uuidv4();
const email = `${uuid}@serviceaccounts.local`;
const serviceUser = await this._homeDb.getUserByLogin(email);
// FIXME use manager.save(entité);
return await manager.createQueryBuilder()
.insert()
.into('service_accounts')
.values({
ownerId,
serviceUserId: serviceUser.id,
description,
endOfLife,
})
.execute();
});
}
}
6 changes: 5 additions & 1 deletion app/gen-server/lib/homedb/UsersManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { Pref } from 'app/gen-server/entity/Pref';
import flatten from 'lodash/flatten';
import { EntityManager } from 'typeorm';

import { UserTypesStrings } from 'app/common/User';

// A special user allowed to add/remove the EVERYONE_EMAIL to/from a resource.
export const SUPPORT_EMAIL = appSettings.section('access').flag('supportEmail').requireString({
envVar: 'GRIST_SUPPORT_EMAIL',
Expand Down Expand Up @@ -364,7 +366,7 @@ export class UsersManager {
* unset/outdated fields of an existing record.
*
*/
public async getUserByLogin(email: string, options: GetUserOptions = {}) {
public async getUserByLogin(email: string, options: GetUserOptions = {}, type?: UserTypesStrings) {
const {manager: transaction, profile, userOptions} = options;
const normalizedEmail = normalizeEmail(email);
return await this._runInTransaction(transaction, async manager => {
Expand All @@ -382,6 +384,8 @@ export class UsersManager {
// Special users do not have first time user set so that they don't get redirected to the
// welcome page.
user.isFirstTimeUser = !NON_LOGIN_EMAILS.includes(normalizedEmail);
// redémarrer lundi ici TODO
user.type = typeof type === 'undefined' ? 'login' : type;
login = new Login();
login.email = normalizedEmail;
login.user = user;
Expand Down
42 changes: 17 additions & 25 deletions app/gen-server/migration/1730215435023-ServiceAccounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,62 +23,54 @@ export class ServiceAccounts1730215435023 implements MigrationInterface {
isPrimary: true,
},
{
name: 'description',
type: 'varchar'
name: 'owner_id',
type: 'int',
},
{
name: 'endOfLife',
type: datetime,
isNullable: false,
name: 'service_user_id',
type: 'int',
},
],
})
);
await queryRunner.createTable(
new Table({
name: 'service_account_user',
columns: [
{
name: 'service_account_id',
type: 'int',
name: 'description',
type: 'varchar',
},
{
name: 'user_id',
type: 'int'
name: 'endOfLife',
type: datetime,
isNullable: false,
},
],
})
);
await queryRunner.createForeignKey(
'service_account_user',
'service_accounts',
new TableForeignKey({
columnNames: ['service_account_id'],
columnNames: ['service_user_id'],
referencedColumnNames: ['id'],
referencedTableName: 'service_accounts',
referencedTableName: 'users',
onDelete: 'CASCADE',
})
);
await queryRunner.createForeignKey(
'service_account_user',
'service_accounts',
new TableForeignKey({
columnNames: ['user_id'],
columnNames: ['owner_id'],
referencedColumnNames: ['id'],
referencedTableName: 'users',
onDelete: 'CASCADE',
})
);
await queryRunner.createIndex(
'service_account_user',
'service_accounts',
new TableIndex({
name: 'service_account__user',
columnNames: ['service_account_id', 'user_id'],
name: 'service_account__owner',
columnNames: ['service_accounts_owner', 'user_id'],
})
);
}

public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.dropColumn('users', 'type');
await queryRunner.dropTable('service_accounts');
await queryRunner.dropTable('service_account_user');
}
}
8 changes: 5 additions & 3 deletions test/gen-server/ApiServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2350,9 +2350,7 @@ describe('ApiServer', function() {

afterEach(async function() {
oldEnv.restore();
// FIXME create the new method to delete services accounts
//const did = await dbManager.testGetId('Curiosity');
// await dbManager.deleteServices(did as string);
await dbManager.deleteAllServiceAccounts();
});

after(async function() {
Expand Down Expand Up @@ -2420,6 +2418,10 @@ describe('ApiServer', function() {
// it('Endpoint UPDATE /api/service-accounts/{saId}/transfer-to/{userId}', async function() {

// });

// it('MUSN'T connect as a login user, async function() {

//});
});
});

Expand Down

0 comments on commit 626dcc1

Please sign in to comment.