Skip to content

Commit

Permalink
feat: support disable change username and nickname (#3911)
Browse files Browse the repository at this point in the history
* feat: support disable change username and nickname

* chore: update UX
  • Loading branch information
thezzisu authored Sep 12, 2024
1 parent 6f3d576 commit b787d1c
Show file tree
Hide file tree
Showing 9 changed files with 514 additions and 267 deletions.
271 changes: 207 additions & 64 deletions docs/apidocs.swagger.yaml

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions proto/api/v1/workspace_setting_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ message WorkspaceGeneralSetting {
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// Default is Sunday.
int32 week_start_day_offset = 6;

// disallow_change_username disallows changing username.
bool disallow_change_username = 7;
// disallow_change_nickname disallows changing nickname.
bool disallow_change_nickname = 8;
}

message WorkspaceCustomProfile {
Expand Down
251 changes: 138 additions & 113 deletions proto/gen/api/v1/workspace_setting_service.pb.go

Large diffs are not rendered by default.

200 changes: 113 additions & 87 deletions proto/gen/store/workspace_setting.pb.go

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions proto/store/workspace_setting.proto
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ message WorkspaceGeneralSetting {
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// Default is Sunday.
int32 week_start_day_offset = 6;

// disallow_change_username disallows changing username.
bool disallow_change_username = 7;
// disallow_change_nickname disallows changing nickname.
bool disallow_change_nickname = 8;
}

message WorkspaceCustomProfile {
Expand Down
11 changes: 11 additions & 0 deletions server/router/api/v1/user_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ func (s *APIV1Service) CreateUser(ctx context.Context, request *v1pb.CreateUserR
}

func (s *APIV1Service) UpdateUser(ctx context.Context, request *v1pb.UpdateUserRequest) (*v1pb.User, error) {
workspaceGeneralSetting, err := s.Store.GetWorkspaceGeneralSetting(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, fmt.Sprintf("failed to get workspace general setting, err: %s", err))
}

userID, err := ExtractUserIDFromName(request.User.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
Expand Down Expand Up @@ -196,11 +201,17 @@ func (s *APIV1Service) UpdateUser(ctx context.Context, request *v1pb.UpdateUserR
}
for _, field := range request.UpdateMask.Paths {
if field == "username" {
if workspaceGeneralSetting.DisallowChangeUsername {
return nil, status.Errorf(codes.PermissionDenied, "permission denied: disallow change username")
}
if !util.UIDMatcher.MatchString(strings.ToLower(request.User.Username)) {
return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", request.User.Username)
}
update.Username = &request.User.Username
} else if field == "nickname" {
if workspaceGeneralSetting.DisallowChangeNickname {
return nil, status.Errorf(codes.PermissionDenied, "permission denied: disallow change nickname")
}
update.Nickname = &request.User.Nickname
} else if field == "email" {
update.Email = &request.User.Email
Expand Down
4 changes: 4 additions & 0 deletions server/router/api/v1/workspace_setting_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSe
AdditionalScript: setting.AdditionalScript,
AdditionalStyle: setting.AdditionalStyle,
WeekStartDayOffset: setting.WeekStartDayOffset,
DisallowChangeUsername: setting.DisallowChangeUsername,
DisallowChangeNickname: setting.DisallowChangeNickname,
}
if setting.CustomProfile != nil {
generalSetting.CustomProfile = &v1pb.WorkspaceCustomProfile{
Expand All @@ -160,6 +162,8 @@ func convertWorkspaceGeneralSettingToStore(setting *v1pb.WorkspaceGeneralSetting
AdditionalScript: setting.AdditionalScript,
AdditionalStyle: setting.AdditionalStyle,
WeekStartDayOffset: setting.WeekStartDayOffset,
DisallowChangeUsername: setting.DisallowChangeUsername,
DisallowChangeNickname: setting.DisallowChangeNickname,
}
if setting.CustomProfile != nil {
generalSetting.CustomProfile = &storepb.WorkspaceCustomProfile{
Expand Down
14 changes: 14 additions & 0 deletions web/src/components/Settings/WorkspaceSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ const WorkspaceSection = () => {
onChange={(event) => updatePartialSetting({ disallowPasswordAuth: event.target.checked })}
/>
</div>
<div className="w-full flex flex-row justify-between items-center">
<span>Disallow Change Username</span>
<Switch
checked={workspaceGeneralSetting.disallowChangeUsername}
onChange={(event) => updatePartialSetting({ disallowChangeUsername: event.target.checked })}
/>
</div>
<div className="w-full flex flex-row justify-between items-center">
<span>Disallow Change Nickname</span>
<Switch
checked={workspaceGeneralSetting.disallowChangeNickname}
onChange={(event) => updatePartialSetting({ disallowChangeNickname: event.target.checked })}
/>
</div>
<div className="w-full flex flex-row justify-between items-center">
<span className="truncate">Week start day</span>
<Select
Expand Down
20 changes: 17 additions & 3 deletions web/src/components/UpdateAccountDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { useState } from "react";
import { toast } from "react-hot-toast";
import { convertFileToBase64 } from "@/helpers/utils";
import useCurrentUser from "@/hooks/useCurrentUser";
import { userNamePrefix, useUserStore } from "@/store/v1";
import { userNamePrefix, useUserStore, useWorkspaceSettingStore } from "@/store/v1";
import { User as UserPb } from "@/types/proto/api/v1/user_service";
import { WorkspaceGeneralSetting, WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
import { useTranslate } from "@/utils/i18n";
import { generateDialog } from "./Dialog";
import UserAvatar from "./UserAvatar";
Expand All @@ -32,6 +33,9 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
email: currentUser.email,
description: currentUser.description,
});
const workspaceSettingStore = useWorkspaceSettingStore();
const workspaceGeneralSetting =
workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.GENERAL)?.generalSetting || WorkspaceGeneralSetting.fromPartial({});

const handleCloseBtnClick = () => {
destroy();
Expand Down Expand Up @@ -168,12 +172,22 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
{t("common.username")}
<span className="text-sm text-gray-400 ml-1">({t("setting.account-section.username-note")})</span>
</p>
<Input className="w-full" value={state.username} onChange={handleUsernameChanged} />
<Input
className="w-full"
value={state.username}
onChange={handleUsernameChanged}
disabled={workspaceGeneralSetting.disallowChangeUsername}
/>
<p className="text-sm">
{t("common.nickname")}
<span className="text-sm text-gray-400 ml-1">({t("setting.account-section.nickname-note")})</span>
</p>
<Input className="w-full" value={state.nickname} onChange={handleNicknameChanged} />
<Input
className="w-full"
value={state.nickname}
onChange={handleNicknameChanged}
disabled={workspaceGeneralSetting.disallowChangeNickname}
/>
<p className="text-sm">
{t("common.email")}
<span className="text-sm text-gray-400 ml-1">({t("setting.account-section.email-note")})</span>
Expand Down

0 comments on commit b787d1c

Please sign in to comment.