Skip to content

Commit

Permalink
OIDC driver changes for lightweight users
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 committed Nov 15, 2021
1 parent 17606d3 commit 1e3e24f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 11 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/oidc-lw-users.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Enhancement: OIDC driver changes for lightweight users

https://github.com/cs3org/reva/pull/2278
27 changes: 22 additions & 5 deletions pkg/auth/manager/oidc/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package oidc
import (
"context"
"fmt"
"strings"
"time"

oidc "github.com/coreos/go-oidc"
Expand Down Expand Up @@ -130,15 +131,17 @@ func (am *mgr) Authenticate(ctx context.Context, clientID, clientSecret string)
if claims["email_verified"] == nil { // This is not set in simplesamlphp
claims["email_verified"] = false
}
if claims["preferred_username"] == nil {
claims["preferred_username"] = claims[am.c.IDClaim]
}
if claims["name"] == nil {
claims["name"] = claims[am.c.IDClaim]
}

if claims["email"] == nil {
return nil, nil, fmt.Errorf("no \"email\" attribute found in userinfo: maybe the client did not request the oidc \"email\"-scope")
}

if claims["preferred_username"] == nil || claims["name"] == nil {
return nil, nil, fmt.Errorf("no \"preferred_username\" or \"name\" attribute found in userinfo: maybe the client did not request the oidc \"profile\"-scope")
}

var uid, gid float64
if am.c.UIDClaim != "" {
uid, _ = claims[am.c.UIDClaim].(float64)
Expand All @@ -150,7 +153,7 @@ func (am *mgr) Authenticate(ctx context.Context, clientID, clientSecret string)
userID := &user.UserId{
OpaqueId: claims[am.c.IDClaim].(string), // a stable non reassignable id
Idp: claims["issuer"].(string), // in the scope of this issuer
Type: user.UserType_USER_TYPE_PRIMARY,
Type: getUserType(claims[am.c.IDClaim].(string)),
}
gwc, err := pool.GetGatewayServiceClient(am.c.GatewaySvc)
if err != nil {
Expand Down Expand Up @@ -228,3 +231,17 @@ func (am *mgr) getOIDCProvider(ctx context.Context) (*oidc.Provider, error) {
am.provider = provider
return am.provider, nil
}

func getUserType(upn string) user.UserType {
var t user.UserType
switch {
case strings.HasPrefix(upn, "guest"):
t = user.UserType_USER_TYPE_LIGHTWEIGHT
case strings.Contains(upn, "@"):
t = user.UserType_USER_TYPE_FEDERATED
default:
t = user.UserType_USER_TYPE_PRIMARY
}
return t

}
40 changes: 34 additions & 6 deletions pkg/cbox/user/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,7 @@ func (m *manager) Configure(ml map[string]interface{}) error {
return nil
}

func (m *manager) getUserByParam(ctx context.Context, param, val string) (map[string]interface{}, error) {
url := fmt.Sprintf("%s/Identity?filter=%s:%s&field=upn&field=primaryAccountEmail&field=displayName&field=uid&field=gid&field=type",
m.conf.APIBaseURL, param, url.QueryEscape(val))
func (m *manager) getUser(ctx context.Context, url string) (map[string]interface{}, error) {
responseData, err := m.apiTokenManager.SendAPIGetRequest(ctx, url, false)
if err != nil {
return nil, err
Expand All @@ -151,17 +149,38 @@ func (m *manager) getUserByParam(ctx context.Context, param, val string) (map[st
}

if len(users) != 1 {
return nil, errors.New("rest: user not found: " + param + ": " + val)
return nil, errors.New("rest: user not found for URL: " + url)
}

return users[0], nil
}

func (m *manager) getUserByParam(ctx context.Context, param, val string) (map[string]interface{}, error) {
url := fmt.Sprintf("%s/Identity?filter=%s:%s&field=upn&field=primaryAccountEmail&field=displayName&field=uid&field=gid&field=type",
m.conf.APIBaseURL, param, url.QueryEscape(val))
return m.getUser(ctx, url)
}

func (m *manager) getLightweightUser(ctx context.Context, mail string) (map[string]interface{}, error) {
url := fmt.Sprintf("%s/Identity?filter=primaryAccountEmail:%s&filter=upn:contains:guest&field=upn&field=primaryAccountEmail&field=displayName&field=uid&field=gid&field=type",
m.conf.APIBaseURL, url.QueryEscape(mail))
return m.getUser(ctx, url)
}

func (m *manager) getInternalUserID(ctx context.Context, uid *userpb.UserId) (string, error) {

internalID, err := m.fetchCachedInternalID(uid)
if err != nil {
userData, err := m.getUserByParam(ctx, "upn", uid.OpaqueId)
var (
userData map[string]interface{}
err error
)
if uid.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT {
// Lightweight accounts need to be fetched by email
userData, err = m.getLightweightUser(ctx, strings.TrimPrefix(uid.OpaqueId, "guest:"))
} else {
userData, err = m.getUserByParam(ctx, "upn", uid.OpaqueId)
}
if err != nil {
return "", err
}
Expand Down Expand Up @@ -217,7 +236,16 @@ func (m *manager) parseAndCacheUser(ctx context.Context, userData map[string]int
func (m *manager) GetUser(ctx context.Context, uid *userpb.UserId) (*userpb.User, error) {
u, err := m.fetchCachedUserDetails(uid)
if err != nil {
userData, err := m.getUserByParam(ctx, "upn", uid.OpaqueId)
var (
userData map[string]interface{}
err error
)
if uid.Type == userpb.UserType_USER_TYPE_LIGHTWEIGHT {
// Lightweight accounts need to be fetched by email
userData, err = m.getLightweightUser(ctx, strings.TrimPrefix(uid.OpaqueId, "guest:"))
} else {
userData, err = m.getUserByParam(ctx, "upn", uid.OpaqueId)
}
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 1e3e24f

Please sign in to comment.