Skip to content

Commit

Permalink
Fetch user groups in OIDC and LDAP backend
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 committed Feb 5, 2021
1 parent 2cffdaa commit 572fdec
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 14 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/oidc-ldap-user-groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Enhancement: Fetch user groups in OIDC and LDAP backend

https://github.com/cs3org/reva/pull/1456
29 changes: 25 additions & 4 deletions pkg/auth/manager/ldap/ldap.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ import (
"strings"

user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
"github.com/cs3org/reva/pkg/auth"
"github.com/cs3org/reva/pkg/auth/manager/registry"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/logger"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/sharedconf"
"github.com/go-ldap/ldap/v3"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
Expand All @@ -53,6 +56,7 @@ type config struct {
BindUsername string `mapstructure:"bind_username"`
BindPassword string `mapstructure:"bind_password"`
Idp string `mapstructure:"idp"`
GatewaySvc string `mapstructure:"gatewaysvc"`
Schema attributes `mapstructure:"schema"`
}

Expand Down Expand Up @@ -111,6 +115,8 @@ func New(m map[string]interface{}) (auth.Manager, error) {
c.LoginFilter = strings.ReplaceAll(c.LoginFilter, "%s", "{{login}}")
}

c.GatewaySvc = sharedconf.GetGatewaySVC(c.GatewaySvc)

return &mgr{
c: c,
}, nil
Expand Down Expand Up @@ -159,11 +165,26 @@ func (am *mgr) Authenticate(ctx context.Context, clientID, clientSecret string)
return nil, err
}

userID := &user.UserId{
Idp: am.c.Idp,
OpaqueId: sr.Entries[0].GetEqualFoldAttributeValue(am.c.Schema.UID),
}
gwc, err := pool.GetGatewayServiceClient(am.c.GatewaySvc)
if err != nil {
return nil, errors.Wrap(err, "ldap: error getting gateway grpc client")
}
getGroupsResp, err := gwc.GetUserGroups(ctx, &user.GetUserGroupsRequest{
UserId: userID,
})
if err != nil {
return nil, errors.Wrap(err, "ldap: error getting user groups")
}
if getGroupsResp.Status.Code != rpc.Code_CODE_OK {
return nil, errors.Wrap(err, "ldap: grpc getting user groups failed")
}

u := &user.User{
Id: &user.UserId{
Idp: am.c.Idp,
OpaqueId: sr.Entries[0].GetEqualFoldAttributeValue(am.c.Schema.UID),
},
Id: userID,
// TODO add more claims from the StandardClaims, eg EmailVerified
Username: sr.Entries[0].GetEqualFoldAttributeValue(am.c.Schema.CN),
// TODO groups
Expand Down
41 changes: 31 additions & 10 deletions pkg/auth/manager/oidc/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ import (

oidc "github.com/coreos/go-oidc"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/pkg/auth"
"github.com/cs3org/reva/pkg/auth/manager/registry"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/rhttp"
"github.com/cs3org/reva/pkg/sharedconf"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
Expand All @@ -47,18 +50,21 @@ type mgr struct {
}

type config struct {
Insecure bool `mapstructure:"insecure" docs:"false;Whether to skip certificate checks when sending requests."`
Issuer string `mapstructure:"issuer" docs:";The issuer of the OIDC token."`
IDClaim string `mapstructure:"id_claim" docs:"sub;The claim containing the ID of the user."`
UIDClaim string `mapstructure:"uid_claim" docs:";The claim containing the UID of the user."`
GIDClaim string `mapstructure:"gid_claim" docs:";The claim containing the GID of the user."`
Insecure bool `mapstructure:"insecure" docs:"false;Whether to skip certificate checks when sending requests."`
Issuer string `mapstructure:"issuer" docs:";The issuer of the OIDC token."`
IDClaim string `mapstructure:"id_claim" docs:"sub;The claim containing the ID of the user."`
UIDClaim string `mapstructure:"uid_claim" docs:";The claim containing the UID of the user."`
GIDClaim string `mapstructure:"gid_claim" docs:";The claim containing the GID of the user."`
GatewaySvc string `mapstructure:"gatewaysvc" docs:";The endpoint at which the GRPC gateway is exposed."`
}

func (c *config) init() {
if c.IDClaim == "" {
// sub is stable and defined as unique. the user manager needs to take care of the sub to user metadata lookup
c.IDClaim = "sub"
}

c.GatewaySvc = sharedconf.GetGatewaySVC(c.GatewaySvc)
}

func parseConfig(m map[string]interface{}) (*config, error) {
Expand Down Expand Up @@ -145,17 +151,32 @@ 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
}
gwc, err := pool.GetGatewayServiceClient(am.c.GatewaySvc)
if err != nil {
return nil, errors.Wrap(err, "oidc: error getting gateway grpc client")
}
getGroupsResp, err := gwc.GetUserGroups(ctx, &user.GetUserGroupsRequest{
UserId: userID,
})
if err != nil {
return nil, errors.Wrap(err, "oidc: error getting user groups")
}
if getGroupsResp.Status.Code != rpc.Code_CODE_OK {
return nil, errors.Wrap(err, "oidc: grpc getting user groups failed")
}

u := &user.User{
Id: &user.UserId{
OpaqueId: claims[am.c.IDClaim].(string), // a stable non reassignable id
Idp: claims["issuer"].(string), // in the scope of this issuer
},
Id: userID,
Username: claims["preferred_username"].(string),
// TODO(labkode) if we can get groups from the claim we need to give the possibility
// to the admin to choose what claim provides the groups.
// TODO(labkode) ... use all claims from oidc?
// TODO(labkode): do like K8s does it: https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go
Groups: []string{},
Groups: getGroupsResp.Groups,
Mail: claims["email"].(string),
MailVerified: claims["email_verified"].(bool),
DisplayName: claims["name"].(string),
Expand Down

0 comments on commit 572fdec

Please sign in to comment.