-
-
Notifications
You must be signed in to change notification settings - Fork 23.5k
Feature/Add Permissions To API Keys #5590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
yau-wd
wants to merge
32
commits into
main
Choose a base branch
from
feature/api-key-permission
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,082
−780
Open
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
0e0b95b
feat(database.util.ts): add function to check if column exists in table
yau-wd 7aa5739
feat(migrations): add permission column to apikey table
yau-wd cde6400
chore(services/apikey): remove auto-create default API key
yau-wd 40fabc6
chore: remove auto-create default API key
yau-wd 63e6784
fix(migrations): rename permission to permissions in apikey table
yau-wd 28963b6
feat(services/apikey): add permissions to create and update
yau-wd ab252a2
feat(views/apikey): add permissions to create and update
yau-wd 5e5f730
feat(api): use API key permissions instead of role permissions
yau-wd cc545ba
feat(permissions): filter by user.permissions except for ROLE type
yau-wd 2e46bb6
feat(services/apikey): filter keys by user permissions in getAllApiKeys
yau-wd 952807b
feat(services/apikey): limit API key permissions to user permissions …
yau-wd c0d9b69
Merge branch 'main' into feature/api-key-permission
yau-wd aacfad5
fix(database.util.ts): replace non-null assertion with explicit error…
yau-wd 9d33318
feat(services/apikey): log errors for malformed API key permissions
yau-wd 9e24e04
refactor(services/apikey): extract permission validation
yau-wd 15d67b2
feat(permission): enhance permission filtering based on user features…
yau-wd e135f4b
chore(migrations): lower API key permission value
yau-wd 29dcb4c
Update packages/ui/src/views/apikey/APIKeyDialog.jsx
yau-wd 51500b7
Update packages/ui/src/views/apikey/APIKeyDialog.jsx
yau-wd 38ce74d
refactor: remove deprecated APIKEY_PATH and APIKEY migration
yau-wd 25a2d76
Merge branch 'main' into feature/api-key-permission
yau-wd 36cb002
refactor(apikey): remove functionality related to import apikey
yau-wd 2163e5b
feat(permission): filter out workspace and admin categories for non-ROLE
yau-wd 281c241
Merge branch 'main' into feature/api-key-permission
yau-wd d01c9e9
feat(services/apikey): validate API key permissions during create and…
yau-wd 6b04658
chore(migrations): clean up role permissions values
yau-wd 16d996a
fix(migrations): handle corrupted permissions gracefully
yau-wd 92beda6
fix(server/src/index.ts): add error handling for API key permissions …
yau-wd 61e765d
fix(APIKeyDialog.jsx): handle corrupted permissions when editing API key
yau-wd 772eede
fix(views/apikey/index.jsx): handle corrupted permissions in API key …
yau-wd 84835d7
fix(services/apikey): validate permissions JSON in API key operations
yau-wd cc1876f
Potential fix for code scanning alert no. 83: Clear-text logging of s…
yau-wd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
packages/server/src/database/migrations/mariadb/1765360298674-AddApiKeyPermission.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import { MigrationInterface, QueryRunner } from 'typeorm' | ||
| import { Role } from '../../../enterprise/database/entities/role.entity' | ||
| import { hasColumn } from '../../../utils/database.util' | ||
| import logger from '../../../utils/logger' | ||
|
|
||
| export class AddApiKeyPermission1765360298674 implements MigrationInterface { | ||
| public async up(queryRunner: QueryRunner): Promise<void> { | ||
| const tableName = 'apikey' | ||
| const columnName = 'permissions' | ||
|
|
||
| const columnExists = await hasColumn(queryRunner, tableName, columnName) | ||
| if (!columnExists) { | ||
| await queryRunner.query(`ALTER TABLE \`${tableName}\` ADD COLUMN \`${columnName}\` TEXT NOT NULL DEFAULT ('[]');`) | ||
|
|
||
| const permission = | ||
| '["chatflows:view","chatflows:create","chatflows:update","chatflows:duplicate","chatflows:delete","chatflows:export","chatflows:import","chatflows:config","chatflows:domains","agentflows:view","agentflows:create","agentflows:update","agentflows:duplicate","agentflows:delete","agentflows:export","agentflows:import","agentflows:config","agentflows:domains","tools:view","tools:create","tools:update","tools:delete","tools:export","assistants:view","assistants:create","assistants:update","assistants:delete","credentials:view","credentials:create","credentials:update","credentials:delete","variables:view","variables:create","variables:update","variables:delete","apikeys:view","apikeys:create","apikeys:update","apikeys:delete","documentStores:view","documentStores:create","documentStores:update","documentStores:delete","documentStores:add-loader","documentStores:delete-loader","documentStores:preview-process","documentStores:upsert-config","executions:view","executions:delete","templates:marketplace","templates:custom","templates:custom-delete","templates:toolexport","templates:flowexport"]' | ||
|
|
||
| await queryRunner.query(`UPDATE \`${tableName}\` SET \`${columnName}\` = '${permission}';`) | ||
| } | ||
|
|
||
| const sso = 'sso:manage' | ||
| const apikey = 'apikeys:import' | ||
| const itemsToRemove = [sso, apikey] | ||
| const roles: Role[] = await queryRunner.query( | ||
| `SELECT * FROM \`role\` WHERE \`${columnName}\` LIKE '%${sso}%' OR \`${columnName}\` LIKE '%${apikey}%';` | ||
| ) | ||
| if (roles.length > 0) { | ||
| for (const role of roles) { | ||
| let permissions: string[] = [] | ||
| try { | ||
| permissions = JSON.parse(role.permissions) | ||
| } catch (error) { | ||
| logger.error(`AddApiKeyPermission1765360298674 error parsing permissions for role ${role.id}:`, error) | ||
| continue | ||
| } | ||
| permissions = permissions.filter((permission: string) => !itemsToRemove.includes(permission)) | ||
| await queryRunner.query( | ||
| `UPDATE \`role\` SET \`${columnName}\` = '${JSON.stringify(permissions)}' WHERE \`id\` = '${role.id}';` | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public async down(): Promise<void> {} | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
packages/server/src/database/migrations/mysql/1765360298674-AddApiKeyPermission.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import { MigrationInterface, QueryRunner } from 'typeorm' | ||
| import { Role } from '../../../enterprise/database/entities/role.entity' | ||
| import { hasColumn } from '../../../utils/database.util' | ||
| import logger from '../../../utils/logger' | ||
|
|
||
| export class AddApiKeyPermission1765360298674 implements MigrationInterface { | ||
| public async up(queryRunner: QueryRunner): Promise<void> { | ||
| const tableName = 'apikey' | ||
| const columnName = 'permissions' | ||
|
|
||
| const columnExists = await hasColumn(queryRunner, tableName, columnName) | ||
| if (!columnExists) { | ||
| await queryRunner.query(`ALTER TABLE \`${tableName}\` ADD COLUMN \`${columnName}\` TEXT NOT NULL DEFAULT ('[]');`) | ||
|
|
||
| const permission = | ||
| '["chatflows:view","chatflows:create","chatflows:update","chatflows:duplicate","chatflows:delete","chatflows:export","chatflows:import","chatflows:config","chatflows:domains","agentflows:view","agentflows:create","agentflows:update","agentflows:duplicate","agentflows:delete","agentflows:export","agentflows:import","agentflows:config","agentflows:domains","tools:view","tools:create","tools:update","tools:delete","tools:export","assistants:view","assistants:create","assistants:update","assistants:delete","credentials:view","credentials:create","credentials:update","credentials:delete","variables:view","variables:create","variables:update","variables:delete","apikeys:view","apikeys:create","apikeys:update","apikeys:delete","documentStores:view","documentStores:create","documentStores:update","documentStores:delete","documentStores:add-loader","documentStores:delete-loader","documentStores:preview-process","documentStores:upsert-config","executions:view","executions:delete","templates:marketplace","templates:custom","templates:custom-delete","templates:toolexport","templates:flowexport"]' | ||
|
|
||
| await queryRunner.query(`UPDATE \`${tableName}\` SET \`${columnName}\` = '${permission}';`) | ||
| } | ||
|
|
||
| const sso = 'sso:manage' | ||
| const apikey = 'apikeys:import' | ||
| const itemsToRemove = [sso, apikey] | ||
| const roles: Role[] = await queryRunner.query( | ||
| `SELECT * FROM \`role\` WHERE \`${columnName}\` LIKE '%${sso}%' OR \`${columnName}\` LIKE '%${apikey}%';` | ||
| ) | ||
| if (roles.length > 0) { | ||
| for (const role of roles) { | ||
| let permissions: string[] = [] | ||
| try { | ||
| permissions = JSON.parse(role.permissions) | ||
| } catch (error) { | ||
| logger.error(`AddApiKeyPermission1765360298674 error parsing permissions for role ${role.id}:`, error) | ||
| continue | ||
| } | ||
| permissions = permissions.filter((permission: string) => !itemsToRemove.includes(permission)) | ||
| await queryRunner.query( | ||
| `UPDATE \`role\` SET \`${columnName}\` = '${JSON.stringify(permissions)}' WHERE \`id\` = '${role.id}';` | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public async down(): Promise<void> {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
packages/server/src/database/migrations/postgres/1765360298674-AddApiKeyPermission.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import { MigrationInterface, QueryRunner } from 'typeorm' | ||
| import { Role } from '../../../enterprise/database/entities/role.entity' | ||
| import { hasColumn } from '../../../utils/database.util' | ||
| import logger from '../../../utils/logger' | ||
|
|
||
| export class AddApiKeyPermission1765360298674 implements MigrationInterface { | ||
| public async up(queryRunner: QueryRunner): Promise<void> { | ||
| const tableName = 'apikey' | ||
| const columnName = 'permissions' | ||
|
|
||
| const columnExists = await hasColumn(queryRunner, tableName, columnName) | ||
| if (!columnExists) { | ||
| await queryRunner.query(`ALTER TABLE "${tableName}" ADD COLUMN "${columnName}" TEXT NOT NULL DEFAULT '[]';`) | ||
|
|
||
| const permission = | ||
| '["chatflows:view","chatflows:create","chatflows:update","chatflows:duplicate","chatflows:delete","chatflows:export","chatflows:import","chatflows:config","chatflows:domains","agentflows:view","agentflows:create","agentflows:update","agentflows:duplicate","agentflows:delete","agentflows:export","agentflows:import","agentflows:config","agentflows:domains","tools:view","tools:create","tools:update","tools:delete","tools:export","assistants:view","assistants:create","assistants:update","assistants:delete","credentials:view","credentials:create","credentials:update","credentials:delete","variables:view","variables:create","variables:update","variables:delete","apikeys:view","apikeys:create","apikeys:update","apikeys:delete","documentStores:view","documentStores:create","documentStores:update","documentStores:delete","documentStores:add-loader","documentStores:delete-loader","documentStores:preview-process","documentStores:upsert-config","executions:view","executions:delete","templates:marketplace","templates:custom","templates:custom-delete","templates:toolexport","templates:flowexport"]' | ||
|
|
||
| await queryRunner.query(`UPDATE "${tableName}" SET "${columnName}" = '${permission}';`) | ||
| } | ||
|
|
||
| const sso = 'sso:manage' | ||
| const apikey = 'apikeys:import' | ||
| const itemsToRemove = [sso, apikey] | ||
| const roles: Role[] = await queryRunner.query( | ||
| `SELECT * FROM "role" WHERE "${columnName}" LIKE '%${sso}%' OR "${columnName}" LIKE '%${apikey}%';` | ||
| ) | ||
| if (roles.length > 0) { | ||
| for (const role of roles) { | ||
| let permissions: string[] = [] | ||
| try { | ||
| permissions = JSON.parse(role.permissions) | ||
| } catch (error) { | ||
| logger.error(`AddApiKeyPermission1765360298674 error parsing permissions for role ${role.id}:`, error) | ||
| continue | ||
| } | ||
| permissions = permissions.filter((permission: string) => !itemsToRemove.includes(permission)) | ||
| await queryRunner.query(`UPDATE "role" SET "${columnName}" = '${JSON.stringify(permissions)}' WHERE "id" = '${role.id}';`) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public async down(): Promise<void> {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.