From 1b0b14512cbe70a357f152e14e919445d38d6e2c Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Tue, 13 Apr 2021 11:40:21 +0200 Subject: [PATCH] Read UID and GID from the opaque object for CS3 proxy backend --- ocs/pkg/service/v0/users.go | 60 +++++++++++++++++++++++++++++++---- proxy/pkg/user/backend/cs3.go | 12 ++++--- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/ocs/pkg/service/v0/users.go b/ocs/pkg/service/v0/users.go index d01c83f09..3e0859656 100644 --- a/ocs/pkg/service/v0/users.go +++ b/ocs/pkg/service/v0/users.go @@ -17,6 +17,7 @@ import ( "google.golang.org/protobuf/types/known/fieldmaskpb" merrors "github.com/asim/go-micro/v3/errors" + cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0" "github.com/owncloud/ocis/ocs/pkg/service/v0/data" "github.com/owncloud/ocis/ocs/pkg/service/v0/response" @@ -42,13 +43,14 @@ func (o Ocs) GetSelf(w http.ResponseWriter, r *http.Request) { // TODO(someone) this fix is in place because if the user backend (PROXY_ACCOUNT_BACKEND_TYPE) is set to, for instance, // cs3, we cannot count with the accounts service. if u != nil { + uid, gid := o.extractUIDAndGID(u) d := &data.User{ UserID: u.Username, DisplayName: u.DisplayName, LegacyDisplayName: u.DisplayName, Email: u.Mail, - UIDNumber: u.UidNumber, - GIDNumber: u.GidNumber, + UIDNumber: uid, + GIDNumber: gid, } mustNotFail(render.Render(w, r, response.DataRender(d))) return @@ -88,10 +90,32 @@ func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) { } if err != nil { merr := merrors.FromError(err) - if merr.Code == http.StatusNotFound { - mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))) - } else { - mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))) + u, ok := user.ContextGetUser(r.Context()) + if !ok || u.Id == nil || u.Id.OpaqueId == "" { + mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id"))) + return + } + if u != nil { + uid, gid := o.extractUIDAndGID(u) + d := &data.User{ + UserID: u.Username, + DisplayName: u.DisplayName, + LegacyDisplayName: u.DisplayName, + Email: u.Mail, + UIDNumber: uid, + GIDNumber: gid, + Enabled: "true", // Assume true for CS3 backend? + // TODO query storage registry for free space? of home storage, maybe... + Quota: &data.Quota{ + Free: 2840756224000, + Used: 5059416668, + Total: 2845815640668, + Relative: 0.18, + Definition: "default", + }, + } + mustNotFail(render.Render(w, r, response.DataRender(d))) + return } o.logger.Error().Err(merr).Str("userid", userid).Msg("could not get account for user") return @@ -533,3 +557,27 @@ func (o Ocs) fetchAccountByUsername(ctx context.Context, name string) (*accounts } return nil, merrors.NotFound("", "The requested user could not be found") } + +func (o Ocs) extractUIDAndGID(u *cs3.User) (int64, int64) { + var uid, gid int64 + var err error + if u.Opaque != nil && u.Opaque.Map != nil { + if uidObj, ok := u.Opaque.Map["uid"]; ok { + if uidObj.Decoder == "plain" { + uid, err = strconv.ParseInt(string(uidObj.Value), 10, 64) + if err != nil { + o.logger.Error().Err(err).Interface("user", u).Msg("could not extract uid for user") + } + } + } + if gidObj, ok := u.Opaque.Map["gid"]; ok { + if gidObj.Decoder == "plain" { + gid, err = strconv.ParseInt(string(gidObj.Value), 10, 64) + if err != nil { + o.logger.Error().Err(err).Interface("user", u).Msg("could not extract gid for user") + } + } + } + } + return uid, gid +} diff --git a/proxy/pkg/user/backend/cs3.go b/proxy/pkg/user/backend/cs3.go index 3c97d3642..3dff9c88c 100644 --- a/proxy/pkg/user/backend/cs3.go +++ b/proxy/pkg/user/backend/cs3.go @@ -70,10 +70,14 @@ func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string, w c.logger.Error().Err(err).Msg("Could not encode loaded roles") } - user.Opaque = &types.Opaque{ - Map: map[string]*types.OpaqueEntry{ - "roles": enc, - }, + if user.Opaque == nil { + user.Opaque = &types.Opaque{ + Map: map[string]*types.OpaqueEntry{ + "roles": enc, + }, + } + } else { + user.Opaque.Map["roles"] = enc } return res.User, nil