Skip to content

Commit

Permalink
Update wildcard policy handling, settings, nav, and more
Browse files Browse the repository at this point in the history
  • Loading branch information
lucemans committed Dec 18, 2024
1 parent 37079a2 commit 390bd19
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 155 deletions.
9 changes: 6 additions & 3 deletions engine/src/auth/permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl User {
// None
// }

let permissions = Self::enumerate_permissions(db, user, resource_type, &resource_id).await;
let permissions = Self::enumerate_permissions(db, user, resource_type, resource_id).await;

let bv = match actions {
Actions::One(action) => permissions.contains(&action),
Expand Down Expand Up @@ -166,11 +166,12 @@ impl User {
db: &Database,
user: impl Into<Option<i32>>,
resource_type: &str,
resource_id: &Option<&str>,
resource_id: impl Into<Option<&str>>,
) -> Vec<Action> {
let user: Option<i32> = user.into();
let user_id = user.unwrap_or(-1).to_string();
let is_authed = user.is_some().to_string();
let resource_id = resource_id.into();

debug!(
"Enumerating permissions for user: {:?} on resource: {:?} / {:?}",
Expand All @@ -179,6 +180,8 @@ impl User {
resource_id
);

let resource_id = resource_id.as_ref();

let policies = query!(
r#"SELECT action FROM policies WHERE
resource_type = $1 AND
Expand All @@ -187,7 +190,7 @@ impl User {
(subject_type = 'authed' AND subject_id = $4))
"#,
resource_type,
resource_id.unwrap_or(""),
resource_id,
user_id,
is_authed,
)
Expand Down
6 changes: 4 additions & 2 deletions engine/src/routes/policy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ impl PolicyApi {
/// Example: "item" | "product" | "media" | "user"
resource_type: Query<String>,
/// Example: "1234" | "AB123"
resource_id: Query<String>,
resource_id: Query<Option<String>>,
) -> Result<Json<Vec<Action>>> {
let resource_id = resource_id.as_ref().map(|id| id.as_str());

Ok(Json(
User::enumerate_permissions(
&state.database,
user,
&resource_type.0,
&Some(resource_id.0.to_string().as_str()),
resource_id,
)
.await,
))
Expand Down
14 changes: 9 additions & 5 deletions web/src/api/policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ import { queryOptions, useQuery } from '@tanstack/react-query';

import { ApiRequest, apiRequest } from './core';

export const getPolicy = (resourceType: string, resourceId: string) =>
export const getPolicy = (resourceType: string, resourceId?: string) =>
queryOptions({
queryKey: ['policy', resourceType, resourceId],
queryFn: async () => {
const response = await apiRequest('/policy/enumerate', 'get', {
query: {
resource_type: resourceType,
resource_id: resourceId,
},
query: resourceId
? {
resource_type: resourceType,
resource_id: resourceId,
}
: {
resource_type: resourceType,
},
});

return response.data;
Expand Down
2 changes: 1 addition & 1 deletion web/src/api/schema.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1491,7 +1491,7 @@ export type paths = {
/** @description Example: "item" | "product" | "media" | "user" */
resource_type: string;
/** @description Example: "1234" | "AB123" */
resource_id: string;
resource_id?: string;
};
header?: never;
path?: never;
Expand Down
7 changes: 4 additions & 3 deletions web/src/components/LeafletPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ export const LeafletPreview: FC<{ latitude: number; longitude: number }> = ({
// style={{ height: 80, width: 80 }}
>
<TileLayer
// attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
// url="https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"
url="https://tiles.stadiamaps.com/tiles/stamen_terrain_background/{z}/{x}/{y}{r}.png"
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"
// url="https://{s}.tile.thunderforest.com/pioneer/{z}/{x}/{y}.png"
// url="https://tiles.stadiamaps.com/tiles/stamen_terrain_background/{z}/{x}/{y}{r}.png"
/>
</MapContainer>
);
Expand Down
134 changes: 68 additions & 66 deletions web/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,82 +19,84 @@ import {
import { useAuth } from '@/api/auth';
import { BASE_URL } from '@/api/core';
import { useMe } from '@/api/me';
import { useHasPolicy } from '@/api/policy';
import * as DropdownMenu from '@/components/ui/Dropdown';

import { Button } from './ui/Button';
import { AvatarHolder, getInitials } from './UserProfile';

const LOGIN_URL = BASE_URL + 'login';

const navLinks = [
{
path: '/items',
name: 'Items',
icon: <FiBox />,
slug: 'items-navlink',
},
{
path: '/products',
name: 'Products',
icon: <FiTag />,
slug: 'products-navlink',
},
{
path: '/search',
name: 'Search',
icon: <FiSearch />,
slug: 'search-navlink',
},
{
path: '/create',
name: 'Create',
icon: <FiPlusCircle />,
slug: 'create-navlink',
},
] as const;

const navLinks2 = [
{
path: '/tags/',
name: 'Tags',
icon: <FiTag />,
slug: 'tags-navlink',
},
{
path: '/settings/fields',
name: 'Fields',
icon: <FiTag />,
slug: 'fields-navlink',
},
{
path: '/media/',
name: 'Media',
icon: <FiImage />,
slug: 'media-navlink',
},
{
path: '/logs/',
name: 'Logs',
icon: <FiLogOut />,
slug: 'logs-navlink',
},
{
path: '/users/',
name: 'Users',
icon: <FiUsers />,
slug: 'users-navlink',
},
{
path: '/settings',
name: 'Settings',
icon: <FiSettings />,
slug: 'settings-navlink',
},
] as const;

export const Navbar = () => {
const { token, clearAuthToken } = useAuth();
const { data: meData } = useMe();
const { ok: hasUsersPermissions } = useHasPolicy('user', '', 'write');

const navLinks = [
{
path: '/items',
name: 'Items',
icon: <FiBox />,
slug: 'items-navlink',
},
{
path: '/products',
name: 'Products',
icon: <FiTag />,
slug: 'products-navlink',
},
{
path: '/search',
name: 'Search',
icon: <FiSearch />,
slug: 'search-navlink',
},
{
path: '/create',
name: 'Create',
icon: <FiPlusCircle />,
slug: 'create-navlink',
},
] as const;

const navLinks2 = [
{
path: '/settings/tags',
name: 'Tags',
icon: <FiTag />,
slug: 'tags-navlink',
},
{
path: '/settings/fields',
name: 'Fields',
icon: <FiTag />,
slug: 'fields-navlink',
},
{
path: '/media/',
name: 'Media',
icon: <FiImage />,
slug: 'media-navlink',
},
{
path: '/settings/logs',
name: 'Logs',
icon: <FiLogOut />,
slug: 'logs-navlink',
},
hasUsersPermissions && {
path: '/settings/users',
name: 'Users',
icon: <FiUsers />,
slug: 'users-navlink',
},
{
path: '/settings',
name: 'Settings',
icon: <FiSettings />,
slug: 'settings-navlink',
},
].filter(Boolean);

const login_here_url =
LOGIN_URL + '?redirect=' + encodeURIComponent(window.location.href);
Expand Down
17 changes: 7 additions & 10 deletions web/src/components/logs/AllLogsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@ export const AllLogsSection = () => {
const { data: logs } = useAllLogs();

return (
<div>
<h2 className="h2">Logs</h2>
<div className="card">
<ul className="divide-y divide-neutral-200 space-y-2">
{logs?.map((log) => (
<ItemLogEntry key={log.log_id} log={log} />
))}
</ul>
</div>
</div>
<ul className="space-y-2">
{logs?.map((log) => (
<div className="card">
<ItemLogEntry key={log.log_id} log={log} />
</div>
))}
</ul>
);
};
20 changes: 18 additions & 2 deletions web/src/components/settings/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { Link } from '@tanstack/react-router';
import clsx from 'clsx';
import {
LuBrain,
LuClipboardType,
LuClock,
LuHardDrive,
LuKey,
LuScroll,
LuSearch,
LuSettings,
LuTag,
} from 'react-icons/lu';

export const SettingsNav = () => {
Expand All @@ -17,7 +19,18 @@ export const SettingsNav = () => {
[
['', [['/settings', 'General', <LuSettings />]]],
[
'Instance Settings',
'Organizational',
[
['/settings/tags', 'Tags', <LuTag />],
[
'/settings/fields',
'Field Definitions',
<LuClipboardType />,
],
],
],
[
'Instance',
[
['/settings/search', 'Search', <LuSearch />],
[
Expand All @@ -41,7 +54,10 @@ export const SettingsNav = () => {
],
[
'System',
[['/settings/build', 'Software Info', <LuScroll />]],
[
['/settings/logs', 'Access Logs', <LuScroll />],
['/settings/build', 'Software Info', <LuScroll />],
],
],
] as const
).map(([group, items]) => (
Expand Down
Loading

0 comments on commit 390bd19

Please sign in to comment.