Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
14c72fa7
Commit
14c72fa7
authored
Feb 02, 2025
by
johnnyjoy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: implement shortcuts
parent
b9a0c561
Changes
9
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1739 additions
and
215 deletions
+1739
-215
user_service.proto
proto/api/v1/user_service.proto
+65
-0
user_service.pb.go
proto/gen/api/v1/user_service.pb.go
+588
-182
user_service.pb.gw.go
proto/gen/api/v1/user_service.pb.gw.go
+380
-0
user_service_grpc.pb.go
proto/gen/api/v1/user_service_grpc.pb.go
+160
-0
apidocs.swagger.yaml
proto/gen/apidocs.swagger.yaml
+129
-0
user_setting.pb.go
proto/gen/store/user_setting.pb.go
+178
-33
user_setting.proto
proto/store/user_setting.proto
+12
-0
user_service_shortcuts.go
server/router/api/v1/user_service_shortcuts.go
+214
-0
user_setting.go
store/user_setting.go
+13
-0
No files found.
proto/api/v1/user_service.proto
View file @
14c72fa7
...
...
@@ -94,6 +94,32 @@ service UserService {
option
(
google.api.http
)
=
{
delete
:
"/api/v1/{name=users/*}/access_tokens/{access_token}"
};
option
(
google.api.method_signature
)
=
"name,access_token"
;
}
// ListShortcuts returns a list of shortcuts for a user.
rpc
ListShortcuts
(
ListShortcutsRequest
)
returns
(
ListShortcutsResponse
)
{
option
(
google.api.http
)
=
{
get
:
"/api/v1/{parent=users/*}/shortcuts"
};
option
(
google.api.method_signature
)
=
"parent"
;
}
// CreateShortcut creates a new shortcut for a user.
rpc
CreateShortcut
(
CreateShortcutRequest
)
returns
(
Shortcut
)
{
option
(
google.api.http
)
=
{
post
:
"/api/v1/{parent=users/*}/shortcuts"
body
:
"shortcut"
};
option
(
google.api.method_signature
)
=
"parent,shortcut"
;
}
// UpdateShortcut updates a shortcut for a user.
rpc
UpdateShortcut
(
UpdateShortcutRequest
)
returns
(
Shortcut
)
{
option
(
google.api.http
)
=
{
patch
:
"/api/v1/{parent=users/*}/shortcuts/{shortcut.id}"
body
:
"shortcut"
};
option
(
google.api.method_signature
)
=
"parent,shortcut,update_mask"
;
}
// DeleteShortcut deletes a shortcut for a user.
rpc
DeleteShortcut
(
DeleteShortcutRequest
)
returns
(
google.protobuf.Empty
)
{
option
(
google.api.http
)
=
{
delete
:
"/api/v1/{parent=users/*}/shortcuts/{id}"
};
option
(
google.api.method_signature
)
=
"parent,id"
;
}
}
message
User
{
...
...
@@ -254,3 +280,42 @@ message DeleteUserAccessTokenRequest {
// access_token is the access token to delete.
string
access_token
=
2
;
}
message
Shortcut
{
string
id
=
1
;
string
title
=
2
;
string
filter
=
3
;
}
message
ListShortcutsRequest
{
// The name of the user.
string
parent
=
1
;
}
message
ListShortcutsResponse
{
repeated
Shortcut
shortcuts
=
1
;
}
message
CreateShortcutRequest
{
// The name of the user.
string
parent
=
1
;
Shortcut
shortcut
=
2
;
}
message
UpdateShortcutRequest
{
// The name of the user.
string
parent
=
1
;
Shortcut
shortcut
=
2
;
google.protobuf.FieldMask
update_mask
=
3
;
}
message
DeleteShortcutRequest
{
// The name of the user.
string
parent
=
1
;
// The id of the shortcut.
string
id
=
2
;
}
proto/gen/api/v1/user_service.pb.go
View file @
14c72fa7
This diff is collapsed.
Click to expand it.
proto/gen/api/v1/user_service.pb.gw.go
View file @
14c72fa7
This diff is collapsed.
Click to expand it.
proto/gen/api/v1/user_service_grpc.pb.go
View file @
14c72fa7
...
...
@@ -35,6 +35,10 @@ const (
UserService_ListUserAccessTokens_FullMethodName
=
"/memos.api.v1.UserService/ListUserAccessTokens"
UserService_CreateUserAccessToken_FullMethodName
=
"/memos.api.v1.UserService/CreateUserAccessToken"
UserService_DeleteUserAccessToken_FullMethodName
=
"/memos.api.v1.UserService/DeleteUserAccessToken"
UserService_ListShortcuts_FullMethodName
=
"/memos.api.v1.UserService/ListShortcuts"
UserService_CreateShortcut_FullMethodName
=
"/memos.api.v1.UserService/CreateShortcut"
UserService_UpdateShortcut_FullMethodName
=
"/memos.api.v1.UserService/UpdateShortcut"
UserService_DeleteShortcut_FullMethodName
=
"/memos.api.v1.UserService/DeleteShortcut"
)
// UserServiceClient is the client API for UserService service.
...
...
@@ -69,6 +73,14 @@ type UserServiceClient interface {
CreateUserAccessToken
(
ctx
context
.
Context
,
in
*
CreateUserAccessTokenRequest
,
opts
...
grpc
.
CallOption
)
(
*
UserAccessToken
,
error
)
// DeleteUserAccessToken deletes an access token for a user.
DeleteUserAccessToken
(
ctx
context
.
Context
,
in
*
DeleteUserAccessTokenRequest
,
opts
...
grpc
.
CallOption
)
(
*
emptypb
.
Empty
,
error
)
// ListShortcuts returns a list of shortcuts for a user.
ListShortcuts
(
ctx
context
.
Context
,
in
*
ListShortcutsRequest
,
opts
...
grpc
.
CallOption
)
(
*
ListShortcutsResponse
,
error
)
// CreateShortcut creates a new shortcut for a user.
CreateShortcut
(
ctx
context
.
Context
,
in
*
CreateShortcutRequest
,
opts
...
grpc
.
CallOption
)
(
*
Shortcut
,
error
)
// UpdateShortcut updates a shortcut for a user.
UpdateShortcut
(
ctx
context
.
Context
,
in
*
UpdateShortcutRequest
,
opts
...
grpc
.
CallOption
)
(
*
Shortcut
,
error
)
// DeleteShortcut deletes a shortcut for a user.
DeleteShortcut
(
ctx
context
.
Context
,
in
*
DeleteShortcutRequest
,
opts
...
grpc
.
CallOption
)
(
*
emptypb
.
Empty
,
error
)
}
type
userServiceClient
struct
{
...
...
@@ -219,6 +231,46 @@ func (c *userServiceClient) DeleteUserAccessToken(ctx context.Context, in *Delet
return
out
,
nil
}
func
(
c
*
userServiceClient
)
ListShortcuts
(
ctx
context
.
Context
,
in
*
ListShortcutsRequest
,
opts
...
grpc
.
CallOption
)
(
*
ListShortcutsResponse
,
error
)
{
cOpts
:=
append
([]
grpc
.
CallOption
{
grpc
.
StaticMethod
()},
opts
...
)
out
:=
new
(
ListShortcutsResponse
)
err
:=
c
.
cc
.
Invoke
(
ctx
,
UserService_ListShortcuts_FullMethodName
,
in
,
out
,
cOpts
...
)
if
err
!=
nil
{
return
nil
,
err
}
return
out
,
nil
}
func
(
c
*
userServiceClient
)
CreateShortcut
(
ctx
context
.
Context
,
in
*
CreateShortcutRequest
,
opts
...
grpc
.
CallOption
)
(
*
Shortcut
,
error
)
{
cOpts
:=
append
([]
grpc
.
CallOption
{
grpc
.
StaticMethod
()},
opts
...
)
out
:=
new
(
Shortcut
)
err
:=
c
.
cc
.
Invoke
(
ctx
,
UserService_CreateShortcut_FullMethodName
,
in
,
out
,
cOpts
...
)
if
err
!=
nil
{
return
nil
,
err
}
return
out
,
nil
}
func
(
c
*
userServiceClient
)
UpdateShortcut
(
ctx
context
.
Context
,
in
*
UpdateShortcutRequest
,
opts
...
grpc
.
CallOption
)
(
*
Shortcut
,
error
)
{
cOpts
:=
append
([]
grpc
.
CallOption
{
grpc
.
StaticMethod
()},
opts
...
)
out
:=
new
(
Shortcut
)
err
:=
c
.
cc
.
Invoke
(
ctx
,
UserService_UpdateShortcut_FullMethodName
,
in
,
out
,
cOpts
...
)
if
err
!=
nil
{
return
nil
,
err
}
return
out
,
nil
}
func
(
c
*
userServiceClient
)
DeleteShortcut
(
ctx
context
.
Context
,
in
*
DeleteShortcutRequest
,
opts
...
grpc
.
CallOption
)
(
*
emptypb
.
Empty
,
error
)
{
cOpts
:=
append
([]
grpc
.
CallOption
{
grpc
.
StaticMethod
()},
opts
...
)
out
:=
new
(
emptypb
.
Empty
)
err
:=
c
.
cc
.
Invoke
(
ctx
,
UserService_DeleteShortcut_FullMethodName
,
in
,
out
,
cOpts
...
)
if
err
!=
nil
{
return
nil
,
err
}
return
out
,
nil
}
// UserServiceServer is the server API for UserService service.
// All implementations must embed UnimplementedUserServiceServer
// for forward compatibility.
...
...
@@ -251,6 +303,14 @@ type UserServiceServer interface {
CreateUserAccessToken
(
context
.
Context
,
*
CreateUserAccessTokenRequest
)
(
*
UserAccessToken
,
error
)
// DeleteUserAccessToken deletes an access token for a user.
DeleteUserAccessToken
(
context
.
Context
,
*
DeleteUserAccessTokenRequest
)
(
*
emptypb
.
Empty
,
error
)
// ListShortcuts returns a list of shortcuts for a user.
ListShortcuts
(
context
.
Context
,
*
ListShortcutsRequest
)
(
*
ListShortcutsResponse
,
error
)
// CreateShortcut creates a new shortcut for a user.
CreateShortcut
(
context
.
Context
,
*
CreateShortcutRequest
)
(
*
Shortcut
,
error
)
// UpdateShortcut updates a shortcut for a user.
UpdateShortcut
(
context
.
Context
,
*
UpdateShortcutRequest
)
(
*
Shortcut
,
error
)
// DeleteShortcut deletes a shortcut for a user.
DeleteShortcut
(
context
.
Context
,
*
DeleteShortcutRequest
)
(
*
emptypb
.
Empty
,
error
)
mustEmbedUnimplementedUserServiceServer
()
}
...
...
@@ -303,6 +363,18 @@ func (UnimplementedUserServiceServer) CreateUserAccessToken(context.Context, *Cr
func
(
UnimplementedUserServiceServer
)
DeleteUserAccessToken
(
context
.
Context
,
*
DeleteUserAccessTokenRequest
)
(
*
emptypb
.
Empty
,
error
)
{
return
nil
,
status
.
Errorf
(
codes
.
Unimplemented
,
"method DeleteUserAccessToken not implemented"
)
}
func
(
UnimplementedUserServiceServer
)
ListShortcuts
(
context
.
Context
,
*
ListShortcutsRequest
)
(
*
ListShortcutsResponse
,
error
)
{
return
nil
,
status
.
Errorf
(
codes
.
Unimplemented
,
"method ListShortcuts not implemented"
)
}
func
(
UnimplementedUserServiceServer
)
CreateShortcut
(
context
.
Context
,
*
CreateShortcutRequest
)
(
*
Shortcut
,
error
)
{
return
nil
,
status
.
Errorf
(
codes
.
Unimplemented
,
"method CreateShortcut not implemented"
)
}
func
(
UnimplementedUserServiceServer
)
UpdateShortcut
(
context
.
Context
,
*
UpdateShortcutRequest
)
(
*
Shortcut
,
error
)
{
return
nil
,
status
.
Errorf
(
codes
.
Unimplemented
,
"method UpdateShortcut not implemented"
)
}
func
(
UnimplementedUserServiceServer
)
DeleteShortcut
(
context
.
Context
,
*
DeleteShortcutRequest
)
(
*
emptypb
.
Empty
,
error
)
{
return
nil
,
status
.
Errorf
(
codes
.
Unimplemented
,
"method DeleteShortcut not implemented"
)
}
func
(
UnimplementedUserServiceServer
)
mustEmbedUnimplementedUserServiceServer
()
{}
func
(
UnimplementedUserServiceServer
)
testEmbeddedByValue
()
{}
...
...
@@ -576,6 +648,78 @@ func _UserService_DeleteUserAccessToken_Handler(srv interface{}, ctx context.Con
return
interceptor
(
ctx
,
in
,
info
,
handler
)
}
func
_UserService_ListShortcuts_Handler
(
srv
interface
{},
ctx
context
.
Context
,
dec
func
(
interface
{})
error
,
interceptor
grpc
.
UnaryServerInterceptor
)
(
interface
{},
error
)
{
in
:=
new
(
ListShortcutsRequest
)
if
err
:=
dec
(
in
);
err
!=
nil
{
return
nil
,
err
}
if
interceptor
==
nil
{
return
srv
.
(
UserServiceServer
)
.
ListShortcuts
(
ctx
,
in
)
}
info
:=
&
grpc
.
UnaryServerInfo
{
Server
:
srv
,
FullMethod
:
UserService_ListShortcuts_FullMethodName
,
}
handler
:=
func
(
ctx
context
.
Context
,
req
interface
{})
(
interface
{},
error
)
{
return
srv
.
(
UserServiceServer
)
.
ListShortcuts
(
ctx
,
req
.
(
*
ListShortcutsRequest
))
}
return
interceptor
(
ctx
,
in
,
info
,
handler
)
}
func
_UserService_CreateShortcut_Handler
(
srv
interface
{},
ctx
context
.
Context
,
dec
func
(
interface
{})
error
,
interceptor
grpc
.
UnaryServerInterceptor
)
(
interface
{},
error
)
{
in
:=
new
(
CreateShortcutRequest
)
if
err
:=
dec
(
in
);
err
!=
nil
{
return
nil
,
err
}
if
interceptor
==
nil
{
return
srv
.
(
UserServiceServer
)
.
CreateShortcut
(
ctx
,
in
)
}
info
:=
&
grpc
.
UnaryServerInfo
{
Server
:
srv
,
FullMethod
:
UserService_CreateShortcut_FullMethodName
,
}
handler
:=
func
(
ctx
context
.
Context
,
req
interface
{})
(
interface
{},
error
)
{
return
srv
.
(
UserServiceServer
)
.
CreateShortcut
(
ctx
,
req
.
(
*
CreateShortcutRequest
))
}
return
interceptor
(
ctx
,
in
,
info
,
handler
)
}
func
_UserService_UpdateShortcut_Handler
(
srv
interface
{},
ctx
context
.
Context
,
dec
func
(
interface
{})
error
,
interceptor
grpc
.
UnaryServerInterceptor
)
(
interface
{},
error
)
{
in
:=
new
(
UpdateShortcutRequest
)
if
err
:=
dec
(
in
);
err
!=
nil
{
return
nil
,
err
}
if
interceptor
==
nil
{
return
srv
.
(
UserServiceServer
)
.
UpdateShortcut
(
ctx
,
in
)
}
info
:=
&
grpc
.
UnaryServerInfo
{
Server
:
srv
,
FullMethod
:
UserService_UpdateShortcut_FullMethodName
,
}
handler
:=
func
(
ctx
context
.
Context
,
req
interface
{})
(
interface
{},
error
)
{
return
srv
.
(
UserServiceServer
)
.
UpdateShortcut
(
ctx
,
req
.
(
*
UpdateShortcutRequest
))
}
return
interceptor
(
ctx
,
in
,
info
,
handler
)
}
func
_UserService_DeleteShortcut_Handler
(
srv
interface
{},
ctx
context
.
Context
,
dec
func
(
interface
{})
error
,
interceptor
grpc
.
UnaryServerInterceptor
)
(
interface
{},
error
)
{
in
:=
new
(
DeleteShortcutRequest
)
if
err
:=
dec
(
in
);
err
!=
nil
{
return
nil
,
err
}
if
interceptor
==
nil
{
return
srv
.
(
UserServiceServer
)
.
DeleteShortcut
(
ctx
,
in
)
}
info
:=
&
grpc
.
UnaryServerInfo
{
Server
:
srv
,
FullMethod
:
UserService_DeleteShortcut_FullMethodName
,
}
handler
:=
func
(
ctx
context
.
Context
,
req
interface
{})
(
interface
{},
error
)
{
return
srv
.
(
UserServiceServer
)
.
DeleteShortcut
(
ctx
,
req
.
(
*
DeleteShortcutRequest
))
}
return
interceptor
(
ctx
,
in
,
info
,
handler
)
}
// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
...
...
@@ -639,6 +783,22 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
MethodName
:
"DeleteUserAccessToken"
,
Handler
:
_UserService_DeleteUserAccessToken_Handler
,
},
{
MethodName
:
"ListShortcuts"
,
Handler
:
_UserService_ListShortcuts_Handler
,
},
{
MethodName
:
"CreateShortcut"
,
Handler
:
_UserService_CreateShortcut_Handler
,
},
{
MethodName
:
"UpdateShortcut"
,
Handler
:
_UserService_UpdateShortcut_Handler
,
},
{
MethodName
:
"DeleteShortcut"
,
Handler
:
_UserService_DeleteShortcut_Handler
,
},
},
Streams
:
[]
grpc
.
StreamDesc
{},
Metadata
:
"api/v1/user_service.proto"
,
...
...
proto/gen/apidocs.swagger.yaml
View file @
14c72fa7
...
...
@@ -1406,6 +1406,118 @@ paths:
pattern
:
users/[^/]+
tags
:
-
UserService
/api/v1/{parent}/shortcuts
:
get
:
summary
:
ListShortcuts returns a list of shortcuts for a user.
operationId
:
UserService_ListShortcuts
responses
:
"
200"
:
description
:
A successful response.
schema
:
$ref
:
'
#/definitions/v1ListShortcutsResponse'
default
:
description
:
An unexpected error response.
schema
:
$ref
:
'
#/definitions/googlerpcStatus'
parameters
:
-
name
:
parent
description
:
The name of the user.
in
:
path
required
:
true
type
:
string
pattern
:
users/[^/]+
tags
:
-
UserService
post
:
summary
:
CreateShortcut creates a new shortcut for a user.
operationId
:
UserService_CreateShortcut
responses
:
"
200"
:
description
:
A successful response.
schema
:
$ref
:
'
#/definitions/apiv1Shortcut'
default
:
description
:
An unexpected error response.
schema
:
$ref
:
'
#/definitions/googlerpcStatus'
parameters
:
-
name
:
parent
description
:
The name of the user.
in
:
path
required
:
true
type
:
string
pattern
:
users/[^/]+
-
name
:
shortcut
in
:
body
required
:
true
schema
:
$ref
:
'
#/definitions/apiv1Shortcut'
tags
:
-
UserService
/api/v1/{parent}/shortcuts/{id}
:
delete
:
summary
:
DeleteShortcut deletes a shortcut for a user.
operationId
:
UserService_DeleteShortcut
responses
:
"
200"
:
description
:
A successful response.
schema
:
type
:
object
properties
:
{}
default
:
description
:
An unexpected error response.
schema
:
$ref
:
'
#/definitions/googlerpcStatus'
parameters
:
-
name
:
parent
description
:
The name of the user.
in
:
path
required
:
true
type
:
string
pattern
:
users/[^/]+
-
name
:
id
description
:
The id of the shortcut.
in
:
path
required
:
true
type
:
string
tags
:
-
UserService
/api/v1/{parent}/shortcuts/{shortcut.id}
:
patch
:
summary
:
UpdateShortcut updates a shortcut for a user.
operationId
:
UserService_UpdateShortcut
responses
:
"
200"
:
description
:
A successful response.
schema
:
$ref
:
'
#/definitions/apiv1Shortcut'
default
:
description
:
An unexpected error response.
schema
:
$ref
:
'
#/definitions/googlerpcStatus'
parameters
:
-
name
:
parent
description
:
The name of the user.
in
:
path
required
:
true
type
:
string
pattern
:
users/[^/]+
-
name
:
shortcut.id
in
:
path
required
:
true
type
:
string
-
name
:
shortcut
in
:
body
required
:
true
schema
:
type
:
object
properties
:
title
:
type
:
string
filter
:
type
:
string
tags
:
-
UserService
/api/v1/{parent}/tags/{tag}
:
delete
:
summary
:
DeleteMemoTag deletes a tag for a memo.
...
...
@@ -1997,6 +2109,15 @@ definitions:
type
:
string
fieldMapping
:
$ref
:
'
#/definitions/apiv1FieldMapping'
apiv1Shortcut
:
type
:
object
properties
:
id
:
type
:
string
title
:
type
:
string
filter
:
type
:
string
apiv1UserSetting
:
type
:
object
properties
:
...
...
@@ -2558,6 +2679,14 @@ definitions:
items
:
type
:
object
$ref
:
'
#/definitions/v1Resource'
v1ListShortcutsResponse
:
type
:
object
properties
:
shortcuts
:
type
:
array
items
:
type
:
object
$ref
:
'
#/definitions/apiv1Shortcut'
v1ListUserAccessTokensResponse
:
type
:
object
properties
:
...
...
proto/gen/store/user_setting.pb.go
View file @
14c72fa7
This diff is collapsed.
Click to expand it.
proto/store/user_setting.proto
View file @
14c72fa7
...
...
@@ -14,6 +14,8 @@ enum UserSettingKey {
APPEARANCE
=
3
;
// The visibility of the memo.
MEMO_VISIBILITY
=
4
;
// The shortcuts of the user.
SHORTCUTS
=
5
;
}
message
UserSetting
{
...
...
@@ -24,6 +26,7 @@ message UserSetting {
string
locale
=
4
;
string
appearance
=
5
;
string
memo_visibility
=
6
;
ShortcutsUserSetting
shortcuts
=
7
;
}
}
...
...
@@ -37,3 +40,12 @@ message AccessTokensUserSetting {
}
repeated
AccessToken
access_tokens
=
1
;
}
message
ShortcutsUserSetting
{
message
Shortcut
{
string
id
=
1
;
string
title
=
2
;
string
filter
=
3
;
}
repeated
Shortcut
shortcuts
=
1
;
}
server/router/api/v1/user_service_shortcuts.go
0 → 100644
View file @
14c72fa7
package
v1
import
(
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
v1pb
"github.com/usememos/memos/proto/gen/api/v1"
storepb
"github.com/usememos/memos/proto/gen/store"
"github.com/usememos/memos/store"
)
func
(
s
*
APIV1Service
)
ListShortcuts
(
ctx
context
.
Context
,
request
*
v1pb
.
ListShortcutsRequest
)
(
*
v1pb
.
ListShortcutsResponse
,
error
)
{
userID
,
err
:=
ExtractUserIDFromName
(
request
.
Parent
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"invalid user name: %v"
,
err
)
}
currentUser
,
err
:=
s
.
GetCurrentUser
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get current user: %v"
,
err
)
}
if
currentUser
==
nil
||
currentUser
.
ID
!=
userID
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
"permission denied"
)
}
userSetting
,
err
:=
s
.
Store
.
GetUserSetting
(
ctx
,
&
store
.
FindUserSetting
{
UserID
:
&
userID
,
Key
:
storepb
.
UserSettingKey_SHORTCUTS
,
})
if
err
!=
nil
{
return
nil
,
err
}
if
userSetting
==
nil
{
return
&
v1pb
.
ListShortcutsResponse
{
Shortcuts
:
[]
*
v1pb
.
Shortcut
{},
},
nil
}
shortcutsUserSetting
:=
userSetting
.
GetShortcuts
()
shortcuts
:=
[]
*
v1pb
.
Shortcut
{}
for
_
,
shortcut
:=
range
shortcutsUserSetting
.
GetShortcuts
()
{
shortcuts
=
append
(
shortcuts
,
&
v1pb
.
Shortcut
{
Id
:
shortcut
.
GetId
(),
Title
:
shortcut
.
GetTitle
(),
Filter
:
shortcut
.
GetFilter
(),
})
}
return
&
v1pb
.
ListShortcutsResponse
{
Shortcuts
:
shortcuts
,
},
nil
}
func
(
s
*
APIV1Service
)
CreateShortcut
(
ctx
context
.
Context
,
request
*
v1pb
.
CreateShortcutRequest
)
(
*
v1pb
.
Shortcut
,
error
)
{
userID
,
err
:=
ExtractUserIDFromName
(
request
.
Parent
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"invalid user name: %v"
,
err
)
}
currentUser
,
err
:=
s
.
GetCurrentUser
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get current user: %v"
,
err
)
}
if
currentUser
==
nil
||
currentUser
.
ID
!=
userID
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
"permission denied"
)
}
userSetting
,
err
:=
s
.
Store
.
GetUserSetting
(
ctx
,
&
store
.
FindUserSetting
{
UserID
:
&
userID
,
Key
:
storepb
.
UserSettingKey_SHORTCUTS
,
})
if
err
!=
nil
{
return
nil
,
err
}
if
userSetting
==
nil
{
userSetting
=
&
storepb
.
UserSetting
{
UserId
:
userID
,
Key
:
storepb
.
UserSettingKey_SHORTCUTS
,
Value
:
&
storepb
.
UserSetting_Shortcuts
{},
}
}
shortcutsUserSetting
:=
userSetting
.
GetShortcuts
()
shortcuts
:=
shortcutsUserSetting
.
GetShortcuts
()
shortcuts
=
append
(
shortcuts
,
&
storepb
.
ShortcutsUserSetting_Shortcut
{
Id
:
request
.
Shortcut
.
GetId
(),
Title
:
request
.
Shortcut
.
GetTitle
(),
Filter
:
request
.
Shortcut
.
GetFilter
(),
})
shortcutsUserSetting
.
Shortcuts
=
shortcuts
userSetting
.
Value
=
&
storepb
.
UserSetting_Shortcuts
{
Shortcuts
:
shortcutsUserSetting
,
}
_
,
err
=
s
.
Store
.
UpsertUserSetting
(
ctx
,
userSetting
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
v1pb
.
Shortcut
{
Id
:
request
.
Shortcut
.
GetId
(),
Title
:
request
.
Shortcut
.
GetTitle
(),
Filter
:
request
.
Shortcut
.
GetFilter
(),
},
nil
}
func
(
s
*
APIV1Service
)
UpdateShortcut
(
ctx
context
.
Context
,
request
*
v1pb
.
UpdateShortcutRequest
)
(
*
v1pb
.
Shortcut
,
error
)
{
userID
,
err
:=
ExtractUserIDFromName
(
request
.
Parent
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"invalid user name: %v"
,
err
)
}
currentUser
,
err
:=
s
.
GetCurrentUser
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get current user: %v"
,
err
)
}
if
currentUser
==
nil
||
currentUser
.
ID
!=
userID
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
"permission denied"
)
}
if
request
.
UpdateMask
==
nil
||
len
(
request
.
UpdateMask
.
Paths
)
==
0
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"update mask is required"
)
}
userSetting
,
err
:=
s
.
Store
.
GetUserSetting
(
ctx
,
&
store
.
FindUserSetting
{
UserID
:
&
userID
,
Key
:
storepb
.
UserSettingKey_SHORTCUTS
,
})
if
err
!=
nil
{
return
nil
,
err
}
if
userSetting
==
nil
{
return
nil
,
status
.
Errorf
(
codes
.
NotFound
,
"shortcut not found"
)
}
shortcutsUserSetting
:=
userSetting
.
GetShortcuts
()
shortcuts
:=
shortcutsUserSetting
.
GetShortcuts
()
newShortcuts
:=
make
([]
*
storepb
.
ShortcutsUserSetting_Shortcut
,
0
,
len
(
shortcuts
))
for
_
,
shortcut
:=
range
shortcuts
{
if
shortcut
.
GetId
()
==
request
.
Shortcut
.
GetId
()
{
for
_
,
field
:=
range
request
.
UpdateMask
.
Paths
{
if
field
==
"title"
{
shortcut
.
Title
=
request
.
Shortcut
.
GetTitle
()
}
else
if
field
==
"filter"
{
shortcut
.
Filter
=
request
.
Shortcut
.
GetFilter
()
}
}
}
newShortcuts
=
append
(
newShortcuts
,
shortcut
)
}
shortcutsUserSetting
.
Shortcuts
=
newShortcuts
userSetting
.
Value
=
&
storepb
.
UserSetting_Shortcuts
{
Shortcuts
:
shortcutsUserSetting
,
}
_
,
err
=
s
.
Store
.
UpsertUserSetting
(
ctx
,
userSetting
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
v1pb
.
Shortcut
{
Id
:
request
.
Shortcut
.
GetId
(),
Title
:
request
.
Shortcut
.
GetTitle
(),
Filter
:
request
.
Shortcut
.
GetFilter
(),
},
nil
}
func
(
s
*
APIV1Service
)
DeleteShortcut
(
ctx
context
.
Context
,
request
*
v1pb
.
DeleteShortcutRequest
)
(
*
emptypb
.
Empty
,
error
)
{
userID
,
err
:=
ExtractUserIDFromName
(
request
.
Parent
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"invalid user name: %v"
,
err
)
}
currentUser
,
err
:=
s
.
GetCurrentUser
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get current user: %v"
,
err
)
}
if
currentUser
==
nil
||
currentUser
.
ID
!=
userID
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
"permission denied"
)
}
userSetting
,
err
:=
s
.
Store
.
GetUserSetting
(
ctx
,
&
store
.
FindUserSetting
{
UserID
:
&
userID
,
Key
:
storepb
.
UserSettingKey_SHORTCUTS
,
})
if
err
!=
nil
{
return
nil
,
err
}
if
userSetting
==
nil
{
return
&
emptypb
.
Empty
{},
nil
}
shortcutsUserSetting
:=
userSetting
.
GetShortcuts
()
shortcuts
:=
shortcutsUserSetting
.
GetShortcuts
()
newShortcuts
:=
make
([]
*
storepb
.
ShortcutsUserSetting_Shortcut
,
0
,
len
(
shortcuts
))
for
_
,
shortcut
:=
range
shortcuts
{
if
shortcut
.
GetId
()
!=
request
.
Id
{
newShortcuts
=
append
(
newShortcuts
,
shortcut
)
}
}
shortcutsUserSetting
.
Shortcuts
=
newShortcuts
userSetting
.
Value
=
&
storepb
.
UserSetting_Shortcuts
{
Shortcuts
:
shortcutsUserSetting
,
}
_
,
err
=
s
.
Store
.
UpsertUserSetting
(
ctx
,
userSetting
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
emptypb
.
Empty
{},
nil
}
store/user_setting.go
View file @
14c72fa7
...
...
@@ -145,6 +145,12 @@ func convertUserSettingFromRaw(raw *UserSetting) (*storepb.UserSetting, error) {
return
nil
,
err
}
userSetting
.
Value
=
&
storepb
.
UserSetting_AccessTokens
{
AccessTokens
:
accessTokensUserSetting
}
case
storepb
.
UserSettingKey_SHORTCUTS
:
shortcutsUserSetting
:=
&
storepb
.
ShortcutsUserSetting
{}
if
err
:=
protojsonUnmarshaler
.
Unmarshal
([]
byte
(
raw
.
Value
),
shortcutsUserSetting
);
err
!=
nil
{
return
nil
,
err
}
userSetting
.
Value
=
&
storepb
.
UserSetting_Shortcuts
{
Shortcuts
:
shortcutsUserSetting
}
case
storepb
.
UserSettingKey_LOCALE
:
userSetting
.
Value
=
&
storepb
.
UserSetting_Locale
{
Locale
:
raw
.
Value
}
case
storepb
.
UserSettingKey_APPEARANCE
:
...
...
@@ -171,6 +177,13 @@ func convertUserSettingToRaw(userSetting *storepb.UserSetting) (*UserSetting, er
return
nil
,
err
}
raw
.
Value
=
string
(
value
)
case
storepb
.
UserSettingKey_SHORTCUTS
:
shortcutsUserSetting
:=
userSetting
.
GetShortcuts
()
value
,
err
:=
protojson
.
Marshal
(
shortcutsUserSetting
)
if
err
!=
nil
{
return
nil
,
err
}
raw
.
Value
=
string
(
value
)
case
storepb
.
UserSettingKey_LOCALE
:
raw
.
Value
=
userSetting
.
GetLocale
()
case
storepb
.
UserSettingKey_APPEARANCE
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment