fix: add service token read value permissions

This commit is contained in:
Daniel Hougaard
2025-03-05 22:47:40 +04:00
parent 2a8bd74e88
commit b00413817d
2 changed files with 69 additions and 1 deletions
@@ -89,6 +89,37 @@ export async function up(knex: Knex): Promise<void> {
const projectUserAdditionalPrivileges = await knex(TableName.ProjectUserAdditionalPrivilege).select( const projectUserAdditionalPrivileges = await knex(TableName.ProjectUserAdditionalPrivilege).select(
selectAllTableCols(TableName.ProjectUserAdditionalPrivilege) selectAllTableCols(TableName.ProjectUserAdditionalPrivilege)
); );
const serviceTokens = await knex(TableName.ServiceToken).select(selectAllTableCols(TableName.ServiceToken));
const updatedServiceTokens = serviceTokens.reduce<typeof serviceTokens>((acc, serviceToken) => {
const { permissions } = serviceToken; // Service tokens are special, and include an array of actions only.
if (permissions.includes(SecretActions.Read) && !permissions.includes(SecretActions.ReadValue)) {
permissions.push(SecretActions.ReadValue);
acc.push({
...serviceToken,
permissions
});
}
return acc;
}, []);
if (updatedServiceTokens.length > 0) {
await knex(TableName.ServiceToken)
.whereIn(
"id",
updatedServiceTokens.map((t) => t.id)
)
.update({
// @ts-expect-error -- raw query
permissions: knex.raw(
`CASE id
${updatedServiceTokens.map((t) => `WHEN '${t.id}' THEN ?::text[]`).join(" ")}
END`,
updatedServiceTokens.map((t) => t.permissions)
)
});
}
const updatedRoles = projectRoles.reduce<typeof projectRoles>((acc, projectRole) => { const updatedRoles = projectRoles.reduce<typeof projectRoles>((acc, projectRole) => {
const { shouldUpdate, parsedPermissions } = $updatePermissionsUp(projectRole.permissions); const { shouldUpdate, parsedPermissions } = $updatePermissionsUp(projectRole.permissions);
@@ -157,6 +188,37 @@ export async function down(knex: Knex): Promise<void> {
const userAdditionalPrivileges = await knex(TableName.ProjectUserAdditionalPrivilege).select( const userAdditionalPrivileges = await knex(TableName.ProjectUserAdditionalPrivilege).select(
selectAllTableCols(TableName.ProjectUserAdditionalPrivilege) selectAllTableCols(TableName.ProjectUserAdditionalPrivilege)
); );
const serviceTokens = await knex(TableName.ServiceToken).select(selectAllTableCols(TableName.ServiceToken));
const updatedServiceTokens = serviceTokens.reduce<typeof serviceTokens>((acc, serviceToken) => {
const { permissions } = serviceToken;
if (permissions.includes(SecretActions.ReadValue)) {
permissions.splice(permissions.indexOf(SecretActions.ReadValue), 1);
acc.push({
...serviceToken,
permissions
});
}
return acc;
}, []);
if (updatedServiceTokens.length > 0) {
await knex(TableName.ServiceToken)
.whereIn(
"id",
updatedServiceTokens.map((t) => t.id)
)
.update({
// @ts-expect-error -- raw query
permissions: knex.raw(
`CASE id
${updatedServiceTokens.map((t) => `WHEN '${t.id}' THEN ?::text[]`).join(" ")}
END`,
updatedServiceTokens.map((t) => t.permissions)
)
});
}
const updatedRoles = projectRoles.reduce<typeof projectRoles>((acc, projectRole) => { const updatedRoles = projectRoles.reduce<typeof projectRoles>((acc, projectRole) => {
const { shouldUpdate, repackedPermissions } = $updatePermissionsDown(projectRole.permissions); const { shouldUpdate, repackedPermissions } = $updatePermissionsDown(projectRole.permissions);
@@ -58,6 +58,7 @@ const schema = z.object({
permissions: z permissions: z
.object({ .object({
read: z.boolean(), read: z.boolean(),
readValue: z.boolean(),
write: z.boolean() write: z.boolean()
}) })
.required() .required()
@@ -296,14 +297,19 @@ export const AddServiceTokenModal = ({ popUp, handlePopUpToggle }: Props) => {
name="permissions" name="permissions"
defaultValue={{ defaultValue={{
read: true, read: true,
readValue: false,
write: false write: false
}} }}
render={({ field: { onChange, value }, fieldState: { error } }) => { render={({ field: { onChange, value }, fieldState: { error } }) => {
const options = [ const options = [
{ {
label: "Read (default)", label: "Describe Secret (default)",
value: "read" value: "read"
}, },
{
label: "Read Value (optional)",
value: "readValue"
},
{ {
label: "Write (optional)", label: "Write (optional)",
value: "write" value: "write"