mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-06 04:09:40 -06:00
248 lines
10 KiB
Go
248 lines
10 KiB
Go
package identity
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/CiscoM31/godata"
|
|
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
|
cs3group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
|
|
cs3user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
|
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
|
libregraph "github.com/opencloud-eu/libre-graph-api-go"
|
|
"github.com/opencloud-eu/opencloud/pkg/log"
|
|
"github.com/opencloud-eu/opencloud/pkg/shared"
|
|
"github.com/opencloud-eu/opencloud/services/graph/pkg/errorcode"
|
|
"github.com/opencloud-eu/opencloud/services/graph/pkg/odata"
|
|
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
|
|
)
|
|
|
|
var (
|
|
errNotImplemented = errorcode.New(errorcode.NotSupported, "not implemented")
|
|
)
|
|
|
|
type CS3 struct {
|
|
Config *shared.Reva
|
|
Logger *log.Logger
|
|
GatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
|
}
|
|
|
|
// CreateUser implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) CreateUser(ctx context.Context, user libregraph.User) (*libregraph.User, error) {
|
|
return nil, errNotImplemented
|
|
}
|
|
|
|
// DeleteUser implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) DeleteUser(ctx context.Context, nameOrID string) error {
|
|
return errNotImplemented
|
|
}
|
|
|
|
// UpdateUser implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) UpdateUser(ctx context.Context, nameOrID string, user libregraph.UserUpdate) (*libregraph.User, error) {
|
|
return nil, errNotImplemented
|
|
}
|
|
|
|
// GetUser implements the Backend Interface.
|
|
func (i *CS3) GetUser(ctx context.Context, nameOrId string, _ *godata.GoDataRequest) (*libregraph.User, error) {
|
|
logger := i.Logger.SubloggerWithRequestID(ctx)
|
|
logger.Debug().Str("backend", "cs3").Msg("GetUser")
|
|
gatewayClient, err := i.GatewaySelector.Next()
|
|
if err != nil {
|
|
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get gatewayClient")
|
|
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
|
}
|
|
|
|
// Try to get the user by username first
|
|
res, err := gatewayClient.GetUserByClaim(ctx, &cs3user.GetUserByClaimRequest{
|
|
Claim: "username", // FIXME add consts to reva
|
|
Value: nameOrId,
|
|
})
|
|
|
|
switch {
|
|
case err != nil:
|
|
logger.Error().Str("backend", "cs3").Err(err).Str("nameOrId", nameOrId).Msg("error sending get user by claim id grpc request: transport error")
|
|
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
|
case res.GetStatus().GetCode() == cs3rpc.Code_CODE_OK:
|
|
return CreateUserModelFromCS3(res.GetUser()), nil
|
|
case res.GetStatus().GetCode() == cs3rpc.Code_CODE_NOT_FOUND:
|
|
// If the user was not found by username, try to get it by user ID
|
|
default:
|
|
logger.Debug().Str("backend", "cs3").Err(err).Str("nameOrId", nameOrId).Msg("error sending get user by claim id grpc request")
|
|
return nil, errorcode.New(errorcode.GeneralException, res.GetStatus().GetMessage())
|
|
|
|
}
|
|
|
|
// If the user was not found by username, try to get it by user ID
|
|
res, err = gatewayClient.GetUserByClaim(ctx, &cs3user.GetUserByClaimRequest{
|
|
Claim: "userid", // FIXME add consts to reva
|
|
Value: nameOrId,
|
|
})
|
|
switch {
|
|
case err != nil:
|
|
logger.Error().Str("backend", "cs3").Err(err).Str("nameOrId", nameOrId).Msg("error sending get user by claim id grpc request: transport error")
|
|
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
|
case res.GetStatus().GetCode() != cs3rpc.Code_CODE_OK:
|
|
if res.GetStatus().GetCode() == cs3rpc.Code_CODE_NOT_FOUND {
|
|
return nil, errorcode.New(errorcode.ItemNotFound, res.GetStatus().GetMessage())
|
|
}
|
|
logger.Debug().Str("backend", "cs3").Err(err).Str("nameOrId", nameOrId).Msg("error sending get user by claim id grpc request")
|
|
return nil, errorcode.New(errorcode.GeneralException, res.GetStatus().GetMessage())
|
|
}
|
|
|
|
return CreateUserModelFromCS3(res.GetUser()), nil
|
|
}
|
|
|
|
// GetUsers implements the Backend Interface.
|
|
func (i *CS3) GetUsers(ctx context.Context, oreq *godata.GoDataRequest) ([]*libregraph.User, error) {
|
|
logger := i.Logger.SubloggerWithRequestID(ctx)
|
|
logger.Debug().Str("backend", "cs3").Msg("GetUsers")
|
|
gatewayClient, err := i.GatewaySelector.Next()
|
|
if err != nil {
|
|
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get gatewayClient")
|
|
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
|
}
|
|
|
|
search, err := odata.GetSearchValues(oreq.Query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res, err := gatewayClient.FindUsers(ctx, &cs3user.FindUsersRequest{
|
|
// FIXME presence match is currently not implemented, an empty search currently leads to
|
|
// Unwilling To Perform": Search Error: error parsing filter: (&(objectclass=posixAccount)(|(cn=*)(displayname=*)(mail=*))), error: Present filter match for cn not implemented
|
|
Query: search,
|
|
})
|
|
switch {
|
|
case err != nil:
|
|
logger.Error().Str("backend", "cs3").Err(err).Str("search", search).Msg("error sending find users grpc request: transport error")
|
|
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
|
case res.GetStatus().GetCode() != cs3rpc.Code_CODE_OK:
|
|
if res.GetStatus().GetCode() == cs3rpc.Code_CODE_NOT_FOUND {
|
|
return nil, errorcode.New(errorcode.ItemNotFound, res.GetStatus().GetMessage())
|
|
}
|
|
logger.Debug().Str("backend", "cs3").Err(err).Str("search", search).Msg("error sending find users grpc request")
|
|
return nil, errorcode.New(errorcode.GeneralException, res.GetStatus().GetMessage())
|
|
}
|
|
|
|
users := make([]*libregraph.User, 0, len(res.GetUsers()))
|
|
|
|
for _, user := range res.GetUsers() {
|
|
users = append(users, CreateUserModelFromCS3(user))
|
|
}
|
|
|
|
return users, nil
|
|
}
|
|
|
|
// FilterUsers implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) FilterUsers(_ context.Context, _ *godata.GoDataRequest, _ *godata.ParseNode) ([]*libregraph.User, error) {
|
|
return nil, errNotImplemented
|
|
}
|
|
|
|
// UpdateLastSignInDate implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) UpdateLastSignInDate(ctx context.Context, userID string, timestamp time.Time) error {
|
|
return errNotImplemented
|
|
}
|
|
|
|
// GetGroups implements the Backend Interface.
|
|
func (i *CS3) GetGroups(ctx context.Context, oreq *godata.GoDataRequest) ([]*libregraph.Group, error) {
|
|
logger := i.Logger.SubloggerWithRequestID(ctx)
|
|
logger.Debug().Str("backend", "cs3").Msg("GetGroups")
|
|
gatewayClient, err := i.GatewaySelector.Next()
|
|
if err != nil {
|
|
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get gatewayClient")
|
|
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
|
}
|
|
|
|
search, err := odata.GetSearchValues(oreq.Query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res, err := gatewayClient.FindGroups(ctx, &cs3group.FindGroupsRequest{
|
|
// FIXME presence match is currently not implemented, an empty search currently leads to
|
|
// Unwilling To Perform": Search Error: error parsing filter: (&(objectclass=posixAccount)(|(cn=*)(displayname=*)(mail=*))), error: Present filter match for cn not implemented
|
|
Filter: search,
|
|
})
|
|
|
|
switch {
|
|
case err != nil:
|
|
logger.Error().Str("backend", "cs3").Err(err).Str("search", search).Msg("error sending find groups grpc request: transport error")
|
|
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
|
case res.Status.Code != cs3rpc.Code_CODE_OK:
|
|
if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
|
|
return nil, errorcode.New(errorcode.ItemNotFound, res.Status.Message)
|
|
}
|
|
logger.Debug().Str("backend", "cs3").Err(err).Str("search", search).Msg("error sending find groups grpc request")
|
|
return nil, errorcode.New(errorcode.GeneralException, res.Status.Message)
|
|
}
|
|
|
|
groups := make([]*libregraph.Group, 0, len(res.GetGroups()))
|
|
|
|
for _, group := range res.GetGroups() {
|
|
groups = append(groups, CreateGroupModelFromCS3(group))
|
|
}
|
|
|
|
return groups, nil
|
|
}
|
|
|
|
// CreateGroup implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) CreateGroup(ctx context.Context, group libregraph.Group) (*libregraph.Group, error) {
|
|
return nil, errNotImplemented
|
|
}
|
|
|
|
// GetGroup implements the Backend Interface.
|
|
func (i *CS3) GetGroup(ctx context.Context, groupID string, queryParam url.Values) (*libregraph.Group, error) {
|
|
logger := i.Logger.SubloggerWithRequestID(ctx)
|
|
logger.Debug().Str("backend", "cs3").Msg("GetGroup")
|
|
gatewayClient, err := i.GatewaySelector.Next()
|
|
if err != nil {
|
|
logger.Error().Str("backend", "cs3").Err(err).Msg("could not get gatewayClient")
|
|
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
|
}
|
|
|
|
res, err := gatewayClient.GetGroupByClaim(ctx, &cs3group.GetGroupByClaimRequest{
|
|
Claim: "group_id", // FIXME add consts to reva
|
|
Value: groupID,
|
|
})
|
|
|
|
switch {
|
|
case err != nil:
|
|
logger.Error().Str("backend", "cs3").Err(err).Str("groupid", groupID).Msg("error sending get group by claim id grpc request: transport error")
|
|
return nil, errorcode.New(errorcode.ServiceNotAvailable, err.Error())
|
|
case res.Status.Code != cs3rpc.Code_CODE_OK:
|
|
if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
|
|
return nil, errorcode.New(errorcode.ItemNotFound, res.Status.Message)
|
|
}
|
|
logger.Debug().Str("backend", "cs3").Err(err).Str("groupid", groupID).Msg("error sending get group by claim id grpc request")
|
|
return nil, errorcode.New(errorcode.GeneralException, res.Status.Message)
|
|
}
|
|
|
|
return CreateGroupModelFromCS3(res.GetGroup()), nil
|
|
}
|
|
|
|
// DeleteGroup implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) DeleteGroup(ctx context.Context, id string) error {
|
|
return errNotImplemented
|
|
}
|
|
|
|
// UpdateGroupName implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) UpdateGroupName(ctx context.Context, groupID string, groupName string) error {
|
|
return errNotImplemented
|
|
}
|
|
|
|
// GetGroupMembers implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) GetGroupMembers(ctx context.Context, groupID string, _ *godata.GoDataRequest) ([]*libregraph.User, error) {
|
|
return nil, errNotImplemented
|
|
}
|
|
|
|
// AddMembersToGroup implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) AddMembersToGroup(ctx context.Context, groupID string, memberID []string) error {
|
|
return errNotImplemented
|
|
}
|
|
|
|
// RemoveMemberFromGroup implements the Backend Interface. It's currently not supported for the CS3 backend
|
|
func (i *CS3) RemoveMemberFromGroup(ctx context.Context, groupID string, memberID string) error {
|
|
return errNotImplemented
|
|
}
|