Commit 1ea4cc45 authored by Steven's avatar Steven

refactor: workspace setting service

parent da906c66
......@@ -3,6 +3,10 @@ syntax = "proto3";
package memos.api.v1;
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/field_mask.proto";
option go_package = "gen/api/v1";
......@@ -11,6 +15,21 @@ service WorkspaceService {
rpc GetWorkspaceProfile(GetWorkspaceProfileRequest) returns (WorkspaceProfile) {
option (google.api.http) = {get: "/api/v1/workspace/profile"};
}
// Gets a workspace setting.
rpc GetWorkspaceSetting(GetWorkspaceSettingRequest) returns (WorkspaceSetting) {
option (google.api.http) = {get: "/api/v1/{name=workspace/settings/*}"};
option (google.api.method_signature) = "name";
}
// Updates a workspace setting.
rpc UpdateWorkspaceSetting(UpdateWorkspaceSettingRequest) returns (WorkspaceSetting) {
option (google.api.http) = {
patch: "/api/v1/{setting.name=workspace/settings/*}"
body: "setting"
};
option (google.api.method_signature) = "setting,update_mask";
}
}
// Workspace profile message containing basic workspace information.
......@@ -31,3 +50,127 @@ message WorkspaceProfile {
// Request for workspace profile.
message GetWorkspaceProfileRequest {}
// A workspace setting resource.
message WorkspaceSetting {
option (google.api.resource) = {
type: "api.memos.dev/WorkspaceSetting"
pattern: "workspace/settings/{setting}"
singular: "workspaceSetting"
plural: "workspaceSettings"
};
// The name of the workspace setting.
// Format: workspace/settings/{setting}
string name = 1 [(google.api.field_behavior) = IDENTIFIER];
oneof value {
WorkspaceGeneralSetting general_setting = 2;
WorkspaceStorageSetting storage_setting = 3;
WorkspaceMemoRelatedSetting memo_related_setting = 4;
}
}
message WorkspaceGeneralSetting {
// disallow_user_registration disallows user registration.
bool disallow_user_registration = 1;
// disallow_password_auth disallows password authentication.
bool disallow_password_auth = 2;
// additional_script is the additional script.
string additional_script = 3;
// additional_style is the additional style.
string additional_style = 4;
// custom_profile is the custom profile.
WorkspaceCustomProfile custom_profile = 5;
// week_start_day_offset is the week start day offset from Sunday.
// 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 {
string title = 1;
string description = 2;
string logo_url = 3;
string locale = 4;
string appearance = 5;
}
message WorkspaceStorageSetting {
enum StorageType {
STORAGE_TYPE_UNSPECIFIED = 0;
// DATABASE is the database storage type.
DATABASE = 1;
// LOCAL is the local storage type.
LOCAL = 2;
// S3 is the S3 storage type.
S3 = 3;
}
// storage_type is the storage type.
StorageType storage_type = 1;
// The template of file path.
// e.g. assets/{timestamp}_{filename}
string filepath_template = 2;
// The max upload size in megabytes.
int64 upload_size_limit_mb = 3;
// Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/
message S3Config {
string access_key_id = 1;
string access_key_secret = 2;
string endpoint = 3;
string region = 4;
string bucket = 5;
bool use_path_style = 6;
}
// The S3 config.
S3Config s3_config = 4;
}
message WorkspaceMemoRelatedSetting {
reserved 4, 8;
// disallow_public_visibility disallows set memo as public visibility.
bool disallow_public_visibility = 1;
// display_with_update_time orders and displays memo with update time.
bool display_with_update_time = 2;
// content_length_limit is the limit of content length. Unit is byte.
int32 content_length_limit = 3;
// enable_double_click_edit enables editing on double click.
bool enable_double_click_edit = 5;
// enable_link_preview enables links preview.
bool enable_link_preview = 6;
// enable_comment enables comment.
bool enable_comment = 7;
// reactions is the list of reactions.
repeated string reactions = 10;
// disable_markdown_shortcuts disallow the registration of markdown shortcuts.
bool disable_markdown_shortcuts = 11;
// enable_blur_nsfw_content enables blurring of content marked as not safe for work (NSFW).
bool enable_blur_nsfw_content = 12;
// nsfw_tags is the list of tags that mark content as NSFW for blurring.
repeated string nsfw_tags = 13;
}
// Request message for GetWorkspaceSetting method.
message GetWorkspaceSettingRequest {
// The resource name of the workspace setting.
// Format: workspace/settings/{setting}
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "api.memos.dev/WorkspaceSetting"}
];
}
// Request message for UpdateWorkspaceSetting method.
message UpdateWorkspaceSettingRequest {
// The workspace setting resource which replaces the resource on the server.
WorkspaceSetting setting = 1 [(google.api.field_behavior) = REQUIRED];
// The list of fields to update.
google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL];
}
syntax = "proto3";
package memos.api.v1;
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
option go_package = "gen/api/v1";
service WorkspaceSettingService {
// GetWorkspaceSetting returns the setting by name.
rpc GetWorkspaceSetting(GetWorkspaceSettingRequest) returns (WorkspaceSetting) {
option (google.api.http) = {get: "/api/v1/workspace/{name=settings/*}"};
option (google.api.method_signature) = "name";
}
// SetWorkspaceSetting updates the setting.
rpc SetWorkspaceSetting(SetWorkspaceSettingRequest) returns (WorkspaceSetting) {
option (google.api.http) = {
patch: "/api/v1/workspace/{setting.name=settings/*}"
body: "setting"
};
option (google.api.method_signature) = "setting";
}
}
message WorkspaceSetting {
// name is the name of the setting.
// Format: settings/{setting}
string name = 1;
oneof value {
WorkspaceGeneralSetting general_setting = 2;
WorkspaceStorageSetting storage_setting = 3;
WorkspaceMemoRelatedSetting memo_related_setting = 4;
}
}
message WorkspaceGeneralSetting {
// disallow_user_registration disallows user registration.
bool disallow_user_registration = 1;
// disallow_password_auth disallows password authentication.
bool disallow_password_auth = 2;
// additional_script is the additional script.
string additional_script = 3;
// additional_style is the additional style.
string additional_style = 4;
// custom_profile is the custom profile.
WorkspaceCustomProfile custom_profile = 5;
// week_start_day_offset is the week start day offset from Sunday.
// 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 {
string title = 1;
string description = 2;
string logo_url = 3;
string locale = 4;
string appearance = 5;
}
message WorkspaceStorageSetting {
enum StorageType {
STORAGE_TYPE_UNSPECIFIED = 0;
// DATABASE is the database storage type.
DATABASE = 1;
// LOCAL is the local storage type.
LOCAL = 2;
// S3 is the S3 storage type.
S3 = 3;
}
// storage_type is the storage type.
StorageType storage_type = 1;
// The template of file path.
// e.g. assets/{timestamp}_{filename}
string filepath_template = 2;
// The max upload size in megabytes.
int64 upload_size_limit_mb = 3;
// Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/
message S3Config {
string access_key_id = 1;
string access_key_secret = 2;
string endpoint = 3;
string region = 4;
string bucket = 5;
bool use_path_style = 6;
}
// The S3 config.
S3Config s3_config = 4;
}
message WorkspaceMemoRelatedSetting {
reserved 4, 8;
// disallow_public_visibility disallows set memo as public visibility.
bool disallow_public_visibility = 1;
// display_with_update_time orders and displays memo with update time.
bool display_with_update_time = 2;
// content_length_limit is the limit of content length. Unit is byte.
int32 content_length_limit = 3;
// enable_double_click_edit enables editing on double click.
bool enable_double_click_edit = 5;
// enable_link_preview enables links preview.
bool enable_link_preview = 6;
// enable_comment enables comment.
bool enable_comment = 7;
// reactions is the list of reactions.
repeated string reactions = 10;
// disable_markdown_shortcuts disallow the registration of markdown shortcuts.
bool disable_markdown_shortcuts = 11;
// enable_blur_nsfw_content enables blurring of content marked as not safe for work (NSFW).
bool enable_blur_nsfw_content = 12;
// nsfw_tags is the list of tags that mark content as NSFW for blurring.
repeated string nsfw_tags = 13;
}
message GetWorkspaceSettingRequest {
// The resource name of the workspace setting.
// Format: settings/{setting}
string name = 1 [(google.api.field_behavior) = REQUIRED];
}
message SetWorkspaceSettingRequest {
// setting is the setting to update.
WorkspaceSetting setting = 1;
}
This diff is collapsed.
This diff is collapsed.
......@@ -19,7 +19,9 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
WorkspaceService_GetWorkspaceProfile_FullMethodName = "/memos.api.v1.WorkspaceService/GetWorkspaceProfile"
WorkspaceService_GetWorkspaceProfile_FullMethodName = "/memos.api.v1.WorkspaceService/GetWorkspaceProfile"
WorkspaceService_GetWorkspaceSetting_FullMethodName = "/memos.api.v1.WorkspaceService/GetWorkspaceSetting"
WorkspaceService_UpdateWorkspaceSetting_FullMethodName = "/memos.api.v1.WorkspaceService/UpdateWorkspaceSetting"
)
// WorkspaceServiceClient is the client API for WorkspaceService service.
......@@ -28,6 +30,10 @@ const (
type WorkspaceServiceClient interface {
// Gets the workspace profile.
GetWorkspaceProfile(ctx context.Context, in *GetWorkspaceProfileRequest, opts ...grpc.CallOption) (*WorkspaceProfile, error)
// Gets a workspace setting.
GetWorkspaceSetting(ctx context.Context, in *GetWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error)
// Updates a workspace setting.
UpdateWorkspaceSetting(ctx context.Context, in *UpdateWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error)
}
type workspaceServiceClient struct {
......@@ -48,12 +54,36 @@ func (c *workspaceServiceClient) GetWorkspaceProfile(ctx context.Context, in *Ge
return out, nil
}
func (c *workspaceServiceClient) GetWorkspaceSetting(ctx context.Context, in *GetWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(WorkspaceSetting)
err := c.cc.Invoke(ctx, WorkspaceService_GetWorkspaceSetting_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *workspaceServiceClient) UpdateWorkspaceSetting(ctx context.Context, in *UpdateWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(WorkspaceSetting)
err := c.cc.Invoke(ctx, WorkspaceService_UpdateWorkspaceSetting_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// WorkspaceServiceServer is the server API for WorkspaceService service.
// All implementations must embed UnimplementedWorkspaceServiceServer
// for forward compatibility.
type WorkspaceServiceServer interface {
// Gets the workspace profile.
GetWorkspaceProfile(context.Context, *GetWorkspaceProfileRequest) (*WorkspaceProfile, error)
// Gets a workspace setting.
GetWorkspaceSetting(context.Context, *GetWorkspaceSettingRequest) (*WorkspaceSetting, error)
// Updates a workspace setting.
UpdateWorkspaceSetting(context.Context, *UpdateWorkspaceSettingRequest) (*WorkspaceSetting, error)
mustEmbedUnimplementedWorkspaceServiceServer()
}
......@@ -67,6 +97,12 @@ type UnimplementedWorkspaceServiceServer struct{}
func (UnimplementedWorkspaceServiceServer) GetWorkspaceProfile(context.Context, *GetWorkspaceProfileRequest) (*WorkspaceProfile, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetWorkspaceProfile not implemented")
}
func (UnimplementedWorkspaceServiceServer) GetWorkspaceSetting(context.Context, *GetWorkspaceSettingRequest) (*WorkspaceSetting, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetWorkspaceSetting not implemented")
}
func (UnimplementedWorkspaceServiceServer) UpdateWorkspaceSetting(context.Context, *UpdateWorkspaceSettingRequest) (*WorkspaceSetting, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateWorkspaceSetting not implemented")
}
func (UnimplementedWorkspaceServiceServer) mustEmbedUnimplementedWorkspaceServiceServer() {}
func (UnimplementedWorkspaceServiceServer) testEmbeddedByValue() {}
......@@ -106,6 +142,42 @@ func _WorkspaceService_GetWorkspaceProfile_Handler(srv interface{}, ctx context.
return interceptor(ctx, in, info, handler)
}
func _WorkspaceService_GetWorkspaceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetWorkspaceSettingRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WorkspaceServiceServer).GetWorkspaceSetting(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: WorkspaceService_GetWorkspaceSetting_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WorkspaceServiceServer).GetWorkspaceSetting(ctx, req.(*GetWorkspaceSettingRequest))
}
return interceptor(ctx, in, info, handler)
}
func _WorkspaceService_UpdateWorkspaceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateWorkspaceSettingRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WorkspaceServiceServer).UpdateWorkspaceSetting(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: WorkspaceService_UpdateWorkspaceSetting_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WorkspaceServiceServer).UpdateWorkspaceSetting(ctx, req.(*UpdateWorkspaceSettingRequest))
}
return interceptor(ctx, in, info, handler)
}
// WorkspaceService_ServiceDesc is the grpc.ServiceDesc for WorkspaceService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
......@@ -117,6 +189,14 @@ var WorkspaceService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetWorkspaceProfile",
Handler: _WorkspaceService_GetWorkspaceProfile_Handler,
},
{
MethodName: "GetWorkspaceSetting",
Handler: _WorkspaceService_GetWorkspaceSetting_Handler,
},
{
MethodName: "UpdateWorkspaceSetting",
Handler: _WorkspaceService_UpdateWorkspaceSetting_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/v1/workspace_service.proto",
......
This diff is collapsed.
This diff is collapsed.
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc (unknown)
// source: api/v1/workspace_setting_service.proto
package apiv1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
WorkspaceSettingService_GetWorkspaceSetting_FullMethodName = "/memos.api.v1.WorkspaceSettingService/GetWorkspaceSetting"
WorkspaceSettingService_SetWorkspaceSetting_FullMethodName = "/memos.api.v1.WorkspaceSettingService/SetWorkspaceSetting"
)
// WorkspaceSettingServiceClient is the client API for WorkspaceSettingService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type WorkspaceSettingServiceClient interface {
// GetWorkspaceSetting returns the setting by name.
GetWorkspaceSetting(ctx context.Context, in *GetWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error)
// SetWorkspaceSetting updates the setting.
SetWorkspaceSetting(ctx context.Context, in *SetWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error)
}
type workspaceSettingServiceClient struct {
cc grpc.ClientConnInterface
}
func NewWorkspaceSettingServiceClient(cc grpc.ClientConnInterface) WorkspaceSettingServiceClient {
return &workspaceSettingServiceClient{cc}
}
func (c *workspaceSettingServiceClient) GetWorkspaceSetting(ctx context.Context, in *GetWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(WorkspaceSetting)
err := c.cc.Invoke(ctx, WorkspaceSettingService_GetWorkspaceSetting_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *workspaceSettingServiceClient) SetWorkspaceSetting(ctx context.Context, in *SetWorkspaceSettingRequest, opts ...grpc.CallOption) (*WorkspaceSetting, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(WorkspaceSetting)
err := c.cc.Invoke(ctx, WorkspaceSettingService_SetWorkspaceSetting_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// WorkspaceSettingServiceServer is the server API for WorkspaceSettingService service.
// All implementations must embed UnimplementedWorkspaceSettingServiceServer
// for forward compatibility.
type WorkspaceSettingServiceServer interface {
// GetWorkspaceSetting returns the setting by name.
GetWorkspaceSetting(context.Context, *GetWorkspaceSettingRequest) (*WorkspaceSetting, error)
// SetWorkspaceSetting updates the setting.
SetWorkspaceSetting(context.Context, *SetWorkspaceSettingRequest) (*WorkspaceSetting, error)
mustEmbedUnimplementedWorkspaceSettingServiceServer()
}
// UnimplementedWorkspaceSettingServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedWorkspaceSettingServiceServer struct{}
func (UnimplementedWorkspaceSettingServiceServer) GetWorkspaceSetting(context.Context, *GetWorkspaceSettingRequest) (*WorkspaceSetting, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetWorkspaceSetting not implemented")
}
func (UnimplementedWorkspaceSettingServiceServer) SetWorkspaceSetting(context.Context, *SetWorkspaceSettingRequest) (*WorkspaceSetting, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetWorkspaceSetting not implemented")
}
func (UnimplementedWorkspaceSettingServiceServer) mustEmbedUnimplementedWorkspaceSettingServiceServer() {
}
func (UnimplementedWorkspaceSettingServiceServer) testEmbeddedByValue() {}
// UnsafeWorkspaceSettingServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to WorkspaceSettingServiceServer will
// result in compilation errors.
type UnsafeWorkspaceSettingServiceServer interface {
mustEmbedUnimplementedWorkspaceSettingServiceServer()
}
func RegisterWorkspaceSettingServiceServer(s grpc.ServiceRegistrar, srv WorkspaceSettingServiceServer) {
// If the following call pancis, it indicates UnimplementedWorkspaceSettingServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&WorkspaceSettingService_ServiceDesc, srv)
}
func _WorkspaceSettingService_GetWorkspaceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetWorkspaceSettingRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WorkspaceSettingServiceServer).GetWorkspaceSetting(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: WorkspaceSettingService_GetWorkspaceSetting_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WorkspaceSettingServiceServer).GetWorkspaceSetting(ctx, req.(*GetWorkspaceSettingRequest))
}
return interceptor(ctx, in, info, handler)
}
func _WorkspaceSettingService_SetWorkspaceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SetWorkspaceSettingRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WorkspaceSettingServiceServer).SetWorkspaceSetting(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: WorkspaceSettingService_SetWorkspaceSetting_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WorkspaceSettingServiceServer).SetWorkspaceSetting(ctx, req.(*SetWorkspaceSettingRequest))
}
return interceptor(ctx, in, info, handler)
}
// WorkspaceSettingService_ServiceDesc is the grpc.ServiceDesc for WorkspaceSettingService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var WorkspaceSettingService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "memos.api.v1.WorkspaceSettingService",
HandlerType: (*WorkspaceSettingServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetWorkspaceSetting",
Handler: _WorkspaceSettingService_GetWorkspaceSetting_Handler,
},
{
MethodName: "SetWorkspaceSetting",
Handler: _WorkspaceSettingService_SetWorkspaceSetting_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/v1/workspace_setting_service.proto",
}
......@@ -14,7 +14,6 @@ tags:
- name: ShortcutService
- name: WebhookService
- name: WorkspaceService
- name: WorkspaceSettingService
consumes:
- application/json
produces:
......@@ -707,68 +706,6 @@ paths:
$ref: '#/definitions/googlerpcStatus'
tags:
- WorkspaceService
/api/v1/workspace/{name}:
get:
summary: GetWorkspaceSetting returns the setting by name.
operationId: WorkspaceSettingService_GetWorkspaceSetting
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/apiv1WorkspaceSetting'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: |-
The resource name of the workspace setting.
Format: settings/{setting}
in: path
required: true
type: string
pattern: settings/[^/]+
tags:
- WorkspaceSettingService
/api/v1/workspace/{setting.name}:
patch:
summary: SetWorkspaceSetting updates the setting.
operationId: WorkspaceSettingService_SetWorkspaceSetting
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/apiv1WorkspaceSetting'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: setting.name
description: |-
name is the name of the setting.
Format: settings/{setting}
in: path
required: true
type: string
pattern: settings/[^/]+
- name: setting
description: setting is the setting to update.
in: body
required: true
schema:
type: object
properties:
generalSetting:
$ref: '#/definitions/apiv1WorkspaceGeneralSetting'
storageSetting:
$ref: '#/definitions/apiv1WorkspaceStorageSetting'
memoRelatedSetting:
$ref: '#/definitions/apiv1WorkspaceMemoRelatedSetting'
title: setting is the setting to update.
tags:
- WorkspaceSettingService
/api/v1/{identityProvider.name}:
patch:
summary: UpdateIdentityProvider updates an identity provider.
......@@ -1199,6 +1136,29 @@ paths:
tags:
- MemoService
/api/v1/{name_6}:
get:
summary: Gets a workspace setting.
operationId: WorkspaceService_GetWorkspaceSetting
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/apiv1WorkspaceSetting'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name_6
description: |-
The resource name of the workspace setting.
Format: workspace/settings/{setting}
in: path
required: true
type: string
pattern: workspace/settings/[^/]+
tags:
- WorkspaceService
delete:
summary: DeleteWebhook deletes a webhook.
operationId: WebhookService_DeleteWebhook
......@@ -1929,6 +1889,46 @@ paths:
description: The related memo. Refer to `Memo.name`.
tags:
- ResourceService
/api/v1/{setting.name}:
patch:
summary: Updates a workspace setting.
operationId: WorkspaceService_UpdateWorkspaceSetting
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/apiv1WorkspaceSetting'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: setting.name
description: |-
The name of the workspace setting.
Format: workspace/settings/{setting}
in: path
required: true
type: string
pattern: workspace/settings/[^/]+
- name: setting
description: The workspace setting resource which replaces the resource on the server.
in: body
required: true
schema:
type: object
properties:
generalSetting:
$ref: '#/definitions/apiv1WorkspaceGeneralSetting'
storageSetting:
$ref: '#/definitions/apiv1WorkspaceStorageSetting'
memoRelatedSetting:
$ref: '#/definitions/apiv1WorkspaceMemoRelatedSetting'
title: The workspace setting resource which replaces the resource on the server.
required:
- setting
tags:
- WorkspaceService
/api/v1/{setting.name}:updateSetting:
patch:
summary: UpdateUserSetting updates the user setting.
......@@ -2591,14 +2591,15 @@ definitions:
name:
type: string
title: |-
name is the name of the setting.
Format: settings/{setting}
The name of the workspace setting.
Format: workspace/settings/{setting}
generalSetting:
$ref: '#/definitions/apiv1WorkspaceGeneralSetting'
storageSetting:
$ref: '#/definitions/apiv1WorkspaceStorageSetting'
memoRelatedSetting:
$ref: '#/definitions/apiv1WorkspaceMemoRelatedSetting'
description: A workspace setting resource.
apiv1WorkspaceStorageSetting:
type: object
properties:
......
......@@ -2,8 +2,7 @@ package v1
var authenticationAllowlistMethods = map[string]bool{
"/memos.api.v1.WorkspaceService/GetWorkspaceProfile": true,
"/memos.api.v1.WorkspaceSettingService/GetWorkspaceSetting": true,
"/memos.api.v1.WorkspaceSettingService/ListWorkspaceSettings": true,
"/memos.api.v1.WorkspaceService/GetWorkspaceSetting": true,
"/memos.api.v1.IdentityProviderService/GetIdentityProvider": true,
"/memos.api.v1.IdentityProviderService/ListIdentityProviders": true,
"/memos.api.v1.AuthService/GetAuthStatus": true,
......@@ -28,8 +27,8 @@ func isUnauthorizeAllowedMethod(fullMethodName string) bool {
}
var allowedMethodsOnlyForAdmin = map[string]bool{
"/memos.api.v1.UserService/CreateUser": true,
"/memos.api.v1.WorkspaceSettingService/SetWorkspaceSetting": true,
"/memos.api.v1.UserService/CreateUser": true,
"/memos.api.v1.WorkspaceService/UpdateWorkspaceSetting": true,
}
// isOnlyForAdminAllowedMethod returns true if the method is allowed to be called only by admin.
......
......@@ -10,7 +10,7 @@ import (
)
const (
WorkspaceSettingNamePrefix = "settings/"
WorkspaceSettingNamePrefix = "workspace/settings/"
UserNamePrefix = "users/"
MemoNamePrefix = "memos/"
ResourceNamePrefix = "resources/"
......@@ -41,11 +41,22 @@ func GetNameParentTokens(name string, tokenPrefixes ...string) ([]string, error)
}
func ExtractWorkspaceSettingKeyFromName(name string) (string, error) {
tokens, err := GetNameParentTokens(name, WorkspaceSettingNamePrefix)
if err != nil {
return "", err
const prefix = "workspace/settings/"
if !strings.HasPrefix(name, prefix) {
return "", errors.Errorf("invalid workspace setting name: expected prefix %q, got %q", prefix, name)
}
settingKey := strings.TrimPrefix(name, prefix)
if settingKey == "" {
return "", errors.Errorf("invalid workspace setting name: empty setting key in %q", name)
}
return tokens[0], nil
// Ensure there are no additional path segments
if strings.Contains(settingKey, "/") {
return "", errors.Errorf("invalid workspace setting name: setting key cannot contain '/' in %q", name)
}
return settingKey, nil
}
// ExtractUserIDFromName returns the uid from a resource name.
......
......@@ -341,7 +341,7 @@ func (s *APIV1Service) GetUserSetting(ctx context.Context, request *v1pb.GetUser
}
userSettingMessage := getDefaultUserSetting()
userSettingMessage.Name = fmt.Sprintf("users/%d/setting", userID)
userSettingMessage.Name = fmt.Sprintf("users/%d", userID)
for _, setting := range userSettings {
if setting.Key == storepb.UserSettingKey_LOCALE {
......@@ -357,12 +357,7 @@ func (s *APIV1Service) GetUserSetting(ctx context.Context, request *v1pb.GetUser
func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.UpdateUserSettingRequest) (*v1pb.UserSetting, error) {
// Extract user ID from the setting resource name
parts := strings.Split(request.Setting.Name, "/")
if len(parts) != 3 || parts[0] != "users" || parts[2] != "setting" {
return nil, status.Errorf(codes.InvalidArgument, "invalid setting name format: %s", request.Setting.Name)
}
userID, err := ExtractUserIDFromName(fmt.Sprintf("users/%s", parts[1]))
userID, err := ExtractUserIDFromName(request.Setting.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
}
......
......@@ -23,7 +23,6 @@ type APIV1Service struct {
grpc_health_v1.UnimplementedHealthServer
v1pb.UnimplementedWorkspaceServiceServer
v1pb.UnimplementedWorkspaceSettingServiceServer
v1pb.UnimplementedAuthServiceServer
v1pb.UnimplementedUserServiceServer
v1pb.UnimplementedMemoServiceServer
......@@ -52,7 +51,6 @@ func NewAPIV1Service(secret string, profile *profile.Profile, store *store.Store
}
grpc_health_v1.RegisterHealthServer(grpcServer, apiv1Service)
v1pb.RegisterWorkspaceServiceServer(grpcServer, apiv1Service)
v1pb.RegisterWorkspaceSettingServiceServer(grpcServer, apiv1Service)
v1pb.RegisterAuthServiceServer(grpcServer, apiv1Service)
v1pb.RegisterUserServiceServer(grpcServer, apiv1Service)
v1pb.RegisterMemoServiceServer(grpcServer, apiv1Service)
......@@ -88,9 +86,6 @@ func (s *APIV1Service) RegisterGateway(ctx context.Context, echoServer *echo.Ech
if err := v1pb.RegisterWorkspaceServiceHandler(ctx, gwMux, conn); err != nil {
return err
}
if err := v1pb.RegisterWorkspaceSettingServiceHandler(ctx, gwMux, conn); err != nil {
return err
}
if err := v1pb.RegisterAuthServiceHandler(ctx, gwMux, conn); err != nil {
return err
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,7 @@ import { toast } from "react-hot-toast";
import { workspaceSettingNamePrefix } from "@/store/common";
import { workspaceStore } from "@/store/v2";
import { WorkspaceSettingKey } from "@/store/v2/workspace";
import { WorkspaceMemoRelatedSetting } from "@/types/proto/api/v1/workspace_setting_service";
import { WorkspaceMemoRelatedSetting } from "@/types/proto/api/v1/workspace_service";
import { useTranslate } from "@/utils/i18n";
const MemoRelatedSettings = observer(() => {
......
......@@ -13,7 +13,7 @@ import {
WorkspaceStorageSetting,
WorkspaceStorageSetting_S3Config,
WorkspaceStorageSetting_StorageType,
} from "@/types/proto/api/v1/workspace_setting_service";
} from "@/types/proto/api/v1/workspace_service";
import { useTranslate } from "@/utils/i18n";
const StorageSection = observer(() => {
......
......@@ -11,7 +11,7 @@ import { workspaceSettingNamePrefix } from "@/store/common";
import { workspaceStore } from "@/store/v2";
import { WorkspaceSettingKey } from "@/store/v2/workspace";
import { IdentityProvider } from "@/types/proto/api/v1/idp_service";
import { WorkspaceGeneralSetting } from "@/types/proto/api/v1/workspace_setting_service";
import { WorkspaceGeneralSetting } from "@/types/proto/api/v1/workspace_service";
import { useTranslate } from "@/utils/i18n";
import showUpdateCustomizedProfileDialog from "../UpdateCustomizedProfileDialog";
......
......@@ -5,7 +5,7 @@ import { toast } from "react-hot-toast";
import { workspaceSettingNamePrefix } from "@/store/common";
import { workspaceStore } from "@/store/v2";
import { WorkspaceSettingKey } from "@/store/v2/workspace";
import { WorkspaceCustomProfile } from "@/types/proto/api/v1/workspace_setting_service";
import { WorkspaceCustomProfile } from "@/types/proto/api/v1/workspace_service";
import { useTranslate } from "@/utils/i18n";
import AppearanceSelect from "./AppearanceSelect";
import { generateDialog } from "./Dialog";
......
......@@ -10,7 +10,6 @@ import { ShortcutServiceDefinition } from "./types/proto/api/v1/shortcut_service
import { UserServiceDefinition } from "./types/proto/api/v1/user_service";
import { WebhookServiceDefinition } from "./types/proto/api/v1/webhook_service";
import { WorkspaceServiceDefinition } from "./types/proto/api/v1/workspace_service";
import { WorkspaceSettingServiceDefinition } from "./types/proto/api/v1/workspace_setting_service";
const channel = createChannel(
window.location.origin,
......@@ -23,8 +22,6 @@ const clientFactory = createClientFactory();
export const workspaceServiceClient = clientFactory.create(WorkspaceServiceDefinition, channel);
export const workspaceSettingServiceClient = clientFactory.create(WorkspaceSettingServiceDefinition, channel);
export const authServiceClient = clientFactory.create(AuthServiceDefinition, channel);
export const userServiceClient = clientFactory.create(UserServiceDefinition, channel);
......
export const workspaceSettingNamePrefix = "settings/";
export const workspaceSettingNamePrefix = "workspace/settings/";
export const userNamePrefix = "users/";
export const memoNamePrefix = "memos/";
export const identityProviderNamePrefix = "identityProviders/";
......
......@@ -134,7 +134,7 @@ const userStore = (() => {
// Ensure the setting has the proper resource name
const settingWithName = {
...userSetting,
name: `${state.currentUser}/setting`,
name: state.currentUser,
};
const updatedUserSetting = await userServiceClient.updateUserSetting({
setting: settingWithName,
......
import { uniqBy } from "lodash-es";
import { makeAutoObservable } from "mobx";
import { workspaceServiceClient, workspaceSettingServiceClient } from "@/grpcweb";
import { workspaceServiceClient } from "@/grpcweb";
import { WorkspaceProfile } from "@/types/proto/api/v1/workspace_service";
import { WorkspaceGeneralSetting, WorkspaceMemoRelatedSetting, WorkspaceSetting } from "@/types/proto/api/v1/workspace_setting_service";
import { WorkspaceGeneralSetting, WorkspaceMemoRelatedSetting, WorkspaceSetting } from "@/types/proto/api/v1/workspace_service";
import { isValidateLocale } from "@/utils/i18n";
import { workspaceSettingNamePrefix } from "../common";
......@@ -60,14 +60,14 @@ const workspaceStore = (() => {
const state = new LocalState();
const fetchWorkspaceSetting = async (settingKey: WorkspaceSettingKey) => {
const setting = await workspaceSettingServiceClient.getWorkspaceSetting({ name: `${workspaceSettingNamePrefix}${settingKey}` });
const setting = await workspaceServiceClient.getWorkspaceSetting({ name: `${workspaceSettingNamePrefix}${settingKey}` });
state.setPartial({
settings: uniqBy([setting, ...state.settings], "name"),
});
};
const upsertWorkspaceSetting = async (setting: WorkspaceSetting) => {
await workspaceSettingServiceClient.setWorkspaceSetting({ setting });
await workspaceServiceClient.updateWorkspaceSetting({ setting });
state.setPartial({
settings: uniqBy([setting, ...state.settings], "name"),
});
......
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