Skip to content

Commit 9bbedc4

Browse files
committed
Contact API on user cache miss
1 parent 39c4d38 commit 9bbedc4

1 file changed

Lines changed: 56 additions & 2 deletions

File tree

user/rest.go

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/cs3org/reva/v3"
3636
"github.com/cs3org/reva/v3/pkg/appctx"
3737
revautils "github.com/cs3org/reva/v3/pkg/cbox/utils"
38+
"github.com/cs3org/reva/v3/pkg/errtypes"
3839
"github.com/cs3org/reva/v3/pkg/user"
3940
"github.com/cs3org/reva/v3/pkg/utils/cfg"
4041
"github.com/cs3org/reva/v3/pkg/utils/list"
@@ -244,6 +245,38 @@ func (m *manager) fetchAllUserAccounts(ctx context.Context) error {
244245
return nil
245246
}
246247

248+
func (m *manager) fetchExternalUserByEmail(ctx context.Context, email string) (*userpb.User, error) {
249+
if email == "" || !strings.Contains(email, "@") {
250+
return nil, errtypes.NotFound("rest: external user lookup requires an email address")
251+
}
252+
253+
log := appctx.GetLogger(ctx)
254+
url := fmt.Sprintf("%s/api/v1.0/Identity/by_email/%s?filter=unconfirmed%%3Afalse&filter=blocked%%3Afalse&filter=disabled%%3Afalse&field=upn&field=primaryAccountEmail&field=displayName&field=uid&field=gid&field=type&field=source&field=activeUser", m.conf.APIBaseURL, neturl.PathEscape(email))
255+
256+
var r IdentitiesResponse
257+
if err := m.apiTokenManager.SendAPIGetRequest(ctx, url, false, &r); err != nil {
258+
log.Error().Err(err).Str("email", email).Msg("rest: failed to fetch external user from authz")
259+
return nil, err
260+
}
261+
262+
for _, usr := range r.Data {
263+
if usr == nil || !isExternalUserType(usr.UserType()) {
264+
continue
265+
}
266+
267+
u, err := m.parseAndCacheUser(ctx, usr)
268+
if err != nil {
269+
log.Error().Err(err).Str("email", email).Msg("rest: failed to parse external user fetched from authz")
270+
continue
271+
}
272+
273+
log.Debug().Str("email", email).Str("opaque_id", u.GetId().GetOpaqueId()).Msg("rest: fetched and cached external user from authz")
274+
return u, nil
275+
}
276+
277+
return nil, errtypes.NotFound("rest: external user not found in authz")
278+
}
279+
247280
func (m *manager) parseAndCacheUser(ctx context.Context, i *Identity) (*userpb.User, error) {
248281
log := appctx.GetLogger(ctx)
249282

@@ -301,7 +334,14 @@ func (m *manager) fetchExternalIdentities(ctx context.Context, email string) ([]
301334
func (m *manager) GetUser(ctx context.Context, uid *userpb.UserId, skipFetchingGroups bool) (*userpb.User, error) {
302335
u, err := m.fetchCachedUserDetails(ctx, uid)
303336
if err != nil {
304-
return nil, err
337+
if uid == nil || !isExternalUserType(uid.Type) || !strings.Contains(uid.OpaqueId, "@") {
338+
return nil, err
339+
}
340+
341+
u, err = m.fetchExternalUserByEmail(ctx, uid.OpaqueId)
342+
if err != nil {
343+
return nil, err
344+
}
305345
}
306346

307347
if !skipFetchingGroups {
@@ -318,7 +358,17 @@ func (m *manager) GetUser(ctx context.Context, uid *userpb.UserId, skipFetchingG
318358
func (m *manager) GetUserByClaim(ctx context.Context, claim, value string, skipFetchingGroups bool) (*userpb.User, error) {
319359
u, err := m.fetchCachedUserByParam(ctx, claim, value)
320360
if err != nil {
321-
return nil, err
361+
if _, ok := err.(errtypes.Conflict); ok {
362+
return nil, err
363+
}
364+
if (claim != "username" && claim != "mail") || !strings.Contains(value, "@") {
365+
return nil, err
366+
}
367+
368+
u, err = m.fetchExternalUserByEmail(ctx, value)
369+
if err != nil {
370+
return nil, err
371+
}
322372
}
323373

324374
if !skipFetchingGroups {
@@ -399,6 +449,10 @@ func isUserAnyType(user *userpb.User, types []userpb.UserType) bool {
399449
return false
400450
}
401451

452+
func isExternalUserType(t userpb.UserType) bool {
453+
return t == userpb.UserType_USER_TYPE_LIGHTWEIGHT || t == userpb.UserType_USER_TYPE_FEDERATED
454+
}
455+
402456
// Group contains the information about a group.
403457
type Group struct {
404458
GroupIdentifier string `json:"groupIdentifier"`

0 commit comments

Comments
 (0)