github.com/cs3org/reva/v2@v2.27.7/internal/grpc/services/userprovider/userprovider.go (about) 1 // Copyright 2018-2021 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package userprovider 20 21 import ( 22 "context" 23 "fmt" 24 "path/filepath" 25 "sort" 26 27 userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" 28 "github.com/cs3org/reva/v2/pkg/appctx" 29 "github.com/cs3org/reva/v2/pkg/errtypes" 30 "github.com/cs3org/reva/v2/pkg/plugin" 31 "github.com/cs3org/reva/v2/pkg/rgrpc" 32 "github.com/cs3org/reva/v2/pkg/rgrpc/status" 33 "github.com/cs3org/reva/v2/pkg/user" 34 "github.com/cs3org/reva/v2/pkg/user/manager/registry" 35 "github.com/mitchellh/mapstructure" 36 "github.com/pkg/errors" 37 "github.com/rs/zerolog" 38 "google.golang.org/grpc" 39 ) 40 41 func init() { 42 rgrpc.Register("userprovider", New) 43 } 44 45 type config struct { 46 Driver string `mapstructure:"driver"` 47 Drivers map[string]map[string]interface{} `mapstructure:"drivers"` 48 } 49 50 func (c *config) init() { 51 if c.Driver == "" { 52 c.Driver = "json" 53 } 54 } 55 56 func parseConfig(m map[string]interface{}) (*config, error) { 57 c := &config{} 58 if err := mapstructure.Decode(m, c); err != nil { 59 err = errors.Wrap(err, "error decoding conf") 60 return nil, err 61 } 62 c.init() 63 return c, nil 64 } 65 66 func getDriver(c *config) (user.Manager, *plugin.RevaPlugin, error) { 67 p, err := plugin.Load("userprovider", c.Driver) 68 if err == nil { 69 manager, ok := p.Plugin.(user.Manager) 70 if !ok { 71 return nil, nil, fmt.Errorf("could not assert the loaded plugin") 72 } 73 pluginConfig := filepath.Base(c.Driver) 74 err = manager.Configure(c.Drivers[pluginConfig]) 75 if err != nil { 76 return nil, nil, err 77 } 78 return manager, p, nil 79 } else if _, ok := err.(errtypes.NotFound); ok { 80 // plugin not found, fetch the driver from the in-memory registry 81 if f, ok := registry.NewFuncs[c.Driver]; ok { 82 mgr, err := f(c.Drivers[c.Driver]) 83 return mgr, nil, err 84 } 85 } else { 86 return nil, nil, err 87 } 88 return nil, nil, errtypes.NotFound(fmt.Sprintf("driver %s not found for user manager", c.Driver)) 89 } 90 91 // New returns a new UserProviderServiceServer. 92 func New(m map[string]interface{}, ss *grpc.Server, _ *zerolog.Logger) (rgrpc.Service, error) { 93 c, err := parseConfig(m) 94 if err != nil { 95 return nil, err 96 } 97 userManager, plug, err := getDriver(c) 98 if err != nil { 99 return nil, err 100 } 101 svc := &service{ 102 usermgr: userManager, 103 plugin: plug, 104 } 105 106 return svc, nil 107 } 108 109 type service struct { 110 usermgr user.Manager 111 plugin *plugin.RevaPlugin 112 } 113 114 func (s *service) Close() error { 115 if s.plugin != nil { 116 s.plugin.Kill() 117 } 118 return nil 119 } 120 121 func (s *service) UnprotectedEndpoints() []string { 122 return []string{"/cs3.identity.user.v1beta1.UserAPI/GetUser", "/cs3.identity.user.v1beta1.UserAPI/GetUserByClaim", "/cs3.identity.user.v1beta1.UserAPI/GetUserGroups"} 123 } 124 125 func (s *service) Register(ss *grpc.Server) { 126 userpb.RegisterUserAPIServer(ss, s) 127 } 128 129 func (s *service) GetUser(ctx context.Context, req *userpb.GetUserRequest) (*userpb.GetUserResponse, error) { 130 if req.UserId == nil { 131 res := &userpb.GetUserResponse{ 132 Status: status.NewInvalid(ctx, "userid missing"), 133 } 134 return res, nil 135 } 136 137 user, err := s.usermgr.GetUser(ctx, req.UserId, req.SkipFetchingUserGroups) 138 if err != nil { 139 res := &userpb.GetUserResponse{} 140 if _, ok := err.(errtypes.NotFound); ok { 141 res.Status = status.NewNotFound(ctx, "user not found") 142 } else { 143 res.Status = status.NewInternal(ctx, "error getting user") 144 } 145 return res, nil 146 } 147 148 res := &userpb.GetUserResponse{ 149 Status: status.NewOK(ctx), 150 User: user, 151 } 152 return res, nil 153 } 154 155 func (s *service) GetUserByClaim(ctx context.Context, req *userpb.GetUserByClaimRequest) (*userpb.GetUserByClaimResponse, error) { 156 user, err := s.usermgr.GetUserByClaim(ctx, req.Claim, req.Value, req.SkipFetchingUserGroups) 157 if err != nil { 158 res := &userpb.GetUserByClaimResponse{} 159 if _, ok := err.(errtypes.NotFound); ok { 160 res.Status = status.NewNotFound(ctx, fmt.Sprintf("user not found %s %s", req.Claim, req.Value)) 161 } else { 162 res.Status = status.NewInternal(ctx, "error getting user by claim") 163 } 164 return res, nil 165 } 166 167 res := &userpb.GetUserByClaimResponse{ 168 Status: status.NewOK(ctx), 169 User: user, 170 } 171 return res, nil 172 } 173 174 func (s *service) FindUsers(ctx context.Context, req *userpb.FindUsersRequest) (*userpb.FindUsersResponse, error) { 175 users, err := s.usermgr.FindUsers(ctx, req.Filter, req.SkipFetchingUserGroups) 176 if err != nil { 177 res := &userpb.FindUsersResponse{ 178 Status: status.NewInternal(ctx, "error finding users"), 179 } 180 return res, nil 181 } 182 183 // sort users by username 184 sort.Slice(users, func(i, j int) bool { 185 return users[i].Username <= users[j].Username 186 }) 187 188 res := &userpb.FindUsersResponse{ 189 Status: status.NewOK(ctx), 190 Users: users, 191 } 192 return res, nil 193 } 194 195 func (s *service) GetUserGroups(ctx context.Context, req *userpb.GetUserGroupsRequest) (*userpb.GetUserGroupsResponse, error) { 196 log := appctx.GetLogger(ctx) 197 if req.UserId == nil { 198 res := &userpb.GetUserGroupsResponse{ 199 Status: status.NewInvalid(ctx, "userid missing"), 200 } 201 return res, nil 202 } 203 groups, err := s.usermgr.GetUserGroups(ctx, req.UserId) 204 if err != nil { 205 log.Warn().Err(err).Interface("userid", req.UserId).Msg("error getting user groups") 206 res := &userpb.GetUserGroupsResponse{ 207 Status: status.NewInternal(ctx, "error getting user groups"), 208 } 209 return res, nil 210 } 211 212 res := &userpb.GetUserGroupsResponse{ 213 Status: status.NewOK(ctx), 214 Groups: groups, 215 } 216 return res, nil 217 }