diff --git a/src/modules/oauth2/entity.rs b/src/modules/oauth2/entity.rs index ac6bd15..f3cb806 100644 --- a/src/modules/oauth2/entity.rs +++ b/src/modules/oauth2/entity.rs @@ -20,8 +20,8 @@ use crate::{ encrypt, id, modules::{ database::{ - delete_impl, insert_impl, manager::DB_MANAGER, paginate_query_primary_scan_all_impl, - async_secondary_find_impl, update_impl, + async_secondary_find_impl, delete_impl, insert_impl, manager::DB_MANAGER, + paginate_query_primary_scan_all_impl, update_impl, }, error::{code::ErrorCode, BichonResult}, rest::response::DataPage, @@ -109,9 +109,9 @@ impl OAuth2 { self.client_id = mask.to_string(); self.client_secret = mask.to_string(); - self.auth_url = mask.to_string(); - self.token_url = mask.to_string(); - self.redirect_uri = mask.to_string(); + self.auth_url = self.auth_url.clone(); + self.token_url = self.token_url.clone(); + self.redirect_uri = self.redirect_uri.clone(); self.scopes = None; self.extra_params = None; diff --git a/src/modules/rest/api/oauth2.rs b/src/modules/rest/api/oauth2.rs index 574e20a..9c7056a 100644 --- a/src/modules/rest/api/oauth2.rs +++ b/src/modules/rest/api/oauth2.rs @@ -35,10 +35,10 @@ pub struct OAuth2Api; #[OpenApi(prefix_path = "/api/v1", tag = "ApiTags::OAuth2")] impl OAuth2Api { - /// Retrieves the OAuth2 configuration for a specified name. + /// Retrieves the OAuth2 configuration for a specified id. /// /// Requires root privileges. - /// This endpoint fetches the OAuth2 configuration identified by the given name. + /// This endpoint fetches the OAuth2 configuration identified by the given id. #[oai( path = "/oauth2/:id", method = "get", @@ -46,7 +46,7 @@ impl OAuth2Api { )] async fn get_oauth2_config( &self, - /// The name of the OAuth2 configuration to retrieve + /// The id of the OAuth2 configuration to retrieve id: Path, context: ClientContext, ) -> ApiResult> { @@ -57,17 +57,9 @@ impl OAuth2Api { ErrorCode::ResourceNotFound ) })?; - if context - .has_permission(None, Permission::ROOT) - .await - { + if context.has_permission(None, Permission::ROOT).await { return Ok(Json(oauth2)); } - - context - .require_permission(None, Permission::ACCOUNT_CREATE) - .await?; - oauth2.scrub_sensitive_fields(); Ok(Json(oauth2)) } @@ -87,9 +79,7 @@ impl OAuth2Api { id: Path, context: ClientContext, ) -> ApiResult<()> { - context - .require_permission(None, Permission::ROOT) - .await?; + context.require_permission(None, Permission::ROOT).await?; Ok(OAuth2::delete(id.0).await?) } @@ -108,9 +98,7 @@ impl OAuth2Api { request: Json, context: ClientContext, ) -> ApiResult<()> { - context - .require_permission(None, Permission::ROOT) - .await?; + context.require_permission(None, Permission::ROOT).await?; let entity = OAuth2::new(request.0)?; Ok(entity.save().await?) } @@ -132,9 +120,7 @@ impl OAuth2Api { payload: Json, context: ClientContext, ) -> ApiResult<()> { - context - .require_permission(None, Permission::ROOT) - .await?; + context.require_permission(None, Permission::ROOT).await?; Ok(OAuth2::update(id.0, payload.0).await?) } @@ -158,17 +144,10 @@ impl OAuth2Api { context: ClientContext, ) -> ApiResult>> { let mut list = OAuth2::paginate_list(page.0, page_size.0, desc.0).await?; - if context - .has_permission(None, Permission::ROOT) - .await - { + if context.has_permission(None, Permission::ROOT).await { return Ok(Json(list)); } - - context - .require_permission(None, Permission::ACCOUNT_CREATE) - .await?; - + //Non-root users can only view masked data. for item in &mut list.items { item.scrub_sensitive_fields(); } diff --git a/src/modules/rest/api/system.rs b/src/modules/rest/api/system.rs index 60acb1e..517a2d3 100644 --- a/src/modules/rest/api/system.rs +++ b/src/modules/rest/api/system.rs @@ -69,13 +69,8 @@ impl SystemApi { /// Get the full list of SOCKS5 proxy configurations. #[oai(method = "get", path = "/list-proxy", operation_id = "list_proxy")] - async fn list_proxy(&self, context: ClientContext) -> ApiResult>> { - context - .require_any_permission(vec![ - (None, Permission::ACCOUNT_CREATE), - (None, Permission::ROOT), - ]) - .await?; + async fn list_proxy(&self, _context: ClientContext) -> ApiResult>> { + //The proxy list is visible to all users. let proxies = Proxy::list_all() .await .map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?; @@ -90,9 +85,7 @@ impl SystemApi { id: Path, context: ClientContext, ) -> ApiResult<()> { - context - .require_permission(None, Permission::ROOT) - .await?; + context.require_permission(None, Permission::ROOT).await?; Ok(Proxy::delete(id.0).await?) } @@ -104,18 +97,14 @@ impl SystemApi { id: Path, context: ClientContext, ) -> ApiResult> { - context - .require_permission(None, Permission::ROOT) - .await?; + context.require_permission(None, Permission::ROOT).await?; Ok(Json(Proxy::get(id.0).await?)) } /// Create a new proxy configuration. Requires root permission. #[oai(path = "/proxy", method = "post", operation_id = "create_proxy")] async fn create_proxy(&self, url: PlainText, context: ClientContext) -> ApiResult<()> { - context - .require_permission(None, Permission::ROOT) - .await?; + context.require_permission(None, Permission::ROOT).await?; let entity = Proxy::new(url.0); Ok(entity.save().await?) } @@ -128,9 +117,7 @@ impl SystemApi { url: PlainText, context: ClientContext, ) -> ApiResult<()> { - context - .require_permission(None, Permission::ROOT) - .await?; + context.require_permission(None, Permission::ROOT).await?; Ok(Proxy::update(id.0, url.0).await?) } /// Get system configurations. @@ -146,9 +133,7 @@ impl SystemApi { &self, context: ClientContext, ) -> ApiResult> { - context - .require_permission(None, Permission::ROOT) - .await?; + context.require_permission(None, Permission::ROOT).await?; let config: SystemConfigurations = SystemConfigurations::from(&*SETTINGS); Ok(Json(config)) } diff --git a/web/src/components/layout/data/sidebar-data.ts b/web/src/components/layout/data/sidebar-data.ts index 53aa360..28b9d68 100644 --- a/web/src/components/layout/data/sidebar-data.ts +++ b/web/src/components/layout/data/sidebar-data.ts @@ -65,8 +65,7 @@ export function useSidebarData(): SidebarData { { title: t('navigation.oauth2'), url: '/oauth2', - icon: IdCard, - visible: require_any_permission(['system:root', 'account:create']), + icon: IdCard } ] }, diff --git a/web/src/features/oauth2/components/columns.tsx b/web/src/features/oauth2/components/columns.tsx index 9748ad9..efec5f9 100644 --- a/web/src/features/oauth2/components/columns.tsx +++ b/web/src/features/oauth2/components/columns.tsx @@ -33,9 +33,9 @@ export const getColumns = (t: (key: string) => string): ColumnDef[ ), cell: ({ row }) => { - return {row.original.id} + return {row.original.id} }, - meta: { className: 'max-w-[100px]' }, + meta: { className: 'max-w-[140px]' }, enableHiding: false, enableSorting: false, }, @@ -92,9 +92,9 @@ export const getColumns = (t: (key: string) => string): ColumnDef[ ), cell: ({ row }) => ( - {row.original.description} + {row.original.description} ), - meta: { className: 'max-w-[200px]' }, + meta: { className: 'max-w-[180px]' }, enableHiding: true, enableSorting: false }, diff --git a/web/src/features/oauth2/components/data-table-row-actions.tsx b/web/src/features/oauth2/components/data-table-row-actions.tsx index f04ad7b..40a7aae 100644 --- a/web/src/features/oauth2/components/data-table-row-actions.tsx +++ b/web/src/features/oauth2/components/data-table-row-actions.tsx @@ -33,6 +33,7 @@ import { useOAuth2Context } from '../context' import { OAuth2Entity } from '../data/schema' import { WorkflowIcon } from 'lucide-react' import { useTranslation } from 'react-i18next' +import { useCurrentUser } from '@/hooks/use-current-user' interface DataTableRowActionsProps { @@ -42,6 +43,9 @@ interface DataTableRowActionsProps { export function DataTableRowActions({ row }: DataTableRowActionsProps) { const { t } = useTranslation() const { setOpen, setCurrentRow } = useOAuth2Context() + const { require_any_permission } = useCurrentUser() + + return ( <> @@ -56,6 +60,7 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { { setCurrentRow(row.original) setOpen('edit') @@ -80,6 +85,7 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { { setCurrentRow(row.original) setOpen('delete') diff --git a/web/src/features/oauth2/index.tsx b/web/src/features/oauth2/index.tsx index 1e50701..726be75 100644 --- a/web/src/features/oauth2/index.tsx +++ b/web/src/features/oauth2/index.tsx @@ -37,12 +37,13 @@ import { TableSkeleton } from '@/components/table-skeleton' import { AuthorizeDialog } from './components/authorize-dialog' import { FixedHeader } from '@/components/layout/fixed-header' import { useTranslation } from 'react-i18next' +import { useCurrentUser } from '@/hooks/use-current-user' export default function OAuth2() { const { t } = useTranslation() const [currentRow, setCurrentRow] = useState(null) const [open, setOpen] = useDialogState(null) - + const { require_any_permission } = useCurrentUser() const { data: oauth2List, isLoading } = useQuery({ queryKey: ['oauth2-list'], @@ -53,12 +54,9 @@ export default function OAuth2() { return ( - {/* ===== Top Heading ===== */} -
-
- {/* Header */} +

{t('oauth2.title')}

@@ -67,13 +65,12 @@ export default function OAuth2() {

-
- {/* Table / Empty State */}
{isLoading ? ( @@ -91,7 +88,7 @@ export default function OAuth2() {

{t('oauth2.noConfigurationsDesc')}

- +
)} diff --git a/web/src/features/settings/index.tsx b/web/src/features/settings/index.tsx index a1bf9ef..26234eb 100644 --- a/web/src/features/settings/index.tsx +++ b/web/src/features/settings/index.tsx @@ -27,7 +27,7 @@ import { useTranslation } from 'react-i18next' export default function Settings() { const { t } = useTranslation() - const { require_any_permission, canGlobal } = useCurrentUser() + const { canGlobal } = useCurrentUser() const sidebarNavItems = [ @@ -50,7 +50,6 @@ export default function Settings() { title: t('settings.sidebar.proxy'), icon: , href: '/settings/proxy', - visible: require_any_permission(['system:root', 'account:create']), }, { title: t('settings.sidebar.configurations'), diff --git a/web/src/features/settings/proxy/components/data-table-row-actions.tsx b/web/src/features/settings/proxy/components/data-table-row-actions.tsx index ecccf83..bfceee7 100644 --- a/web/src/features/settings/proxy/components/data-table-row-actions.tsx +++ b/web/src/features/settings/proxy/components/data-table-row-actions.tsx @@ -32,6 +32,7 @@ import { import { useProxyContext } from '../context' import { useTranslation } from 'react-i18next' import { Proxy } from '@/api/system/api' +import { useCurrentUser } from '@/hooks/use-current-user' interface DataTableRowActionsProps { @@ -40,6 +41,7 @@ interface DataTableRowActionsProps { export function DataTableRowActions({ row }: DataTableRowActionsProps) { const { setOpen, setCurrentRow } = useProxyContext() + const { require_any_permission } = useCurrentUser() const { t } = useTranslation() return ( <> @@ -55,6 +57,7 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { { setCurrentRow(row.original) setOpen('edit') @@ -67,6 +70,7 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { { setCurrentRow(row.original) setOpen('delete') diff --git a/web/src/features/settings/proxy/index.tsx b/web/src/features/settings/proxy/index.tsx index 46a441b..de2d4c9 100644 --- a/web/src/features/settings/proxy/index.tsx +++ b/web/src/features/settings/proxy/index.tsx @@ -33,13 +33,14 @@ import Logo from '@/assets/logo.svg' import useProxyList from '@/hooks/use-proxy' import { useTranslation } from 'react-i18next' import { Proxy } from '@/api/system/api' +import { useCurrentUser } from '@/hooks/use-current-user' export default function ProxyManagerPage() { const { t } = useTranslation() const [currentRow, setCurrentRow] = useState(null) const [open, setOpen] = useDialogState(null) - + const { require_any_permission } = useCurrentUser() const { proxyList, isLoading } = useProxyList() const columns = getColumns(t) @@ -49,7 +50,7 @@ export default function ProxyManagerPage() {
-