Initial QSfera import
This commit is contained in:
+35
@@ -0,0 +1,35 @@
|
||||
// Copyright 2018-2020 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package group
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
|
||||
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
)
|
||||
|
||||
// Manager is the interface to implement to manipulate groups.
|
||||
type Manager interface {
|
||||
GetGroup(ctx context.Context, gid *grouppb.GroupId, skipFetchingMembers bool) (*grouppb.Group, error)
|
||||
GetGroupByClaim(ctx context.Context, claim, value string, skipFetchingMembers bool) (*grouppb.Group, error)
|
||||
FindGroups(ctx context.Context, query string, skipFetchingMembers bool) ([]*grouppb.Group, error)
|
||||
GetMembers(ctx context.Context, gid *grouppb.GroupId) ([]*userpb.UserId, error)
|
||||
HasMember(ctx context.Context, gid *grouppb.GroupId, uid *userpb.UserId) (bool, error)
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
// Copyright 2018-2020 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
|
||||
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/group"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/group/manager/registry"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.Register("json", New)
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
groups []*grouppb.Group
|
||||
}
|
||||
|
||||
type config struct {
|
||||
// Groups holds a path to a file containing json conforming to the Groups struct
|
||||
Groups string `mapstructure:"groups"`
|
||||
}
|
||||
|
||||
func (c *config) init() {
|
||||
if c.Groups == "" {
|
||||
c.Groups = "/etc/revad/groups.json"
|
||||
}
|
||||
}
|
||||
|
||||
func parseConfig(m map[string]interface{}) (*config, error) {
|
||||
c := &config{}
|
||||
if err := mapstructure.Decode(m, c); err != nil {
|
||||
err = errors.Wrap(err, "error decoding conf")
|
||||
return nil, err
|
||||
}
|
||||
c.init()
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// New returns a group manager implementation that reads a json file to provide group metadata.
|
||||
func New(m map[string]interface{}) (group.Manager, error) {
|
||||
c, err := parseConfig(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f, err := os.ReadFile(c.Groups)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groups := []*grouppb.Group{}
|
||||
|
||||
err = json.Unmarshal(f, &groups)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &manager{
|
||||
groups: groups,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *manager) GetGroup(ctx context.Context, gid *grouppb.GroupId, skipFetchingMembers bool) (*grouppb.Group, error) {
|
||||
for _, g := range m.groups {
|
||||
if (g.Id.GetOpaqueId() == gid.OpaqueId || g.GroupName == gid.OpaqueId) && (gid.Idp == "" || gid.Idp == g.Id.GetIdp()) {
|
||||
group := proto.Clone(g).(*grouppb.Group)
|
||||
if skipFetchingMembers {
|
||||
group.Members = nil
|
||||
}
|
||||
return group, nil
|
||||
}
|
||||
}
|
||||
return nil, errtypes.NotFound(gid.OpaqueId)
|
||||
}
|
||||
|
||||
func (m *manager) GetGroupByClaim(ctx context.Context, claim, value string, skipFetchingMembers bool) (*grouppb.Group, error) {
|
||||
for _, g := range m.groups {
|
||||
if groupClaim, err := extractClaim(g, claim); err == nil && value == groupClaim {
|
||||
group := proto.Clone(g).(*grouppb.Group)
|
||||
if skipFetchingMembers {
|
||||
group.Members = nil
|
||||
}
|
||||
return group, nil
|
||||
}
|
||||
}
|
||||
return nil, errtypes.NotFound(value)
|
||||
}
|
||||
|
||||
func extractClaim(g *grouppb.Group, claim string) (string, error) {
|
||||
switch claim {
|
||||
case "group_name":
|
||||
return g.GroupName, nil
|
||||
case "gid_number":
|
||||
return strconv.FormatInt(g.GidNumber, 10), nil
|
||||
case "display_name":
|
||||
return g.DisplayName, nil
|
||||
case "mail":
|
||||
return g.Mail, nil
|
||||
}
|
||||
return "", errors.New("json: invalid field")
|
||||
}
|
||||
|
||||
func (m *manager) FindGroups(ctx context.Context, query string, skipFetchingMembers bool) ([]*grouppb.Group, error) {
|
||||
groups := []*grouppb.Group{}
|
||||
for _, g := range m.groups {
|
||||
if groupContains(g, query) {
|
||||
group := proto.Clone(g).(*grouppb.Group)
|
||||
if skipFetchingMembers {
|
||||
group.Members = nil
|
||||
}
|
||||
groups = append(groups, group)
|
||||
}
|
||||
}
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func groupContains(g *grouppb.Group, query string) bool {
|
||||
query = strings.ToLower(query)
|
||||
return strings.Contains(strings.ToLower(g.GroupName), query) || strings.Contains(strings.ToLower(g.DisplayName), query) ||
|
||||
strings.Contains(strings.ToLower(g.Mail), query) || strings.Contains(strings.ToLower(g.Id.OpaqueId), query)
|
||||
}
|
||||
|
||||
func (m *manager) GetMembers(ctx context.Context, gid *grouppb.GroupId) ([]*userpb.UserId, error) {
|
||||
for _, g := range m.groups {
|
||||
if g.Id.GetOpaqueId() == gid.OpaqueId || g.GroupName == gid.OpaqueId {
|
||||
return g.Members, nil
|
||||
}
|
||||
}
|
||||
return nil, errtypes.NotFound(gid.OpaqueId)
|
||||
}
|
||||
|
||||
func (m *manager) HasMember(ctx context.Context, gid *grouppb.GroupId, uid *userpb.UserId) (bool, error) {
|
||||
members, err := m.GetMembers(ctx, gid)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, u := range members {
|
||||
if u.OpaqueId == uid.OpaqueId && u.Idp == uid.Idp {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
+377
@@ -0,0 +1,377 @@
|
||||
// Copyright 2018-2020 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
|
||||
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/google/uuid"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/appctx"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/group"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/group/manager/registry"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/sharedconf"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/utils"
|
||||
ldapIdentity "github.com/opencloud-eu/reva/v2/pkg/utils/ldap"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.Register("ldap", New)
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
c *config
|
||||
ldapClient ldap.Client
|
||||
}
|
||||
|
||||
type config struct {
|
||||
utils.LDAPConn `mapstructure:",squash"`
|
||||
LDAPIdentity ldapIdentity.Identity `mapstructure:",squash"`
|
||||
Idp string `mapstructure:"idp"`
|
||||
// Nobody specifies the fallback gid number for groups that don't have a gidNumber set in LDAP
|
||||
Nobody int64 `mapstructure:"nobody"`
|
||||
}
|
||||
|
||||
const tracerName = "pkg/group/manager/ldap"
|
||||
|
||||
func parseConfig(m map[string]interface{}) (*config, error) {
|
||||
c := config{
|
||||
LDAPIdentity: ldapIdentity.New(),
|
||||
}
|
||||
if err := mapstructure.Decode(m, &c); err != nil {
|
||||
return nil, fmt.Errorf("error decoding conf: %w", err)
|
||||
}
|
||||
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
// New returns a group manager implementation that connects to a LDAP server to provide group metadata.
|
||||
func New(m map[string]interface{}) (group.Manager, error) {
|
||||
if sharedconf.MultiTenantEnabled() {
|
||||
return nil, errtypes.NotSupported("ldap group manager does not support multi-tenancy")
|
||||
}
|
||||
|
||||
mgr := &manager{}
|
||||
err := mgr.Configure(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mgr.ldapClient, err = utils.GetLDAPClientWithReconnect(&mgr.c.LDAPConn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mgr, nil
|
||||
}
|
||||
|
||||
// Configure initializes the configuration of the group manager from the supplied config map
|
||||
func (m *manager) Configure(ml map[string]interface{}) error {
|
||||
c, err := parseConfig(ml)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c.Nobody == 0 {
|
||||
c.Nobody = 99
|
||||
}
|
||||
|
||||
if err = c.LDAPIdentity.Setup(); err != nil {
|
||||
return fmt.Errorf("error setting up Identity config: %w", err)
|
||||
}
|
||||
m.c = c
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetGroup implements the group.Manager interface. Looks up a group by Id and return the group
|
||||
func (m *manager) GetGroup(ctx context.Context, gid *grouppb.GroupId, skipFetchingMembers bool) (*grouppb.Group, error) {
|
||||
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "GetGroup")
|
||||
defer span.End()
|
||||
|
||||
span.SetAttributes(
|
||||
attribute.Stringer("group_id", gid),
|
||||
attribute.Bool("skip_fetching_members", skipFetchingMembers),
|
||||
)
|
||||
|
||||
log := appctx.GetLogger(ctx)
|
||||
if gid.Idp != "" && gid.Idp != m.c.Idp {
|
||||
return nil, errtypes.NotFound("idp mismatch")
|
||||
}
|
||||
|
||||
groupEntry, err := m.c.LDAPIdentity.GetLDAPGroupByID(ctx, m.ldapClient, gid.OpaqueId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debug().Interface("entry", groupEntry).Msg("entries")
|
||||
|
||||
g, err := m.ldapEntryToGroup(groupEntry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if skipFetchingMembers {
|
||||
return g, nil
|
||||
}
|
||||
|
||||
members, err := m.c.LDAPIdentity.GetLDAPGroupMembers(ctx, m.ldapClient, groupEntry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
memberIDs := make([]*userpb.UserId, 0, len(members))
|
||||
for _, member := range members {
|
||||
userid, err := m.ldapEntryToUserID(member)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Interface("member", member).Msg("Failed convert member entry to userid")
|
||||
continue
|
||||
}
|
||||
memberIDs = append(memberIDs, userid)
|
||||
}
|
||||
|
||||
g.Members = memberIDs
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
// GetGroupByClaim implements the group.Manager interface. Looks up a group by
|
||||
// claim ('group_name', 'group_id', 'display_name') and returns the group.
|
||||
func (m *manager) GetGroupByClaim(ctx context.Context, claim, value string, skipFetchingMembers bool) (*grouppb.Group, error) {
|
||||
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "GetGroupByClaim")
|
||||
defer span.End()
|
||||
|
||||
span.SetAttributes(
|
||||
attribute.String("claim", claim),
|
||||
attribute.String("value", value),
|
||||
attribute.Bool("skip_fetching_members", skipFetchingMembers),
|
||||
)
|
||||
|
||||
log := appctx.GetLogger(ctx)
|
||||
groupEntry, err := m.c.LDAPIdentity.GetLDAPGroupByAttribute(ctx, m.ldapClient, claim, value)
|
||||
if err != nil {
|
||||
log.Debug().Err(err).Msg("GetGroupByClaim")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debug().Interface("entry", groupEntry).Msg("entries")
|
||||
|
||||
g, err := m.ldapEntryToGroup(groupEntry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if skipFetchingMembers {
|
||||
return g, nil
|
||||
}
|
||||
|
||||
members, err := m.c.LDAPIdentity.GetLDAPGroupMembers(ctx, m.ldapClient, groupEntry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
memberIDs := make([]*userpb.UserId, 0, len(members))
|
||||
for _, member := range members {
|
||||
userid, err := m.ldapEntryToUserID(member)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Interface("member", member).Msg("Failed convert member entry to userid")
|
||||
continue
|
||||
}
|
||||
memberIDs = append(memberIDs, userid)
|
||||
}
|
||||
|
||||
g.Members = memberIDs
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
// FindGroups implements the group.Manager interface. Searches for groups using
|
||||
// a prefix-substring search on the group attributes ('group_name',
|
||||
// 'display_name', 'group_id') and returns the groups. FindGroups does NOT expand the
|
||||
// members of the Groups.
|
||||
func (m *manager) FindGroups(ctx context.Context, query string, skipFetchingMembers bool) ([]*grouppb.Group, error) {
|
||||
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "FindGroups")
|
||||
defer span.End()
|
||||
|
||||
span.SetAttributes(
|
||||
attribute.String("query", query),
|
||||
attribute.Bool("skip_fetching_members", skipFetchingMembers),
|
||||
)
|
||||
|
||||
entries, err := m.c.LDAPIdentity.GetLDAPGroups(ctx, m.ldapClient, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groups := make([]*grouppb.Group, 0, len(entries))
|
||||
|
||||
for _, entry := range entries {
|
||||
g, err := m.ldapEntryToGroup(entry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groups = append(groups, g)
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
// GetMembers implements the group.Manager interface. It returns all the userids of the members
|
||||
// of the group identified by the supplied id.
|
||||
func (m *manager) GetMembers(ctx context.Context, gid *grouppb.GroupId) ([]*userpb.UserId, error) {
|
||||
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "GetMembers")
|
||||
defer span.End()
|
||||
|
||||
span.SetAttributes(
|
||||
attribute.Stringer("group_id", gid),
|
||||
)
|
||||
log := appctx.GetLogger(ctx)
|
||||
if gid.Idp != "" && gid.Idp != m.c.Idp {
|
||||
return nil, errtypes.NotFound("idp mismatch")
|
||||
}
|
||||
|
||||
groupEntry, err := m.c.LDAPIdentity.GetLDAPGroupByID(ctx, m.ldapClient, gid.OpaqueId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debug().Interface("entry", groupEntry).Msg("entries")
|
||||
|
||||
members, err := m.c.LDAPIdentity.GetLDAPGroupMembers(ctx, m.ldapClient, groupEntry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
memberIDs := make([]*userpb.UserId, 0, len(members))
|
||||
for _, member := range members {
|
||||
userid, err := m.ldapEntryToUserID(member)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Interface("member", member).Msg("Failed convert member entry to userid")
|
||||
continue
|
||||
}
|
||||
memberIDs = append(memberIDs, userid)
|
||||
}
|
||||
|
||||
return memberIDs, nil
|
||||
}
|
||||
|
||||
// HasMember implements the group.Member interface. Checks whether the supplied userid is a member
|
||||
// of the supplied groupid.
|
||||
func (m *manager) HasMember(ctx context.Context, gid *grouppb.GroupId, uid *userpb.UserId) (bool, error) {
|
||||
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "HasMember")
|
||||
defer span.End()
|
||||
|
||||
span.SetAttributes(
|
||||
attribute.Stringer("group_id", gid),
|
||||
attribute.Stringer("user_id", uid),
|
||||
)
|
||||
// It might be possible to do a somewhat more clever LDAP search here. (First lookup the user and then
|
||||
// search for (&(objectclass=<groupoc>)(<groupid>=gid)(member=<username/userdn>)
|
||||
// The GetMembers call used below can be quiet ineffecient for large groups
|
||||
members, err := m.GetMembers(ctx, gid)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, u := range members {
|
||||
if u.OpaqueId == uid.OpaqueId && u.Idp == uid.Idp {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (m *manager) ldapEntryToGroup(entry *ldap.Entry) (*grouppb.Group, error) {
|
||||
id, err := m.ldapEntryToGroupID(entry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gidNumber := m.c.Nobody
|
||||
gidValue := entry.GetEqualFoldAttributeValue(m.c.LDAPIdentity.Group.Schema.GIDNumber)
|
||||
if gidValue != "" {
|
||||
gidNumber, err = strconv.ParseInt(gidValue, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
g := &grouppb.Group{
|
||||
Id: id,
|
||||
GroupName: entry.GetEqualFoldAttributeValue(m.c.LDAPIdentity.Group.Schema.Groupname),
|
||||
Mail: entry.GetEqualFoldAttributeValue(m.c.LDAPIdentity.Group.Schema.Mail),
|
||||
DisplayName: entry.GetEqualFoldAttributeValue(m.c.LDAPIdentity.Group.Schema.DisplayName),
|
||||
GidNumber: gidNumber,
|
||||
}
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (m *manager) ldapEntryToGroupID(entry *ldap.Entry) (*grouppb.GroupId, error) {
|
||||
var id string
|
||||
if m.c.LDAPIdentity.Group.Schema.IDIsOctetString {
|
||||
attribute := m.c.LDAPIdentity.Group.Schema.ID
|
||||
rawValue := entry.GetEqualFoldRawAttributeValue(attribute)
|
||||
if strings.EqualFold(attribute, "objectguid") {
|
||||
rawValue = ldapIdentity.SwapObjectGUIDBytes(rawValue)
|
||||
}
|
||||
if value, err := uuid.FromBytes(rawValue); err == nil {
|
||||
id = value.String()
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
id = entry.GetEqualFoldAttributeValue(m.c.LDAPIdentity.Group.Schema.ID)
|
||||
}
|
||||
|
||||
return &grouppb.GroupId{
|
||||
Idp: m.c.Idp,
|
||||
OpaqueId: id,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *manager) ldapEntryToUserID(entry *ldap.Entry) (*userpb.UserId, error) {
|
||||
var uid string
|
||||
if m.c.LDAPIdentity.User.Schema.IDIsOctetString {
|
||||
attribute := m.c.LDAPIdentity.User.Schema.ID
|
||||
rawValue := entry.GetEqualFoldRawAttributeValue(attribute)
|
||||
if strings.EqualFold(attribute, "objectguid") {
|
||||
rawValue = ldapIdentity.SwapObjectGUIDBytes(rawValue)
|
||||
}
|
||||
if value, err := uuid.FromBytes(rawValue); err == nil {
|
||||
uid = value.String()
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
uid = entry.GetEqualFoldAttributeValue(m.c.LDAPIdentity.User.Schema.ID)
|
||||
}
|
||||
|
||||
return &userpb.UserId{
|
||||
Idp: m.c.Idp,
|
||||
OpaqueId: uid,
|
||||
Type: userpb.UserType_USER_TYPE_PRIMARY,
|
||||
}, nil
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Copyright 2018-2020 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
// Load core group manager drivers.
|
||||
_ "github.com/opencloud-eu/reva/v2/pkg/group/manager/json"
|
||||
_ "github.com/opencloud-eu/reva/v2/pkg/group/manager/ldap"
|
||||
_ "github.com/opencloud-eu/reva/v2/pkg/group/manager/null"
|
||||
// Add your own here
|
||||
)
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
// Copyright 2018-2020 CERN
|
||||
// Copyright 2025 OpenCloud GmbH
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package null
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
|
||||
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/group"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/group/manager/registry"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.Register("null", New)
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
}
|
||||
|
||||
// New returns a group manager implementation that return NOT FOUND or empty result set for every call
|
||||
func New(m map[string]interface{}) (group.Manager, error) {
|
||||
return &manager{}, nil
|
||||
}
|
||||
|
||||
func (m *manager) GetGroup(ctx context.Context, gid *grouppb.GroupId, skipFetchingMembers bool) (*grouppb.Group, error) {
|
||||
return nil, errtypes.NotFound(gid.OpaqueId)
|
||||
}
|
||||
|
||||
func (m *manager) GetGroupByClaim(ctx context.Context, claim, value string, skipFetchingMembers bool) (*grouppb.Group, error) {
|
||||
return nil, errtypes.NotFound(value)
|
||||
}
|
||||
|
||||
func (m *manager) FindGroups(ctx context.Context, query string, skipFetchingMembers bool) ([]*grouppb.Group, error) {
|
||||
return []*grouppb.Group{}, nil
|
||||
}
|
||||
|
||||
func (m *manager) GetMembers(ctx context.Context, gid *grouppb.GroupId) ([]*userpb.UserId, error) {
|
||||
return nil, errtypes.NotFound(gid.OpaqueId)
|
||||
}
|
||||
|
||||
func (m *manager) HasMember(ctx context.Context, gid *grouppb.GroupId, uid *userpb.UserId) (bool, error) {
|
||||
return false, errtypes.NotFound(gid.OpaqueId)
|
||||
}
|
||||
Generated
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
// Copyright 2018-2020 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package registry
|
||||
|
||||
import "github.com/opencloud-eu/reva/v2/pkg/group"
|
||||
|
||||
// NewFunc is the function that group managers
|
||||
// should register at init time.
|
||||
type NewFunc func(map[string]interface{}) (group.Manager, error)
|
||||
|
||||
// NewFuncs is a map containing all the registered group managers.
|
||||
var NewFuncs = map[string]NewFunc{}
|
||||
|
||||
// Register registers a new group manager new function.
|
||||
// Not safe for concurrent use. Safe for use from package init.
|
||||
func Register(name string, f NewFunc) {
|
||||
NewFuncs[name] = f
|
||||
}
|
||||
Reference in New Issue
Block a user