Unverified Commit b787d1c7 authored by Zisu Zhang's avatar Zisu Zhang Committed by GitHub

feat: support disable change username and nickname (#3911)

* feat: support disable change username and nickname

* chore: update UX
parent 6f3d5762
This diff is collapsed.
......@@ -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 {
......
This diff is collapsed.
......@@ -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 {
......
......@@ -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)
......@@ -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
......
......@@ -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{
......@@ -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{
......
......@@ -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
......
......@@ -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";
......@@ -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();
......@@ -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>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment