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 APPLY_CHANGE_REQUEST = 'APPLY_CHANGE_REQUEST';
|
||||||
export const APPROVE_CHANGE_REQUEST = 'APPROVE_CHANGE_REQUEST';
|
export const APPROVE_CHANGE_REQUEST = 'APPROVE_CHANGE_REQUEST';
|
||||||
export const SKIP_CHANGE_REQUEST = 'SKIP_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,
|
"networkView": false,
|
||||||
"proxyReturnAllToggles": false,
|
"proxyReturnAllToggles": false,
|
||||||
"responseTimeWithAppName": false,
|
"responseTimeWithAppName": false,
|
||||||
|
"serviceAccounts": false,
|
||||||
"variantsPerEnvironment": false,
|
"variantsPerEnvironment": false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -98,6 +99,7 @@ exports[`should create default config 1`] = `
|
|||||||
"networkView": false,
|
"networkView": false,
|
||||||
"proxyReturnAllToggles": false,
|
"proxyReturnAllToggles": false,
|
||||||
"responseTimeWithAppName": false,
|
"responseTimeWithAppName": false,
|
||||||
|
"serviceAccounts": false,
|
||||||
"variantsPerEnvironment": false,
|
"variantsPerEnvironment": false,
|
||||||
},
|
},
|
||||||
"externalResolver": {
|
"externalResolver": {
|
||||||
|
@ -78,7 +78,11 @@ export default class PatController extends Controller {
|
|||||||
|
|
||||||
async createPat(req: IAuthRequest, res: Response): Promise<void> {
|
async createPat(req: IAuthRequest, res: Response): Promise<void> {
|
||||||
const pat = req.body;
|
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(
|
this.openApiService.respondWithValidation(
|
||||||
201,
|
201,
|
||||||
res,
|
res,
|
||||||
@ -88,7 +92,7 @@ export default class PatController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getPats(req: IAuthRequest, res: Response<PatSchema>): Promise<void> {
|
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, {
|
this.openApiService.respondWithValidation(200, res, patsSchema.$id, {
|
||||||
pats: serializeDates(pats),
|
pats: serializeDates(pats),
|
||||||
});
|
});
|
||||||
|
@ -33,24 +33,28 @@ export default class PatService {
|
|||||||
this.eventStore = eventStore;
|
this.eventStore = eventStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
async createPat(pat: IPat, user: User): Promise<IPat> {
|
async createPat(
|
||||||
await this.validatePat(pat, user.id);
|
pat: IPat,
|
||||||
|
forUserId: number,
|
||||||
|
creator: User,
|
||||||
|
): Promise<IPat> {
|
||||||
|
await this.validatePat(pat, forUserId);
|
||||||
pat.secret = this.generateSecretKey();
|
pat.secret = this.generateSecretKey();
|
||||||
pat.userId = user.id;
|
pat.userId = forUserId;
|
||||||
const newPat = await this.patStore.create(pat);
|
const newPat = await this.patStore.create(pat);
|
||||||
|
|
||||||
pat.secret = '***';
|
pat.secret = '***';
|
||||||
await this.eventStore.store({
|
await this.eventStore.store({
|
||||||
type: PAT_CREATED,
|
type: PAT_CREATED,
|
||||||
createdBy: user.email || user.username,
|
createdBy: creator.email || creator.username,
|
||||||
data: pat,
|
data: pat,
|
||||||
});
|
});
|
||||||
|
|
||||||
return newPat;
|
return newPat;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAll(user: User): Promise<IPat[]> {
|
async getAll(userId: number): Promise<IPat[]> {
|
||||||
return this.patStore.getAllByUser(user.id);
|
return this.patStore.getAllByUser(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deletePat(id: number, userId: number): Promise<void> {
|
async deletePat(id: number, userId: number): Promise<void> {
|
||||||
|
@ -51,6 +51,10 @@ const flags = {
|
|||||||
process.env.UNLEASH_EXPERIMENTAL_MESSAGE_BANNER,
|
process.env.UNLEASH_EXPERIMENTAL_MESSAGE_BANNER,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
serviceAccounts: parseEnvVarBoolean(
|
||||||
|
process.env.UNLEASH_EXPERIMENTAL_SERVICE_ACCOUNTS,
|
||||||
|
false,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||||
|
@ -42,3 +42,6 @@ export const DELETE_SEGMENT = 'DELETE_SEGMENT';
|
|||||||
export const APPROVE_CHANGE_REQUEST = 'APPROVE_CHANGE_REQUEST';
|
export const APPROVE_CHANGE_REQUEST = 'APPROVE_CHANGE_REQUEST';
|
||||||
export const APPLY_CHANGE_REQUEST = 'APPLY_CHANGE_REQUEST';
|
export const APPLY_CHANGE_REQUEST = 'APPLY_CHANGE_REQUEST';
|
||||||
export const SKIP_CHANGE_REQUEST = 'SKIP_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,
|
responseTimeWithAppName: true,
|
||||||
changeRequests: true,
|
changeRequests: true,
|
||||||
variantsPerEnvironment: true,
|
variantsPerEnvironment: true,
|
||||||
|
maintenance: false,
|
||||||
|
serviceAccounts: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
authentication: {
|
authentication: {
|
||||||
|
Loading…
Reference in New Issue
Block a user