diff --git a/.vscode/launch.json b/.vscode/launch.json index 89918e30a9..32492d9cab 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -22,7 +22,7 @@ // demo users "IDM_CREATE_DEMO_USERS": "true", // OCIS_RUN_EXTENSIONS allows to start a subset of extensions even in the supervised mode - //"OCIS_RUN_EXTENSIONS": "settings,storage-system,graph,graph-explorer,idp,idm,ocs,store,thumbnails,web,webdav,frontend,gateway,users,groups,auth-basic,auth-bearer,storage-authmachine,storage-users,storage-shares,storage-publiclink,app-provider,sharing,proxy,ocdav", + //"OCIS_RUN_EXTENSIONS": "settings,storage-system,graph,graph-explorer,idp,idm,ocs,store,thumbnails,web,webdav,frontend,gateway,users,groups,auth-basic,auth-bearer,storage-authmachine,storage-users,storage-shares,storage-publiclink,storage-system,app-provider,sharing,proxy,ocdav", /* * Keep secrets and passwords in one block to allow easy uncommenting diff --git a/extensions/graph/pkg/identity/ldap.go b/extensions/graph/pkg/identity/ldap.go index c9083061f4..bd195a634b 100644 --- a/extensions/graph/pkg/identity/ldap.go +++ b/extensions/graph/pkg/identity/ldap.go @@ -5,12 +5,15 @@ import ( "errors" "fmt" "net/url" + "strings" "github.com/go-ldap/ldap/v3" "github.com/gofrs/uuid" ldapdn "github.com/libregraph/idm/pkg/ldapdn" libregraph "github.com/owncloud/libre-graph-api-go" + "golang.org/x/exp/slices" + "github.com/owncloud/ocis/v2/extensions/graph/pkg/config" "github.com/owncloud/ocis/v2/extensions/graph/pkg/service/v0/errorcode" "github.com/owncloud/ocis/v2/ocis-pkg/log" @@ -399,14 +402,38 @@ func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregra users := make([]*libregraph.User, 0, len(res.Entries)) for _, e := range res.Entries { - users = append(users, i.createUserModelFromLDAP(e)) + sel := strings.Split(queryParam.Get("$select"), ",") + exp := strings.Split(queryParam.Get("$expand"), ",") + u := i.createUserModelFromLDAP(e) + if slices.Contains(sel, "memberOf") || slices.Contains(exp, "memberOf") { + groupFilter := fmt.Sprintf( + "(%s=%s)", + i.groupAttributeMap.member, e.DN, + ) + userGroups, err := i.getLDAPGroupsByFilter(groupFilter, false, false) + if err != nil { + return nil, err + } + if len(userGroups) > 0 { + expand := ldap.EscapeFilter(queryParam.Get("expand")) + if expand == "" { + expand = "false" + } + groups := make([]libregraph.Group, 0, len(userGroups)) + for _, g := range userGroups { + groups = append(groups, *i.createGroupModelFromLDAP(g)) + } + u.MemberOf = groups + } + } + users = append(users, u) } return users, nil } func (i *LDAP) GetGroup(ctx context.Context, nameOrID string) (*libregraph.Group, error) { i.logger.Debug().Str("backend", "ldap").Msg("GetGroup") - e, err := i.getLDAPGroupByNameOrID(nameOrID, false) + e, err := i.getLDAPGroupByNameOrID(nameOrID, true) if err != nil { return nil, err } @@ -550,7 +577,24 @@ func (i *LDAP) GetGroups(ctx context.Context, queryParam url.Values) ([]*libregr groups := make([]*libregraph.Group, 0, len(res.Entries)) for _, e := range res.Entries { - groups = append(groups, i.createGroupModelFromLDAP(e)) + sel := strings.Split(queryParam.Get("$select"), ",") + exp := strings.Split(queryParam.Get("$expand"), ",") + g := i.createGroupModelFromLDAP(e) + if slices.Contains(sel, "members") || slices.Contains(exp, "members") { + + members, err := i.GetGroupMembers(ctx, *g.Id) + if err != nil { + return nil, err + } + if len(members) > 1 { + m := make([]libregraph.User, 0, len(members)) + for _, u := range members { + m = append(m, *u) + } + g.Members = m + } + } + groups = append(groups, g) } return groups, nil } diff --git a/go.mod b/go.mod index 821200dc52..a744b760fc 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/owncloud/ocis/v2 -go 1.17 +go 1.18 require ( github.com/CiscoM31/godata v1.0.5 @@ -67,6 +67,7 @@ require ( go.opentelemetry.io/otel/sdk v1.7.0 go.opentelemetry.io/otel/trace v1.7.0 golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 + golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf golang.org/x/image v0.0.0-20220321031419-a8550c1d254a golang.org/x/net v0.0.0-20220516155154-20f960328961 golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 diff --git a/go.sum b/go.sum index a3ee162d60..97bf397f2c 100644 --- a/go.sum +++ b/go.sum @@ -1023,8 +1023,6 @@ github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35uk github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY= github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA= -github.com/owncloud/libre-graph-api-go v0.14.2 h1:JiI32eDp7JZmiVv4aUpC4yaPpv6gK4xxM9MOe/0cXpE= -github.com/owncloud/libre-graph-api-go v0.14.2/go.mod h1:579sFrPP7aP24LZXGPopLfvE+hAka/2DYHk0+Ij+w+U= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -1403,6 +1401,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf h1:oXVg4h2qJDd9htKxb5SCpFBHLipW6hXmL3qpUixS2jw= +golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf/go.mod h1:yh0Ynu2b5ZUe3MQfp2nM0ecK7wsgouWTDN0FNeJuIys= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=