mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
feat: allows creation of PATs for other users (#2718)
https://linear.app/unleash/issue/2-530/api-allow-creation-of-pats-for-other-users ![image](https://user-images.githubusercontent.com/14320932/208720680-5d5ccee7-1972-4f5b-8024-3a69d50a571f.png) Adds and takes into account the following permissions: - **READ_USER_PAT**; - **CREATE_USER_PAT**; - **DELETE_USER_PAT**; API only, will make some exploration on UI soon. Co-authored-by: Gastón Fournier <gaston@getunleash.ai>
This commit is contained in:
parent
aab809cac3
commit
88004a6138
@ -36,3 +36,6 @@ export const DELETE_SEGMENT = 'DELETE_SEGMENT';
|
||||
export const APPLY_CHANGE_REQUEST = 'APPLY_CHANGE_REQUEST';
|
||||
export const APPROVE_CHANGE_REQUEST = 'APPROVE_CHANGE_REQUEST';
|
||||
export const SKIP_CHANGE_REQUEST = 'SKIP_CHANGE_REQUEST';
|
||||
export const READ_USER_PAT = 'READ_USER_PAT';
|
||||
export const CREATE_USER_PAT = 'CREATE_USER_PAT';
|
||||
export const DELETE_USER_PAT = 'DELETE_USER_PAT';
|
||||
|
@ -80,6 +80,7 @@ exports[`should create default config 1`] = `
|
||||
"networkView": false,
|
||||
"proxyReturnAllToggles": false,
|
||||
"responseTimeWithAppName": false,
|
||||
"serviceAccounts": false,
|
||||
"variantsPerEnvironment": false,
|
||||
},
|
||||
},
|
||||
@ -98,6 +99,7 @@ exports[`should create default config 1`] = `
|
||||
"networkView": false,
|
||||
"proxyReturnAllToggles": false,
|
||||
"responseTimeWithAppName": false,
|
||||
"serviceAccounts": false,
|
||||
"variantsPerEnvironment": false,
|
||||
},
|
||||
"externalResolver": {
|
||||
|
@ -78,7 +78,11 @@ export default class PatController extends Controller {
|
||||
|
||||
async createPat(req: IAuthRequest, res: Response): Promise<void> {
|
||||
const pat = req.body;
|
||||
const createdPat = await this.patService.createPat(pat, req.user);
|
||||
const createdPat = await this.patService.createPat(
|
||||
pat,
|
||||
req.user.id,
|
||||
req.user,
|
||||
);
|
||||
this.openApiService.respondWithValidation(
|
||||
201,
|
||||
res,
|
||||
@ -88,7 +92,7 @@ export default class PatController extends Controller {
|
||||
}
|
||||
|
||||
async getPats(req: IAuthRequest, res: Response<PatSchema>): Promise<void> {
|
||||
const pats = await this.patService.getAll(req.user);
|
||||
const pats = await this.patService.getAll(req.user.id);
|
||||
this.openApiService.respondWithValidation(200, res, patsSchema.$id, {
|
||||
pats: serializeDates(pats),
|
||||
});
|
||||
|
@ -33,24 +33,28 @@ export default class PatService {
|
||||
this.eventStore = eventStore;
|
||||
}
|
||||
|
||||
async createPat(pat: IPat, user: User): Promise<IPat> {
|
||||
await this.validatePat(pat, user.id);
|
||||
async createPat(
|
||||
pat: IPat,
|
||||
forUserId: number,
|
||||
creator: User,
|
||||
): Promise<IPat> {
|
||||
await this.validatePat(pat, forUserId);
|
||||
pat.secret = this.generateSecretKey();
|
||||
pat.userId = user.id;
|
||||
pat.userId = forUserId;
|
||||
const newPat = await this.patStore.create(pat);
|
||||
|
||||
pat.secret = '***';
|
||||
await this.eventStore.store({
|
||||
type: PAT_CREATED,
|
||||
createdBy: user.email || user.username,
|
||||
createdBy: creator.email || creator.username,
|
||||
data: pat,
|
||||
});
|
||||
|
||||
return newPat;
|
||||
}
|
||||
|
||||
async getAll(user: User): Promise<IPat[]> {
|
||||
return this.patStore.getAllByUser(user.id);
|
||||
async getAll(userId: number): Promise<IPat[]> {
|
||||
return this.patStore.getAllByUser(userId);
|
||||
}
|
||||
|
||||
async deletePat(id: number, userId: number): Promise<void> {
|
||||
|
@ -51,6 +51,10 @@ const flags = {
|
||||
process.env.UNLEASH_EXPERIMENTAL_MESSAGE_BANNER,
|
||||
false,
|
||||
),
|
||||
serviceAccounts: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_EXPERIMENTAL_SERVICE_ACCOUNTS,
|
||||
false,
|
||||
),
|
||||
};
|
||||
|
||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||
|
@ -42,3 +42,6 @@ export const DELETE_SEGMENT = 'DELETE_SEGMENT';
|
||||
export const APPROVE_CHANGE_REQUEST = 'APPROVE_CHANGE_REQUEST';
|
||||
export const APPLY_CHANGE_REQUEST = 'APPLY_CHANGE_REQUEST';
|
||||
export const SKIP_CHANGE_REQUEST = 'SKIP_CHANGE_REQUEST';
|
||||
export const READ_USER_PAT = 'READ_USER_PAT';
|
||||
export const CREATE_USER_PAT = 'CREATE_USER_PAT';
|
||||
export const DELETE_USER_PAT = 'DELETE_USER_PAT';
|
||||
|
21
src/migrations/20221220160345-user-pat-permissions.js
Normal file
21
src/migrations/20221220160345-user-pat-permissions.js
Normal file
@ -0,0 +1,21 @@
|
||||
exports.up = function (db, cb) {
|
||||
db.runSql(
|
||||
`
|
||||
INSERT INTO permissions (permission, display_name, type) VALUES ('READ_USER_PAT', 'Read PATs for a specific user', 'root');
|
||||
INSERT INTO permissions (permission, display_name, type) VALUES ('CREATE_USER_PAT', 'Create a PAT for a specific user', 'root');
|
||||
INSERT INTO permissions (permission, display_name, type) VALUES ('DELETE_USER_PAT', 'Delete a PAT for a specific user', 'root');
|
||||
`,
|
||||
cb,
|
||||
);
|
||||
};
|
||||
|
||||
exports.down = function (db, cb) {
|
||||
db.runSql(
|
||||
`
|
||||
DELETE FROM permissions WHERE permission = 'READ_USER_PAT';
|
||||
DELETE FROM permissions WHERE permission = 'CREATE_USER_PAT';
|
||||
DELETE FROM permissions WHERE permission = 'DELETE_USER_PAT';
|
||||
`,
|
||||
cb,
|
||||
);
|
||||
};
|
@ -41,6 +41,8 @@ process.nextTick(async () => {
|
||||
responseTimeWithAppName: true,
|
||||
changeRequests: true,
|
||||
variantsPerEnvironment: true,
|
||||
maintenance: false,
|
||||
serviceAccounts: true,
|
||||
},
|
||||
},
|
||||
authentication: {
|
||||
|
Loading…
Reference in New Issue
Block a user