diff --git a/api/v2/acl_config.go b/api/v2/acl_config.go index 7b7f80f..2db9e5e 100644 --- a/api/v2/acl_config.go +++ b/api/v2/acl_config.go @@ -2,7 +2,9 @@ package v2 import "strings" -var allowedMethodsWhenUnauthorized = map[string]bool{} +var allowedMethodsWhenUnauthorized = map[string]bool{ + "/slash.api.v2.WorkspaceSettingService/GetWorkspaceSetting": true, +} // isUnauthorizeAllowedMethod returns true if the method is allowed to be called when the user is not authorized. func isUnauthorizeAllowedMethod(methodName string) bool { diff --git a/api/v2/workspace_setting_service.go b/api/v2/workspace_setting_service.go index fd0cc86..f4d277c 100644 --- a/api/v2/workspace_setting_service.go +++ b/api/v2/workspace_setting_service.go @@ -24,6 +24,17 @@ func NewWorkspaceSettingService(store *store.Store) *WorkspaceSettingService { } func (s *WorkspaceSettingService) GetWorkspaceSetting(ctx context.Context, _ *apiv2pb.GetWorkspaceSettingRequest) (*apiv2pb.GetWorkspaceSettingResponse, error) { + isAdmin := false + userID, ok := ctx.Value(userIDContextKey).(int32) + if ok { + user, err := s.Store.GetUser(ctx, &store.FindUser{ID: &userID}) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if user.Role == store.RoleAdmin { + isAdmin = true + } + } workspaceSettings, err := s.Store.ListWorkspaceSettings(ctx, &store.FindWorkspaceSetting{}) if err != nil { return nil, status.Errorf(codes.Internal, "failed to list workspace settings: %v", err) @@ -32,14 +43,15 @@ func (s *WorkspaceSettingService) GetWorkspaceSetting(ctx context.Context, _ *ap for _, v := range workspaceSettings { if v.Key == storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP { workspaceSetting.EnableSignup = v.GetEnableSignup() - } else if v.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH { - workspaceSetting.ResourceRelativePath = v.GetResourceRelativePath() } else if v.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE { workspaceSetting.CustomStyle = v.GetCustomStyle() } else if v.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_SCRIPT { workspaceSetting.CustomScript = v.GetCustomScript() - } else { - return nil, status.Errorf(codes.Internal, "invalid workspace setting key: %s", v.Key.String()) + } else if isAdmin { + // For some settings, only admin can get the value. + if v.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH { + workspaceSetting.ResourceRelativePath = v.GetResourceRelativePath() + } } } return &apiv2pb.GetWorkspaceSettingResponse{ diff --git a/frontend/web/src/App.tsx b/frontend/web/src/App.tsx index 75d7ea2..3de4072 100644 --- a/frontend/web/src/App.tsx +++ b/frontend/web/src/App.tsx @@ -1,11 +1,14 @@ import { useEffect, useState } from "react"; import { Outlet } from "react-router-dom"; import DemoBanner from "./components/DemoBanner"; +import { workspaceSettingServiceClient } from "./grpcweb"; import { globalService } from "./services"; import useUserStore from "./stores/v1/user"; +import { WorkspaceSetting } from "./types/proto/api/v2/workspace_setting_service"; function App() { const userStore = useUserStore(); + const [workspaceSetting, setWorkspaceSetting] = useState(WorkspaceSetting.fromPartial({})); const [loading, setLoading] = useState(true); useEffect(() => { @@ -16,6 +19,15 @@ function App() { // do nothing } + try { + const { setting } = await workspaceSettingServiceClient.getWorkspaceSetting({}); + if (setting) { + setWorkspaceSetting(setting); + } + } catch (error) { + // do nothing + } + try { await userStore.fetchCurrentUser(); } catch (error) { @@ -28,6 +40,13 @@ function App() { initialState(); }, []); + useEffect(() => { + const styleEl = document.createElement("style"); + styleEl.innerHTML = workspaceSetting.customStyle; + styleEl.setAttribute("type", "text/css"); + document.body.insertAdjacentElement("beforeend", styleEl); + }, [workspaceSetting.customStyle]); + return !loading ? ( <>