@@ -5,9 +5,11 @@ import (
55
66 "connectrpc.com/connect"
77 "golang.org/x/oauth2"
8+ "google.golang.org/protobuf/types/known/structpb"
89
910 clientsv1 "github.com/sourcegraph/sourcegraph-accounts-sdk-go/clients/v1"
1011 "github.com/sourcegraph/sourcegraph-accounts-sdk-go/clients/v1/clientsv1connect"
12+ "github.com/sourcegraph/sourcegraph/lib/errors"
1113)
1214
1315// UsersServiceV1 provides client methods to interact with the UsersService API
@@ -84,3 +86,57 @@ func (s *UsersServiceV1) GetUserRolesByID(ctx context.Context, userID, service s
8486 }
8587 return resp .Msg .GetUserRoles (), nil
8688}
89+
90+ // GetUserMetadata returns the metadata associated with the given user ID and
91+ // metadata namespaces.
92+ //
93+ // Required scopes: sams::user.metadata.${NAMESPACE}::read for each of the
94+ // requested namespaces.
95+ func (s * UsersServiceV1 ) GetUserMetadata (ctx context.Context , userID string , namespaces []string ) ([]* clientsv1.UserServiceMetadata , error ) {
96+ if userID == "" {
97+ return nil , errors .New ("user ID cannot be empty" )
98+ }
99+ if len (namespaces ) == 0 {
100+ return nil , errors .New ("at least one namespace must be provided" )
101+ }
102+
103+ req := & clientsv1.GetUserMetadataRequest {
104+ Id : userID ,
105+ Namespaces : namespaces ,
106+ }
107+ client := s .newClient (ctx )
108+ resp , err := parseResponseAndError (client .GetUserMetadata (ctx , connect .NewRequest (req )))
109+ if err != nil {
110+ return nil , err
111+ }
112+ return resp .Msg .GetMetadata (), nil
113+ }
114+
115+ // UpdateUserMetadata updates the metadata associated with the given user ID
116+ // and metadata namespace.
117+ //
118+ // Required scopes: sams::user.metadata.${NAMESPACE}::read for the namespace
119+ // being updated.
120+ func (s * UsersServiceV1 ) UpdateUserMetadata (ctx context.Context , userID , namespace string , metadata map [string ]any ) (* clientsv1.UserServiceMetadata , error ) {
121+ if userID == "" || namespace == "" {
122+ return nil , errors .New ("user ID and namespace cannot be empty" )
123+ }
124+
125+ md , err := structpb .NewStruct (metadata )
126+ if err != nil {
127+ return nil , errors .Wrap (err , "failed to marshal user metadata" )
128+ }
129+ req := & clientsv1.UpdateUserMetadataRequest {
130+ Metadata : & clientsv1.UserServiceMetadata {
131+ UserId : userID ,
132+ Namespace : namespace ,
133+ Metadata : md ,
134+ },
135+ }
136+ client := s .newClient (ctx )
137+ resp , err := parseResponseAndError (client .UpdateUserMetadata (ctx , connect .NewRequest (req )))
138+ if err != nil {
139+ return nil , err
140+ }
141+ return resp .Msg .GetMetadata (), nil
142+ }
0 commit comments