diff --git a/api/v1/auth.go b/api/v1/auth.go index c9985e1..15afba6 100644 --- a/api/v1/auth.go +++ b/api/v1/auth.go @@ -66,13 +66,13 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) { g.POST("/auth/signup", func(c echo.Context) error { ctx := c.Request().Context() - disallowSignUpSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ - Key: store.WorkspaceDisallowSignUp, + enableSignUpSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ + Key: storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP, }) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to get workspace setting, err: %s", err)).SetInternal(err) } - if disallowSignUpSetting != nil && disallowSignUpSetting.Value == "true" { + if enableSignUpSetting != nil && !enableSignUpSetting.GetEnableSignup() { return echo.NewHTTPError(http.StatusForbidden, "sign up has been disabled") } diff --git a/api/v1/workspace.go b/api/v1/workspace.go index b18cc59..ea253ce 100644 --- a/api/v1/workspace.go +++ b/api/v1/workspace.go @@ -1,10 +1,10 @@ package v1 import ( - "encoding/json" "fmt" "net/http" + storepb "github.com/boojack/slash/proto/gen/store" "github.com/boojack/slash/server/profile" "github.com/boojack/slash/store" "github.com/labstack/echo/v4" @@ -15,25 +15,6 @@ type WorkspaceSetting struct { Value string `json:"value"` } -type WorkspaceSettingUpsert struct { - Key string `json:"key"` - Value string `json:"value"` -} - -func (upsert WorkspaceSettingUpsert) Validate() error { - if upsert.Key == store.WorkspaceDisallowSignUp.String() { - value := false - err := json.Unmarshal([]byte(upsert.Value), &value) - if err != nil { - return fmt.Errorf("failed to unmarshal workspace setting disallow signup value") - } - } else { - return fmt.Errorf("invalid workspace setting key") - } - - return nil -} - type WorkspaceProfile struct { Profile *profile.Profile `json:"profile"` DisallowSignUp bool `json:"disallowSignUp"` @@ -47,87 +28,16 @@ func (s *APIV1Service) registerWorkspaceRoutes(g *echo.Group) { DisallowSignUp: false, } - disallowSignUpSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ - Key: store.WorkspaceDisallowSignUp, + enableSignUpSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ + Key: storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP, }) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to find workspace setting, err: %s", err)).SetInternal(err) } - if disallowSignUpSetting != nil { - workspaceProfile.DisallowSignUp = disallowSignUpSetting.Value == "true" + if enableSignUpSetting != nil { + workspaceProfile.DisallowSignUp = !enableSignUpSetting.GetEnableSignup() } return c.JSON(http.StatusOK, workspaceProfile) }) - - g.POST("/workspace/setting", func(c echo.Context) error { - ctx := c.Request().Context() - userID, ok := c.Get(UserIDContextKey).(int32) - if !ok { - return echo.NewHTTPError(http.StatusUnauthorized, "missing user in session") - } - - user, err := s.Store.GetUser(ctx, &store.FindUser{ - ID: &userID, - }) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to find user, err: %s", err)).SetInternal(err) - } - if user == nil || user.Role != store.RoleAdmin { - return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized") - } - - upsert := &WorkspaceSettingUpsert{} - if err := json.NewDecoder(c.Request().Body).Decode(upsert); err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("failed to decode request body, err: %s", err)).SetInternal(err) - } - if err := upsert.Validate(); err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("invalid request body, err: %s", err)).SetInternal(err) - } - - workspaceSetting, err := s.Store.UpsertWorkspaceSetting(ctx, &store.WorkspaceSetting{ - Key: store.WorkspaceSettingKey(upsert.Key), - Value: upsert.Value, - }) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to upsert workspace setting, err: %s", err)).SetInternal(err) - } - return c.JSON(http.StatusOK, convertWorkspaceSettingFromStore(workspaceSetting)) - }) - - g.GET("/workspace/setting", func(c echo.Context) error { - ctx := c.Request().Context() - userID, ok := c.Get(UserIDContextKey).(int32) - if !ok { - return echo.NewHTTPError(http.StatusUnauthorized, "missing user in session") - } - - user, err := s.Store.GetUser(ctx, &store.FindUser{ - ID: &userID, - }) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to find user, err: %s", err)).SetInternal(err) - } - if user == nil || user.Role != store.RoleAdmin { - return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized") - } - - list, err := s.Store.ListWorkspaceSettings(ctx, &store.FindWorkspaceSetting{}) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to list workspace settings, err: %s", err)).SetInternal(err) - } - - workspaceSettingList := []*WorkspaceSetting{} - for _, workspaceSetting := range list { - workspaceSettingList = append(workspaceSettingList, convertWorkspaceSettingFromStore(workspaceSetting)) - } - return c.JSON(http.StatusOK, workspaceSettingList) - }) -} - -func convertWorkspaceSettingFromStore(workspaceSetting *store.WorkspaceSetting) *WorkspaceSetting { - return &WorkspaceSetting{ - Key: workspaceSetting.Key.String(), - Value: workspaceSetting.Value, - } } diff --git a/api/v2/acl_config.go b/api/v2/acl_config.go index 18d70eb..7b7f80f 100644 --- a/api/v2/acl_config.go +++ b/api/v2/acl_config.go @@ -13,8 +13,9 @@ func isUnauthorizeAllowedMethod(methodName string) bool { } var allowedMethodsOnlyForAdmin = map[string]bool{ - "/slash.api.v2.UserService/CreateUser": true, - "/slash.api.v2.UserService/DeleteUser": true, + "/slash.api.v2.UserService/CreateUser": true, + "/slash.api.v2.UserService/DeleteUser": true, + "/slash.api.v2.WorkspaceSettingService/UpdateWorkspaceSetting": true, } // isOnlyForAdminAllowedMethod returns true if the method is allowed to be called only by admin. diff --git a/api/v2/workspace_setting_service.go b/api/v2/workspace_setting_service.go index 5aa1ed5..d7ad2fa 100644 --- a/api/v2/workspace_setting_service.go +++ b/api/v2/workspace_setting_service.go @@ -24,7 +24,7 @@ func NewWorkspaceSettingService(store *store.Store) *WorkspaceSettingService { } func (s *WorkspaceSettingService) GetWorkspaceSetting(ctx context.Context, _ *apiv2pb.GetWorkspaceSettingRequest) (*apiv2pb.GetWorkspaceSettingResponse, error) { - workspaceSettings, err := s.Store.ListWorkspaceSettingsV1(ctx, &store.FindWorkspaceSettingV1{}) + workspaceSettings, err := s.Store.ListWorkspaceSettings(ctx, &store.FindWorkspaceSetting{}) if err != nil { return nil, status.Errorf(codes.Internal, "failed to list workspace settings: %v", err) } @@ -50,7 +50,7 @@ func (s *WorkspaceSettingService) UpdateWorkspaceSetting(ctx context.Context, re for _, path := range request.UpdateMask { if path == "enable_signup" { - if _, err := s.Store.UpsertWorkspaceSettingV1(ctx, &storepb.WorkspaceSetting{ + if _, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{ Key: storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP, Value: &storepb.WorkspaceSetting_EnableSignup{ EnableSignup: request.Setting.EnableSignup, @@ -59,7 +59,7 @@ func (s *WorkspaceSettingService) UpdateWorkspaceSetting(ctx context.Context, re return nil, status.Errorf(codes.Internal, "failed to update workspace setting: %v", err) } } else if path == "resource_relative_path" { - if _, err := s.Store.UpsertWorkspaceSettingV1(ctx, &storepb.WorkspaceSetting{ + if _, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{ Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH, Value: &storepb.WorkspaceSetting_ResourceRelativePath{ ResourceRelativePath: request.Setting.ResourceRelativePath, diff --git a/frontend/web/src/components/setting/WorkspaceSection.tsx b/frontend/web/src/components/setting/WorkspaceSection.tsx index ac5abd8..f9e86ae 100644 --- a/frontend/web/src/components/setting/WorkspaceSection.tsx +++ b/frontend/web/src/components/setting/WorkspaceSection.tsx @@ -1,31 +1,40 @@ import { Checkbox } from "@mui/joy"; import { useEffect, useState } from "react"; -import { getWorkspaceProfile, upsertWorkspaceSetting } from "../../helpers/api"; +import { WorkspaceSetting } from "@/types/proto/api/v2/workspace_setting_service_pb"; +import { getWorkspaceSetting, updateWorkspaceSetting } from "../../helpers/api"; const WorkspaceSection: React.FC = () => { - const [disallowSignUp, setDisallowSignUp] = useState(false); + const [workspaceSetting, setWorkspaceSetting] = useState(); useEffect(() => { - getWorkspaceProfile().then(({ data }) => { - setDisallowSignUp(data.disallowSignUp); + getWorkspaceSetting().then(({ data }) => { + setWorkspaceSetting(data.setting); }); }, []); const handleDisallowSignUpChange = async (value: boolean) => { - await upsertWorkspaceSetting("disallow-signup", JSON.stringify(value)); - setDisallowSignUp(value); + const { data } = await updateWorkspaceSetting( + { + ...workspaceSetting, + enableSignup: value, + } as WorkspaceSetting, + ["enable_signup"] + ); + setWorkspaceSetting(data.setting); }; + if (!workspaceSetting) return <>; + return (

Workspace settings

handleDisallowSignUpChange(event.target.checked)} /> -

Once disabled, other users cannot signup.

+

Once enabled, other users can signup.

); diff --git a/frontend/web/src/helpers/api.ts b/frontend/web/src/helpers/api.ts index a25b4d7..97da358 100644 --- a/frontend/web/src/helpers/api.ts +++ b/frontend/web/src/helpers/api.ts @@ -1,4 +1,9 @@ import axios from "axios"; +import { + GetWorkspaceSettingResponse, + UpdateWorkspaceSettingResponse, + WorkspaceSetting, +} from "@/types/proto/api/v2/workspace_setting_service_pb"; export function getWorkspaceProfile() { return axios.get("/api/v1/workspace/profile"); @@ -75,10 +80,14 @@ export function deleteShortcutById(shortcutId: ShortcutId) { return axios.delete(`/api/v1/shortcut/${shortcutId}`); } -export function upsertWorkspaceSetting(key: string, value: string) { - return axios.post(`/api/v1/workspace/setting`, { - key, - value, +export function getWorkspaceSetting() { + return axios.get(`/api/v2/workspace/settings`); +} + +export function updateWorkspaceSetting(setting: WorkspaceSetting, updateMask: string[]) { + return axios.post(`/api/v2/workspace/settings`, { + setting, + updateMask, }); } diff --git a/server/resource.go b/server/resource.go index 8854ee6..87d3fd2 100644 --- a/server/resource.go +++ b/server/resource.go @@ -6,6 +6,7 @@ import ( "net/http" "os" + storepb "github.com/boojack/slash/proto/gen/store" "github.com/boojack/slash/server/profile" "github.com/boojack/slash/store" "github.com/h2non/filetype" @@ -30,16 +31,16 @@ func (s *ResourceService) Register(g *echo.Group) { ctx := c.Request().Context() resourceID := c.Param("resourceId") resourceRelativePathSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ - Key: store.WorkspaceResourceRelativePath, + Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH, }) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, "failed to workspace resource relative path setting").SetInternal(err) } - if resourceRelativePathSetting == nil || resourceRelativePathSetting.Value == "" { + if resourceRelativePathSetting == nil { return echo.NewHTTPError(http.StatusBadRequest, "found no workspace resource relative path setting") } - resourceRelativePath := resourceRelativePathSetting.Value + resourceRelativePath := resourceRelativePathSetting.GetResourceRelativePath() resourcePath := fmt.Sprintf("%s/%s", resourceRelativePath, resourceID) buf, err := os.ReadFile(resourcePath) if err != nil { diff --git a/server/server.go b/server/server.go index add682b..44ce2eb 100644 --- a/server/server.go +++ b/server/server.go @@ -8,6 +8,7 @@ import ( apiv1 "github.com/boojack/slash/api/v1" apiv2 "github.com/boojack/slash/api/v2" + storepb "github.com/boojack/slash/proto/gen/store" "github.com/boojack/slash/server/profile" "github.com/boojack/slash/store" "github.com/google/uuid" @@ -120,21 +121,23 @@ func (s *Server) GetEcho() *echo.Echo { } func (s *Server) getSystemSecretSessionName(ctx context.Context) (string, error) { - secretSessionNameValue, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ - Key: store.WorkspaceDisallowSignUp, + secretSessionSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ + Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION, }) if err != nil { return "", err } - if secretSessionNameValue == nil || secretSessionNameValue.Value == "" { + if secretSessionSetting == nil { tempSecret := uuid.New().String() - secretSessionNameValue, err = s.Store.UpsertWorkspaceSetting(ctx, &store.WorkspaceSetting{ - Key: store.WorkspaceSecretSessionName, - Value: string(tempSecret), + secretSessionSetting, err = s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{ + Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION, + Value: &storepb.WorkspaceSetting_SecretSession{ + SecretSession: tempSecret, + }, }) if err != nil { return "", err } } - return secretSessionNameValue.Value, nil + return secretSessionSetting.GetSecretSession(), nil } diff --git a/store/workspace_setting.go b/store/workspace_setting.go index b12e285..eeb8a89 100644 --- a/store/workspace_setting.go +++ b/store/workspace_setting.go @@ -2,35 +2,19 @@ package store import ( "context" + "errors" + "strconv" "strings" + + storepb "github.com/boojack/slash/proto/gen/store" + "google.golang.org/protobuf/encoding/protojson" ) -type WorkspaceSettingKey string - -const ( - // WorkspaceSecretSessionName is the key type for secret session name. - WorkspaceSecretSessionName WorkspaceSettingKey = "secret-session-name" - // WorkspaceDisallowSignUp is the key type for disallow sign up in workspace level. - WorkspaceDisallowSignUp WorkspaceSettingKey = "disallow-signup" - // WorkspaceResourceRelativePath is the key type for resource relative path. - WorkspaceResourceRelativePath WorkspaceSettingKey = "resource-relative-path" -) - -// String returns the string format of WorkspaceSettingKey type. -func (key WorkspaceSettingKey) String() string { - return string(key) -} - -type WorkspaceSetting struct { - Key WorkspaceSettingKey - Value string -} - type FindWorkspaceSetting struct { - Key WorkspaceSettingKey + Key storepb.WorkspaceSettingKey } -func (s *Store) UpsertWorkspaceSetting(ctx context.Context, upsert *WorkspaceSetting) (*WorkspaceSetting, error) { +func (s *Store) UpsertWorkspaceSetting(ctx context.Context, upsert *storepb.WorkspaceSetting) (*storepb.WorkspaceSetting, error) { stmt := ` INSERT INTO workspace_setting ( key, @@ -40,7 +24,24 @@ func (s *Store) UpsertWorkspaceSetting(ctx context.Context, upsert *WorkspaceSet ON CONFLICT(key) DO UPDATE SET value = EXCLUDED.value ` - if _, err := s.db.ExecContext(ctx, stmt, upsert.Key, upsert.Value); err != nil { + var valueString string + if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION { + valueString = upsert.GetSecretSession() + } else if upsert.Key == storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP { + valueString = strconv.FormatBool(upsert.GetEnableSignup()) + } else if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH { + valueString = upsert.GetResourceRelativePath() + } else if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_AUTO_BACKUP { + valueBytes, err := protojson.Marshal(upsert.GetAutoBackup()) + if err != nil { + return nil, err + } + valueString = string(valueBytes) + } else { + return nil, errors.New("invalid workspace setting key") + } + + if _, err := s.db.ExecContext(ctx, stmt, upsert.Key.String(), valueString); err != nil { return nil, err } @@ -49,11 +50,11 @@ func (s *Store) UpsertWorkspaceSetting(ctx context.Context, upsert *WorkspaceSet return workspaceSetting, nil } -func (s *Store) ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSetting) ([]*WorkspaceSetting, error) { +func (s *Store) ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSetting) ([]*storepb.WorkspaceSetting, error) { where, args := []string{"1 = 1"}, []any{} - if find.Key != "" { - where, args = append(where, "key = ?"), append(args, find.Key) + if find.Key != storepb.WorkspaceSettingKey_WORKSPACE_SETTING_KEY_UNSPECIFIED { + where, args = append(where, "key = ?"), append(args, find.Key.String()) } query := ` @@ -69,15 +70,36 @@ func (s *Store) ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSe defer rows.Close() - list := []*WorkspaceSetting{} + list := []*storepb.WorkspaceSetting{} for rows.Next() { - workspaceSetting := &WorkspaceSetting{} + workspaceSetting := &storepb.WorkspaceSetting{} + var keyString, valueString string if err := rows.Scan( - &workspaceSetting.Key, - &workspaceSetting.Value, + &keyString, + &valueString, ); err != nil { return nil, err } + workspaceSetting.Key = storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[keyString]) + if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION { + workspaceSetting.Value = &storepb.WorkspaceSetting_SecretSession{SecretSession: valueString} + } else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP { + enableSignup, err := strconv.ParseBool(valueString) + if err != nil { + return nil, err + } + workspaceSetting.Value = &storepb.WorkspaceSetting_EnableSignup{EnableSignup: enableSignup} + } else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH { + workspaceSetting.Value = &storepb.WorkspaceSetting_ResourceRelativePath{ResourceRelativePath: valueString} + } else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_AUTO_BACKUP { + autoBackupSetting := &storepb.AutoBackupWorkspaceSetting{} + if err := protojson.Unmarshal([]byte(valueString), autoBackupSetting); err != nil { + return nil, err + } + workspaceSetting.Value = &storepb.WorkspaceSetting_AutoBackup{AutoBackup: autoBackupSetting} + } else { + return nil, errors.New("invalid workspace setting key") + } list = append(list, workspaceSetting) } @@ -93,10 +115,10 @@ func (s *Store) ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSe return list, nil } -func (s *Store) GetWorkspaceSetting(ctx context.Context, find *FindWorkspaceSetting) (*WorkspaceSetting, error) { - if find.Key != "" { +func (s *Store) GetWorkspaceSetting(ctx context.Context, find *FindWorkspaceSetting) (*storepb.WorkspaceSetting, error) { + if find.Key != storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP { if cache, ok := s.workspaceSettingCache.Load(find.Key); ok { - return cache.(*WorkspaceSetting), nil + return cache.(*storepb.WorkspaceSetting), nil } } diff --git a/store/workspace_setting_v1.go b/store/workspace_setting_v1.go deleted file mode 100644 index b3175df..0000000 --- a/store/workspace_setting_v1.go +++ /dev/null @@ -1,137 +0,0 @@ -package store - -import ( - "context" - "errors" - "strconv" - "strings" - - storepb "github.com/boojack/slash/proto/gen/store" - "google.golang.org/protobuf/encoding/protojson" -) - -type FindWorkspaceSettingV1 struct { - Key storepb.WorkspaceSettingKey -} - -func (s *Store) UpsertWorkspaceSettingV1(ctx context.Context, upsert *storepb.WorkspaceSetting) (*storepb.WorkspaceSetting, error) { - stmt := ` - INSERT INTO workspace_setting ( - key, - value - ) - VALUES (?, ?) - ON CONFLICT(key) DO UPDATE - SET value = EXCLUDED.value - ` - var valueString string - if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION { - valueString = upsert.GetSecretSession() - } else if upsert.Key == storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP { - valueString = strconv.FormatBool(upsert.GetEnableSignup()) - } else if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH { - valueString = upsert.GetResourceRelativePath() - } else if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_AUTO_BACKUP { - valueBytes, err := protojson.Marshal(upsert.GetAutoBackup()) - if err != nil { - return nil, err - } - valueString = string(valueBytes) - } else { - return nil, errors.New("invalid workspace setting key") - } - - if _, err := s.db.ExecContext(ctx, stmt, upsert.Key.String(), valueString); err != nil { - return nil, err - } - - workspaceSetting := upsert - s.workspaceSettingCache.Store(workspaceSetting.Key, workspaceSetting) - return workspaceSetting, nil -} - -func (s *Store) ListWorkspaceSettingsV1(ctx context.Context, find *FindWorkspaceSettingV1) ([]*storepb.WorkspaceSetting, error) { - where, args := []string{"1 = 1"}, []any{} - - if find.Key != storepb.WorkspaceSettingKey_WORKSPACE_SETTING_KEY_UNSPECIFIED { - where, args = append(where, "key = ?"), append(args, find.Key.String()) - } - - query := ` - SELECT - key, - value - FROM workspace_setting - WHERE ` + strings.Join(where, " AND ") - rows, err := s.db.QueryContext(ctx, query, args...) - if err != nil { - return nil, err - } - - defer rows.Close() - - list := []*storepb.WorkspaceSetting{} - for rows.Next() { - workspaceSetting := &storepb.WorkspaceSetting{} - var keyString, valueString string - if err := rows.Scan( - &keyString, - &valueString, - ); err != nil { - return nil, err - } - workspaceSetting.Key = storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[keyString]) - if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION { - workspaceSetting.Value = &storepb.WorkspaceSetting_SecretSession{SecretSession: valueString} - } else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP { - enableSignup, err := strconv.ParseBool(valueString) - if err != nil { - return nil, err - } - workspaceSetting.Value = &storepb.WorkspaceSetting_EnableSignup{EnableSignup: enableSignup} - } else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH { - workspaceSetting.Value = &storepb.WorkspaceSetting_ResourceRelativePath{ResourceRelativePath: valueString} - } else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_AUTO_BACKUP { - autoBackupSetting := &storepb.AutoBackupWorkspaceSetting{} - if err := protojson.Unmarshal([]byte(valueString), autoBackupSetting); err != nil { - return nil, err - } - workspaceSetting.Value = &storepb.WorkspaceSetting_AutoBackup{AutoBackup: autoBackupSetting} - } else { - return nil, errors.New("invalid workspace setting key") - } - - list = append(list, workspaceSetting) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - for _, workspaceSetting := range list { - s.workspaceSettingCache.Store(workspaceSetting.Key, workspaceSetting) - } - - return list, nil -} - -func (s *Store) GetWorkspaceSettingV1(ctx context.Context, find *FindWorkspaceSettingV1) (*storepb.WorkspaceSetting, error) { - if find.Key != storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP { - if cache, ok := s.workspaceSettingCache.Load(find.Key); ok { - return cache.(*storepb.WorkspaceSetting), nil - } - } - - list, err := s.ListWorkspaceSettingsV1(ctx, find) - if err != nil { - return nil, err - } - - if len(list) == 0 { - return nil, nil - } - - workspaceSetting := list[0] - s.workspaceSettingCache.Store(workspaceSetting.Key, workspaceSetting) - return workspaceSetting, nil -} diff --git a/test/store/workspace_setting_test.go b/test/store/workspace_setting_test.go index 6ae4b7f..ab2b534 100644 --- a/test/store/workspace_setting_test.go +++ b/test/store/workspace_setting_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + storepb "github.com/boojack/slash/proto/gen/store" "github.com/boojack/slash/store" "github.com/google/uuid" "github.com/stretchr/testify/require" @@ -13,13 +14,13 @@ func TestWorkspaceSettingStore(t *testing.T) { ctx := context.Background() ts := NewTestingStore(ctx, t) tempSecret := uuid.New().String() - workspaceSetting, err := ts.UpsertWorkspaceSetting(ctx, &store.WorkspaceSetting{ - Key: store.WorkspaceSecretSessionName, - Value: string(tempSecret), + workspaceSetting, err := ts.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{ + Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION, + Value: &storepb.WorkspaceSetting_SecretSession{SecretSession: tempSecret}, }) require.NoError(t, err) foundWorkspaceSetting, err := ts.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ - Key: store.WorkspaceSecretSessionName, + Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION, }) require.NoError(t, err) require.Equal(t, workspaceSetting, foundWorkspaceSetting)