Skip to content

Commit

Permalink
PR touchups
Browse files Browse the repository at this point in the history
  • Loading branch information
pjdotson committed Sep 24, 2024
1 parent 7d128f7 commit e0dafae
Show file tree
Hide file tree
Showing 17 changed files with 86 additions and 57 deletions.
4 changes: 2 additions & 2 deletions client/ts/src/user/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ export class Client {
return res[0];
}

async changeName(key: Key, firstName?: string, lastName?: string): Promise<void> {
await this.writer.changeName(key, firstName, lastName);
async rename(key: Key, firstName?: string, lastName?: string): Promise<void> {
await this.writer.rename(key, firstName, lastName);
}

async delete(key: Key): Promise<void>;
Expand Down
4 changes: 2 additions & 2 deletions client/ts/src/user/payload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export type Key = z.infer<typeof keyZ>;
export const userZ = z.object({
key: keyZ,
username: z.string().min(1),
firstName: z.string().optional(),
lastName: z.string().optional(),
firstName: z.string(),
lastName: z.string(),
rootUser: z.boolean(),
});
export type User = z.infer<typeof userZ>;
Expand Down
6 changes: 2 additions & 4 deletions client/ts/src/user/user.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ describe("User", () => {
describe("Change Name", () => {
test("Successful", async () => {
await expect(
client.user.changeName(userOne.key as string, "Thomas", "Jefferson"),
client.user.rename(userOne.key as string, "Thomas", "Jefferson"),
).resolves.toBeUndefined();
const res = await client.user.retrieve(userOne.key as string);
expect(res.username).toEqual(userOne.username);
Expand All @@ -259,7 +259,7 @@ describe("User", () => {
});
test("Only one name", async () => {
await expect(
client.user.changeName(userOne.key as string, "James"),
client.user.rename(userOne.key as string, "James"),
).resolves.toBeUndefined();
const res = await client.user.retrieve(userOne.key as string);
expect(res.username).toEqual(userOne.username);
Expand All @@ -284,8 +284,6 @@ describe("User", () => {
client.user.retrieve(userArray.map((u) => u.key as string)),
).rejects.toThrow(NotFoundError);
});
// Skipping this test because errors currently get thrown on this function - not
// idempotent on server-side
test("one that doesn't exist", async () => {
await expect(client.user.delete(userOne.key as string)).resolves.toBeUndefined();
});
Expand Down
16 changes: 8 additions & 8 deletions client/ts/src/user/writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ const createResZ = z.object({ users: userZ.array() });
const changeUsernameReqZ = z.object({ key: keyZ, username: z.string().min(1) });
const changeUsernameResZ = z.object({});

const changeNameReqZ = z.object({
const renameReqZ = z.object({
key: keyZ,
firstName: z.string().optional(),
lastName: z.string().optional(),
});
const changeNameResZ = z.object({});
const renameResZ = z.object({});

const deleteReqZ = z.object({ keys: keyZ.array() });
const deleteResZ = z.object({});

const CREATE_ENDPOINT = "/user/create";
const CHANGE_USERNAME_ENDPOINT = "/user/change-username";
const CHANGE_NAME_ENDPOINT = "/user/rename";
const RENAME_ENDPOINT = "/user/rename";
const DELETE_ENDPOINT = "/user/delete";

export class Writer {
Expand Down Expand Up @@ -69,13 +69,13 @@ export class Writer {
);
}

async changeName(key: Key, firstName?: string, lastName?: string): Promise<void> {
await sendRequired<typeof changeNameReqZ, typeof changeNameResZ>(
async rename(key: Key, firstName?: string, lastName?: string): Promise<void> {
await sendRequired<typeof renameReqZ, typeof renameResZ>(
this.client,
CHANGE_NAME_ENDPOINT,
RENAME_ENDPOINT,
{ key, firstName, lastName },
changeNameReqZ,
changeNameResZ,
renameReqZ,
renameResZ,
);
}

Expand Down
2 changes: 1 addition & 1 deletion console/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"width": 1080,
"minWidth": 625,
"minHeight": 375,
"visible": true,
"visible": false,
"acceptFirstMouse": true,
"titleBarStyle": "Overlay",
"hiddenTitle": true,
Expand Down
2 changes: 1 addition & 1 deletion console/src/hardware/ni/device/Configure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { type ReactElement, useRef, useState } from "react";
import { CSS } from "@/css";
import {
configurablePropertiesZ,
Properties,
type Properties,
ZERO_PROPERTIES,
} from "@/hardware/ni/device/types";
import { type Layout } from "@/layout";
Expand Down
2 changes: 1 addition & 1 deletion console/src/palette/Palette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import { type Ontology } from "@/ontology";
import { type Service } from "@/ontology/service";
import { TooltipContent } from "@/palette/Tooltip";
import { type Mode, type TriggerConfig } from "@/palette/types";
import { Permissions } from "@/permissions";
import { type Permissions } from "@/permissions";
import { type RootState, type RootStore } from "@/store";

export interface PaletteProps {
Expand Down
1 change: 1 addition & 0 deletions console/src/permissions/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as v0 from "@/permissions/migrations/v0";

export type SliceState = v0.State;
export type AnySliceState = v0.State;
export const ALLOW_ALL = v0.ALLOW_ALL;

export const ZERO_SLICE_STATE = v0.ZERO_STATE;

Expand Down
5 changes: 3 additions & 2 deletions console/src/permissions/migrations/v0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
import { policy } from "@synnaxlabs/client";
import { z } from "zod";

export const ALLOW_ALL = "ALLOW_ALL";

export const stateZ = z.object({
version: z.literal("0.0.0"),
policies: policy.policyZ.array().or(z.literal("ALLOW_ALL")),
policies: policy.policyZ.array().or(z.literal(ALLOW_ALL)),
});

export type State = z.infer<typeof stateZ>;

export const ZERO_STATE: State = {
Expand Down
11 changes: 8 additions & 3 deletions console/src/permissions/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,26 @@
import { access, type ontology, policy } from "@synnaxlabs/client";

import { useMemoSelect } from "@/hooks";
import { SLICE_NAME, type SliceState, type StoreState } from "@/permissions/slice";
import {
ALLOW_ALL,
SLICE_NAME,
type SliceState,
type StoreState,
} from "@/permissions/slice";

const selectState = (state: StoreState): SliceState => state[SLICE_NAME];

export const selectPolicies = (state: StoreState): policy.Policy[] => {
const policies = selectState(state).policies;
if (policies === "ALLOW_ALL") return [];
if (policies === ALLOW_ALL) return [];
return policies;
};

export const useSelectPolicies = (): policy.Policy[] =>
useMemoSelect(selectPolicies, []);

export const selectHasAllPermissions = (state: StoreState): boolean =>
selectState(state).policies === "ALLOW_ALL";
selectState(state).policies === ALLOW_ALL;

export const useSelectHasAllPermissions = (): boolean =>
useMemoSelect(selectHasAllPermissions, []);
Expand Down
3 changes: 2 additions & 1 deletion console/src/permissions/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const ZERO_SLICE_STATE = latest.ZERO_SLICE_STATE;
export const migrateSlice = latest.migrateSlice;

export const SLICE_NAME = "permissions";
export const ALLOW_ALL = latest.ALLOW_ALL;

export type StoreState = {
[SLICE_NAME]: SliceState;
Expand All @@ -34,7 +35,7 @@ export const { actions, reducer } = createSlice({
state.policies = [];
},
giveAllPermissions: (state) => {
state.policies = "ALLOW_ALL";
state.policies = ALLOW_ALL;
},
set: (state, { payload: { policies } }: PayloadAction<SetPayload>) => {
state.policies = policies;
Expand Down
22 changes: 9 additions & 13 deletions console/src/user/services/ontology.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// License, use of this software will be governed by the Apache License, Version 2.0,
// included in the file licenses/APL.txt.

import { type user as cuser } from "@synnaxlabs/client";
import { user } from "@synnaxlabs/client";
import { Icon } from "@synnaxlabs/media";
import { Menu as PMenu, Tree } from "@synnaxlabs/pluto";
import { type ReactElement } from "react";
Expand All @@ -17,12 +17,12 @@ import { Ontology } from "@/ontology";
import { Permissions } from "@/permissions";
import { useSelectHasPermission } from "@/user/selectors";

const useSetPermissions = (): ((props: Ontology.TreeContextMenuProps) => void) => {
return (props) =>
props.placeLayout(
Permissions.setLayout({ user: props.selection.resources[0].data as cuser.User }),
const useSetPermissions =
(): ((props: Ontology.TreeContextMenuProps) => void) =>
({ placeLayout, selection }) =>
placeLayout(
Permissions.setLayout({ user: selection.resources[0].data as user.User }),
);
};

const TreeContextMenu: Ontology.TreeContextMenu = (props): ReactElement => {
const {
Expand Down Expand Up @@ -62,12 +62,8 @@ const TreeContextMenu: Ontology.TreeContextMenu = (props): ReactElement => {
};

const handleRename: Ontology.HandleTreeRename = {
eager: async () => console.log("eager"),
execute: async ({ client, id, name }) => {
console.log("execute");
await client.user.changeUsername(id.key, name);
},
rollback: async () => console.log("rollback"),
execute: async ({ client, id, name }) =>
await client.user.changeUsername(id.key, name),
};

const allowRename: Ontology.AllowRename = (props): boolean => {
Expand All @@ -77,7 +73,7 @@ const allowRename: Ontology.AllowRename = (props): boolean => {
};

export const ONTOLOGY_SERVICE: Ontology.Service = {
type: "user",
type: user.ONTOLOGY_TYPE,
icon: <Icon.User />,
hasChildren: true,
allowRename,
Expand Down
46 changes: 38 additions & 8 deletions synnax/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func start(cmd *cobra.Command) {
return err
}

// Set the base policies.
// Set the base permissions for all users.
if err = maybeSetBasePermission(ctx, gorpDB, rbacSvc); err != nil {
return err
}
Expand Down Expand Up @@ -468,27 +468,32 @@ func maybeSetBasePermission(
oldBasePolicies := map[ontology.Type]action.Action{}

existingPolicies := make([]rbac.Policy, 0, len(basePolicies))
var policiesToDelete []uuid.UUID
if err := rbacSvc.NewRetriever().WhereSubjects(user.OntologyTypeID).Entries(&existingPolicies).Exec(ctx, tx); err != nil {
policiesToDelete := make([]uuid.UUID, 0, len(oldBasePolicies))
if err := rbacSvc.NewRetriever().WhereSubjects(user.OntologyTypeID).
Entries(&existingPolicies).Exec(ctx, tx); err != nil {
return err
}
for _, p := range existingPolicies {
if len(p.Subjects) != 1 || len(p.Objects) != 1 || len(p.Actions) != 1 {
continue
}
s := p.Subjects[0]
o := p.Objects[0]
a := p.Actions[0]
if (s != user.OntologyTypeID) || (o.Key != "") {
continue
}
if basePolicies[o.Type] == a {
delete(basePolicies, o.Type)
} else if oldBasePolicies[o.Type] == a {
policiesToDelete = append(policiesToDelete, p.Key)
}
}
for o := range basePolicies {
for t := range basePolicies {
if err := rbacSvc.NewWriter(tx).Create(ctx, &rbac.Policy{
Subjects: []ontology.ID{user.OntologyTypeID},
Objects: []ontology.ID{{Type: o, Key: ""}},
Actions: []action.Action{basePolicies[o]},
Objects: []ontology.ID{{Type: t, Key: ""}},
Actions: []action.Action{basePolicies[t]},
}); err != nil {
return err
}
Expand All @@ -509,11 +514,35 @@ func maybeProvisionRootUser(
Password: password.Raw(viper.GetString(passwordFlag)),
}
exists, err := userSvc.UsernameExists(ctx, creds.Username)
if err != nil || exists {
if err != nil {
return err
}
if exists {
// we want to make sure the root user still has the allow_all policy
return db.WithTx(ctx, func(tx gorp.Tx) error {
var u user.User
if err = userSvc.NewRetrieve().WhereUsername(creds.Username).Entry(&u).Exec(ctx, db); err != nil {
return err
}
if !u.RootUser {
return nil
}
policies := make([]rbac.Policy, 0, 1)
rbacSvc.NewRetriever().WhereSubjects(user.OntologyID(u.Key)).Entries(&policies).Exec(ctx, tx)
for _, p := range policies {
if lo.Contains(p.Objects, rbac.AllowAllOntologyID) {
return nil
}
}
return rbacSvc.NewWriter(tx).Create(ctx, &rbac.Policy{
Subjects: []ontology.ID{user.OntologyID(u.Key)},
Objects: []ontology.ID{rbac.AllowAllOntologyID},
Actions: []action.Action{},
})
})
}

// Register the user first.
// Register the user first, then give them all permissions
return db.WithTx(ctx, func(tx gorp.Tx) error {
if err = authSvc.NewWriter(tx).Register(ctx, creds); err != nil {
return err
Expand All @@ -527,6 +556,7 @@ func maybeProvisionRootUser(
&rbac.Policy{
Subjects: []ontology.ID{user.OntologyID(userObj.Key)},
Objects: []ontology.ID{rbac.AllowAllOntologyID},
Actions: []action.Action{},
},
)
})
Expand Down
2 changes: 1 addition & 1 deletion synnax/pkg/access/rbac/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func allowRequest(req access.Request, policies []Policy) bool {
}

for _, o := range policy.Objects {
if o.Type == AllowAllOntologyID.Type {
if o.Type == AllowAllOntologyType {
// If the subject has an AllowAll policy, allow all requests.
return true
}
Expand Down
7 changes: 3 additions & 4 deletions synnax/pkg/api/ranger.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@ import (
"context"
"go/types"

"github.com/google/uuid"
"github.com/synnaxlabs/synnax/pkg/access"
"github.com/synnaxlabs/synnax/pkg/access/action"
"github.com/synnaxlabs/synnax/pkg/distribution/channel"
"github.com/synnaxlabs/synnax/pkg/distribution/ontology"
"github.com/synnaxlabs/synnax/pkg/ranger"
"github.com/synnaxlabs/x/errors"
"github.com/synnaxlabs/x/gorp"
"github.com/synnaxlabs/x/query"
"github.com/synnaxlabs/x/telem"

"github.com/google/uuid"
"github.com/synnaxlabs/synnax/pkg/ranger"
"github.com/synnaxlabs/x/gorp"
)

type (
Expand Down
5 changes: 2 additions & 3 deletions synnax/pkg/workspace/lineplot/lineplot_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"context"
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/synnaxlabs/synnax/pkg/distribution/ontology"
"github.com/synnaxlabs/synnax/pkg/distribution/ontology/group"
"github.com/synnaxlabs/synnax/pkg/user"
Expand All @@ -21,9 +23,6 @@ import (
"github.com/synnaxlabs/x/config"
"github.com/synnaxlabs/x/gorp"
"github.com/synnaxlabs/x/kv/memkv"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/synnaxlabs/x/testutil"
)

Expand Down
5 changes: 2 additions & 3 deletions synnax/pkg/workspace/workspace_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"context"
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/synnaxlabs/synnax/pkg/distribution/ontology"
"github.com/synnaxlabs/synnax/pkg/distribution/ontology/group"
"github.com/synnaxlabs/synnax/pkg/user"
Expand All @@ -21,9 +23,6 @@ import (
"github.com/synnaxlabs/x/gorp"
"github.com/synnaxlabs/x/kv/memkv"
. "github.com/synnaxlabs/x/testutil"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestWorkspace(t *testing.T) {
Expand Down

0 comments on commit e0dafae

Please sign in to comment.