mirror of
https://github.com/owncloud/ocis
synced 2026-04-25 17:25:21 +02:00
fix: [OCM] Specification Compliance (#11773)
* fix: [OCISDEV-450] fix ocm path * fix: [OCM] Specification Compliance * update the test * fix: [OCISDEV-471] OCM: User can't change the federated share permission * fix tests * test: fix federated user regex Signed-off-by: Saw-jan <saw.jan.grg3e@gmail.com> * test: fix federated user regex Signed-off-by: Saw-jan <saw.jan.grg3e@gmail.com> * test: fix federated user regex Signed-off-by: Saw-jan <saw.jan.grg3e@gmail.com> * test: adjust test expectations Signed-off-by: Saw-jan <saw.jan.grg3e@gmail.com> * latest reva ocm changes --------- Signed-off-by: Saw-jan <saw.jan.grg3e@gmail.com> Co-authored-by: Saw-jan <saw.jan.grg3e@gmail.com>
This commit is contained in:
5
changelog/unreleased/fix-ocm-weddav.md
Normal file
5
changelog/unreleased/fix-ocm-weddav.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Bugfix: OCM Specification Compliance
|
||||
|
||||
OCM Specification Compliance
|
||||
|
||||
https://github.com/owncloud/ocis/pull/11773
|
||||
5
go.mod
5
go.mod
@@ -66,7 +66,7 @@ require (
|
||||
github.com/open-policy-agent/opa v1.6.0
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20250217093259-fa3804be6c27
|
||||
github.com/owncloud/reva/v2 v2.0.0-20251017104024-82c22e954c1c
|
||||
github.com/owncloud/reva/v2 v2.0.0-20251106102926-751223b32d48
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/xattr v0.4.12
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
@@ -334,7 +334,6 @@ require (
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
golang.org/x/tools v0.37.0 // indirect
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated // indirect
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
|
||||
@@ -344,7 +343,7 @@ require (
|
||||
sigs.k8s.io/yaml v1.5.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/studio-b12/gowebdav => github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202
|
||||
replace github.com/studio-b12/gowebdav => github.com/kobergj/gowebdav v0.0.0-20251030165916-532350997dde
|
||||
|
||||
replace github.com/egirna/icap-client => github.com/kobergj/icap-client v0.0.0-20250116172800-8eaa5022532b
|
||||
|
||||
|
||||
8
go.sum
8
go.sum
@@ -578,8 +578,8 @@ github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4O
|
||||
github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kobergj/go-micro/v4 v4.0.0-20250610135441-d0b187215699 h1:3TOdtI6WPyvBB+uCykapjRtQX8vTHMlyhINzR+58B4k=
|
||||
github.com/kobergj/go-micro/v4 v4.0.0-20250610135441-d0b187215699/go.mod h1:eE/tD53n3KbVrzrWxKLxdkGw45Fg1qaNLWjpJMvIUF4=
|
||||
github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202 h1:A1xJ2NKgiYFiaHiLl9B5yw/gUBACSs9crDykTS3GuQI=
|
||||
github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
|
||||
github.com/kobergj/gowebdav v0.0.0-20251030165916-532350997dde h1:HYcp4J4xYe2m9KSUVbTccJb14TpSs+ldCfDFgqsXedI=
|
||||
github.com/kobergj/gowebdav v0.0.0-20251030165916-532350997dde/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
|
||||
github.com/kobergj/icap-client v0.0.0-20250116172800-8eaa5022532b h1:NBKEgFtIukCreWOEvtrgNQusqosGyhlxzyiHbba1zEI=
|
||||
github.com/kobergj/icap-client v0.0.0-20250116172800-8eaa5022532b/go.mod h1:HpntrRsQA6RKNXy2Nbr4kVj+NO3OYWpAQUVxeya+3sU=
|
||||
github.com/kobergj/plugins/v4/store/nats-js-kv v0.0.0-20240807130109-f62bb67e8c90 h1:pfI8Z5yavO6fU6vDGlWhZ4BgDlvj8c6xB7J57HfTPwA=
|
||||
@@ -717,8 +717,8 @@ github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HD
|
||||
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20250217093259-fa3804be6c27 h1:ID8s5lGBntmrlI6TbDAjTzRyHucn3bVM2wlW+HBplv4=
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20250217093259-fa3804be6c27/go.mod h1:+gT+x62AS9u2Farh9wE2uYmgdvTg0MQgsSI62D+xoRg=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20251017104024-82c22e954c1c h1:8xgW1qAuKNdXgH9P8F4hDI5vU6/VM1PibZhIFj7JSU0=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20251017104024-82c22e954c1c/go.mod h1:EgvdLWO1ezgdVqewaAP2GIZJfRRggwZItJnnTBxNNrY=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20251106102926-751223b32d48 h1:RGnvbZNOE1ss3b0BOM8J+bPrk6prfXB0paKnWaDA/Xg=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20251106102926-751223b32d48/go.mod h1:XenQR69s8JQ5Q4/+/vQbSg6B4+0iM6inYjNxB7SJAhI=
|
||||
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/pablodz/inotifywaitgo v0.0.9 h1:njquRbBU7fuwIe5rEvtaniVBjwWzcpdUVptSgzFqZsw=
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"path"
|
||||
"reflect"
|
||||
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
@@ -544,7 +545,7 @@ func cs3ReceivedOCMSharesToDriveItems(ctx context.Context,
|
||||
// file shares
|
||||
resOpaqueID := "/"
|
||||
if receivedShares[0].GetResourceType() == storageprovider.ResourceType_RESOURCE_TYPE_FILE {
|
||||
resOpaqueID += receivedShares[0].GetName()
|
||||
resOpaqueID = path.Join(resOpaqueID, receivedShares[0].GetName())
|
||||
}
|
||||
|
||||
shareStat, err := gatewayClient.Stat(ctx, &storageprovider.StatRequest{
|
||||
|
||||
@@ -143,7 +143,7 @@ class GraphHelper {
|
||||
* @return string
|
||||
*/
|
||||
public static function getFederatedUserRegex(): string {
|
||||
return '(?=(.{4})*$)[A-Za-z0-9+/]*={0,2}$';
|
||||
return self::getUUIDv4Regex() . '@[a-zA-Z-\\\.]+(:\\\d+)?';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -64,7 +64,7 @@ Feature: search federation users
|
||||
],
|
||||
"properties": {
|
||||
"issuer": {
|
||||
"const": "%local_host_port%"
|
||||
"const": "%local_base_url%"
|
||||
},
|
||||
"issuerAssignedId": {
|
||||
"type": "string",
|
||||
@@ -126,7 +126,7 @@ Feature: search federation users
|
||||
],
|
||||
"properties": {
|
||||
"issuer": {
|
||||
"const": "%remote_host_port%"
|
||||
"const": "%remote_base_url%"
|
||||
},
|
||||
"issuerAssignedId": {
|
||||
"type": "string",
|
||||
@@ -194,7 +194,7 @@ Feature: search federation users
|
||||
],
|
||||
"properties": {
|
||||
"issuer": {
|
||||
"const": "%local_host_port%"
|
||||
"const": "%local_base_url%"
|
||||
},
|
||||
"issuerAssignedId": {
|
||||
"type": "string",
|
||||
@@ -256,7 +256,7 @@ Feature: search federation users
|
||||
],
|
||||
"properties": {
|
||||
"issuer": {
|
||||
"const": "%remote_host_port%"
|
||||
"const": "%remote_base_url%"
|
||||
},
|
||||
"issuerAssignedId": {
|
||||
"type": "string",
|
||||
@@ -346,7 +346,7 @@ Feature: search federation users
|
||||
},
|
||||
"idp": {
|
||||
"type": "string",
|
||||
"const": "%remote_host_port%"
|
||||
"const": "%remote_base_url%"
|
||||
},
|
||||
"mail": {
|
||||
"type": "string",
|
||||
@@ -385,7 +385,7 @@ Feature: search federation users
|
||||
"const": "Alice Hansen"
|
||||
},
|
||||
"idp": {
|
||||
"const": "%local_host_port%"
|
||||
"const": "%local_base_url%"
|
||||
},
|
||||
"mail": {
|
||||
"pattern": "alice@example.org"
|
||||
@@ -409,7 +409,7 @@ Feature: search federation users
|
||||
"const": "Carol King"
|
||||
},
|
||||
"idp": {
|
||||
"const": "%local_host_port%"
|
||||
"const": "%local_base_url%"
|
||||
},
|
||||
"mail": {
|
||||
"pattern": "carol@example.org"
|
||||
@@ -480,7 +480,7 @@ Feature: search federation users
|
||||
],
|
||||
"properties": {
|
||||
"issuer": {
|
||||
"const": "%local_host_port%"
|
||||
"const": "%local_base_url%"
|
||||
},
|
||||
"issuerAssignedId": {
|
||||
"type": "string",
|
||||
@@ -545,7 +545,7 @@ Feature: search federation users
|
||||
],
|
||||
"properties": {
|
||||
"issuer": {
|
||||
"const": "%remote_host_port%"
|
||||
"const": "%remote_base_url%"
|
||||
},
|
||||
"issuerAssignedId": {
|
||||
"type": "string",
|
||||
@@ -692,7 +692,7 @@ Feature: search federation users
|
||||
],
|
||||
"properties": {
|
||||
"issuer": {
|
||||
"const": "%remote_host_port%"
|
||||
"const": "%remote_base_url%"
|
||||
},
|
||||
"issuerAssignedId": {
|
||||
"type": "string",
|
||||
|
||||
8
vendor/github.com/owncloud/reva/v2/internal/grpc/services/ocmcore/ocmcore.go
generated
vendored
8
vendor/github.com/owncloud/reva/v2/internal/grpc/services/ocmcore/ocmcore.go
generated
vendored
@@ -207,7 +207,7 @@ func (s *service) UpdateOCMCoreShare(ctx context.Context, req *ocmcore.UpdateOCM
|
||||
}
|
||||
fileMask := &fieldmaskpb.FieldMask{Paths: []string{"protocols"}}
|
||||
|
||||
user := &userpb.User{Id: ocmuser.RemoteID(&userpb.UserId{OpaqueId: grantee})}
|
||||
user := &userpb.User{Id: ocmuser.DecodeRemoteUserFederatedID(&userpb.UserId{OpaqueId: grantee})}
|
||||
_, err := s.repo.UpdateReceivedShare(ctx, user, &ocm.ReceivedShare{
|
||||
Id: &ocm.ShareId{
|
||||
OpaqueId: req.GetOcmShareId(),
|
||||
@@ -234,7 +234,7 @@ func (s *service) DeleteOCMCoreShare(ctx context.Context, req *ocmcore.DeleteOCM
|
||||
return nil, errtypes.UserRequired("missing remote user id in a metadata")
|
||||
}
|
||||
|
||||
share, err := s.repo.GetReceivedShare(ctx, &userpb.User{Id: ocmuser.RemoteID(&userpb.UserId{OpaqueId: grantee})}, &ocm.ShareReference{
|
||||
share, err := s.repo.GetReceivedShare(ctx, &userpb.User{Id: ocmuser.DecodeRemoteUserFederatedID(&userpb.UserId{OpaqueId: grantee})}, &ocm.ShareReference{
|
||||
Spec: &ocm.ShareReference_Id{
|
||||
Id: &ocm.ShareId{
|
||||
OpaqueId: req.GetId(),
|
||||
@@ -245,7 +245,7 @@ func (s *service) DeleteOCMCoreShare(ctx context.Context, req *ocmcore.DeleteOCM
|
||||
return nil, errtypes.InternalError("unable to get share details")
|
||||
}
|
||||
|
||||
granteeUser := &userpb.User{Id: ocmuser.RemoteID(&userpb.UserId{OpaqueId: grantee})}
|
||||
granteeUser := &userpb.User{Id: ocmuser.DecodeRemoteUserFederatedID(&userpb.UserId{OpaqueId: grantee})}
|
||||
err = s.repo.DeleteReceivedShare(ctx, granteeUser, &ocm.ShareReference{
|
||||
Spec: &ocm.ShareReference_Id{
|
||||
Id: &ocm.ShareId{
|
||||
@@ -262,7 +262,7 @@ func (s *service) DeleteOCMCoreShare(ctx context.Context, req *ocmcore.DeleteOCM
|
||||
if err := events.Publish(ctx, s.eventStream, events.OCMCoreShareDelete{
|
||||
ShareID: share.Id.OpaqueId,
|
||||
Sharer: share.GetOwner(),
|
||||
Grantee: ocmuser.RemoteID(&userpb.UserId{OpaqueId: grantee}),
|
||||
Grantee: ocmuser.DecodeRemoteUserFederatedID(&userpb.UserId{OpaqueId: grantee}),
|
||||
ResourceName: share.Name,
|
||||
CTime: &typespb.Timestamp{Seconds: uint64(time.Now().Unix())},
|
||||
}); err != nil {
|
||||
|
||||
@@ -180,8 +180,8 @@ func (s *service) ForwardInvite(ctx context.Context, req *invitepb.ForwardInvite
|
||||
remoteUser, err := s.ocmClient.InviteAccepted(ctx, ocmEndpoint, &client.InviteAcceptedRequest{
|
||||
Token: req.InviteToken.GetToken(),
|
||||
RecipientProvider: s.conf.ProviderDomain,
|
||||
// The UserID is only a string here. To not loose the IDP information we use the FederatedID encoding
|
||||
// i.e. base64(UserID@IDP)
|
||||
// The UserID is only a string here. To not lose the IDP information we use the FederatedID encoding
|
||||
// i.e. UserID@IDP
|
||||
UserID: ocmuser.FederatedID(user.GetId(), "").GetOpaqueId(),
|
||||
Email: user.GetMail(),
|
||||
Name: user.GetDisplayName(),
|
||||
@@ -219,7 +219,7 @@ func (s *service) ForwardInvite(ctx context.Context, req *invitepb.ForwardInvite
|
||||
// we're using the provider domain as the IDP part of the ID
|
||||
remoteUserID := &userpb.UserId{
|
||||
Type: userpb.UserType_USER_TYPE_FEDERATED,
|
||||
Idp: req.GetOriginSystemProvider().Domain,
|
||||
Idp: ocmuser.NormalizeOCMUserIPD(req.GetOriginSystemProvider().Domain),
|
||||
OpaqueId: remoteUser.UserID,
|
||||
}
|
||||
|
||||
|
||||
@@ -325,9 +325,9 @@ func (s *service) CreateOCMShare(ctx context.Context, req *ocm.CreateOCMShareReq
|
||||
|
||||
// 2.b replace outgoing user ids with ocm user ids
|
||||
// unpack the federated user id
|
||||
shareWith := ocmuser.FormatOCMUser(ocmuser.RemoteID(req.GetGrantee().GetUserId()))
|
||||
shareWith := ocmuser.FormatOCMUser(ocmuser.FederatedID(req.GetGrantee().GetUserId(), ""))
|
||||
|
||||
// wrap the local user id in a federated user id
|
||||
// wrap the local user id in a local federated user id
|
||||
owner := ocmuser.FormatOCMUser(ocmuser.FederatedID(info.Owner, s.conf.ProviderDomain))
|
||||
sender := ocmuser.FormatOCMUser(ocmuser.FederatedID(user.Id, s.conf.ProviderDomain))
|
||||
|
||||
|
||||
6
vendor/github.com/owncloud/reva/v2/internal/http/services/ocmd/invites.go
generated
vendored
6
vendor/github.com/owncloud/reva/v2/internal/http/services/ocmd/invites.go
generated
vendored
@@ -60,7 +60,7 @@ type acceptInviteRequest struct {
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// AcceptInvite informs avout an accepted invitation so that the users
|
||||
// AcceptInvite informs about an accepted invitation so that the users
|
||||
// can initiate the OCM share creation.
|
||||
func (h *invitesHandler) AcceptInvite(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
@@ -73,7 +73,7 @@ func (h *invitesHandler) AcceptInvite(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if req.Token == "" || req.UserID == "" || req.RecipientProvider == "" {
|
||||
reqres.WriteError(w, r, reqres.APIErrorInvalidParameter, "token, userID and recipiendProvider must not be null", nil)
|
||||
reqres.WriteError(w, r, reqres.APIErrorInvalidParameter, "token, userID and recipientProvider must not be null", nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ func (h *invitesHandler) AcceptInvite(w http.ResponseWriter, r *http.Request) {
|
||||
userObj := &userpb.User{
|
||||
Id: &userpb.UserId{
|
||||
OpaqueId: req.UserID,
|
||||
Idp: req.RecipientProvider,
|
||||
Idp: ocmuser.NormalizeOCMUserIPD(req.RecipientProvider),
|
||||
Type: userpb.UserType_USER_TYPE_FEDERATED,
|
||||
},
|
||||
Mail: req.Email,
|
||||
|
||||
3
vendor/github.com/owncloud/reva/v2/internal/http/services/ocmd/notifications.go
generated
vendored
3
vendor/github.com/owncloud/reva/v2/internal/http/services/ocmd/notifications.go
generated
vendored
@@ -29,10 +29,10 @@ import (
|
||||
ocmcore "github.com/cs3org/go-cs3apis/cs3/ocm/core/v1beta1"
|
||||
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/owncloud/reva/v2/pkg/appctx"
|
||||
"github.com/owncloud/reva/v2/pkg/rgrpc/todo/pool"
|
||||
"github.com/owncloud/reva/v2/pkg/utils"
|
||||
"github.com/go-chi/render"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -99,7 +99,6 @@ func (h *notifHandler) Notifications(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(lopresti) this is all to be implemented. For now we just log what we got
|
||||
log.Debug().Msgf("Received OCM notification: %+v", req)
|
||||
|
||||
var status *rpc.Status
|
||||
|
||||
42
vendor/github.com/owncloud/reva/v2/internal/http/services/ocmd/shares.go
generated
vendored
42
vendor/github.com/owncloud/reva/v2/internal/http/services/ocmd/shares.go
generated
vendored
@@ -34,11 +34,12 @@ import (
|
||||
ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
|
||||
providerpb "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/owncloud/reva/v2/internal/http/services/reqres"
|
||||
"github.com/owncloud/reva/v2/pkg/appctx"
|
||||
ocmuser "github.com/owncloud/reva/v2/pkg/ocm/user"
|
||||
"github.com/owncloud/reva/v2/pkg/rgrpc/todo/pool"
|
||||
"github.com/owncloud/reva/v2/pkg/utils"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
var validate = validator.New()
|
||||
@@ -124,7 +125,7 @@ func (h *sharesHandler) CreateShare(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
shareWith, _, err := getIDAndMeshProvider(req.ShareWith)
|
||||
shareWith, _, err := getLocalUserID(req.ShareWith)
|
||||
if err != nil {
|
||||
reqres.WriteError(w, r, reqres.APIErrorInvalidParameter, err.Error(), nil)
|
||||
return
|
||||
@@ -197,11 +198,28 @@ func (h *sharesHandler) CreateShare(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
func getLocalUserID(user string) (id, provider string, err error) {
|
||||
idPart, provider, err := getIDAndMeshProvider(user)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// Handle nested @ in idPart (e.g. "user@idp@provider")
|
||||
if inner := strings.LastIndex(idPart, "@"); inner != -1 {
|
||||
id = idPart[:inner]
|
||||
} else {
|
||||
id = idPart
|
||||
}
|
||||
|
||||
return id, provider, nil
|
||||
}
|
||||
|
||||
func getUserIDFromOCMUser(user string) (*userpb.UserId, error) {
|
||||
id, idp, err := getIDAndMeshProvider(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
idp = ocmuser.NormalizeOCMUserIPD(idp)
|
||||
return &userpb.UserId{
|
||||
OpaqueId: id,
|
||||
Idp: idp,
|
||||
@@ -210,13 +228,21 @@ func getUserIDFromOCMUser(user string) (*userpb.UserId, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getIDAndMeshProvider(user string) (string, string, error) {
|
||||
// the user is in the form of dimitri@apiwise.nl
|
||||
split := strings.Split(user, "@")
|
||||
if len(split) < 2 {
|
||||
return "", "", errors.New("not in the form <id>@<provider>")
|
||||
func getIDAndMeshProvider(user string) (id, provider string, err error) {
|
||||
last := strings.LastIndex(user, "@")
|
||||
if last == -1 {
|
||||
return "", "", fmt.Errorf("%s not in the form <id>@<provider>", user)
|
||||
}
|
||||
return strings.Join(split[:len(split)-1], "@"), split[len(split)-1], nil
|
||||
|
||||
id, provider = user[:last], user[last+1:]
|
||||
if id == "" {
|
||||
return "", "", errors.New("id cannot be empty")
|
||||
}
|
||||
if provider == "" {
|
||||
return "", "", errors.New("provider cannot be empty")
|
||||
}
|
||||
|
||||
return id, provider, nil
|
||||
}
|
||||
|
||||
func getCreateShareRequest(r *http.Request) (*createShareRequest, error) {
|
||||
|
||||
12
vendor/github.com/owncloud/reva/v2/pkg/ocm/invite/repository/json/json.go
generated
vendored
12
vendor/github.com/owncloud/reva/v2/pkg/ocm/invite/repository/json/json.go
generated
vendored
@@ -226,12 +226,14 @@ func (m *manager) GetRemoteUser(ctx context.Context, initiator *userpb.UserId, r
|
||||
log := appctx.GetLogger(ctx)
|
||||
for _, acceptedUser := range m.model.AcceptedUsers[initiator.GetOpaqueId()] {
|
||||
log.Info().Msgf("looking for '%s' at '%s' - considering '%s' at '%s'",
|
||||
remoteUserID.OpaqueId,
|
||||
remoteUserID.Idp,
|
||||
acceptedUser.Id.GetOpaqueId(),
|
||||
acceptedUser.Id.GetIdp(),
|
||||
)
|
||||
remoteUserID.OpaqueId, remoteUserID.Idp,
|
||||
acceptedUser.Id.GetOpaqueId(), acceptedUser.Id.GetIdp())
|
||||
|
||||
if (acceptedUser.Id.GetOpaqueId() == remoteUserID.OpaqueId) && (remoteUserID.Idp == "" || idpsEqual(acceptedUser.Id.GetIdp(), remoteUserID.Idp)) {
|
||||
log.Info().Msgf("remote user OpaqueId:'%s' Idp:'%s' matches OpaqueId:'%s' Idp:'%s'",
|
||||
remoteUserID.OpaqueId, remoteUserID.Idp,
|
||||
acceptedUser.Id.GetOpaqueId(), acceptedUser.Id.GetIdp())
|
||||
|
||||
return acceptedUser, nil
|
||||
}
|
||||
}
|
||||
|
||||
6
vendor/github.com/owncloud/reva/v2/pkg/ocm/provider/authorizer/json/json.go
generated
vendored
6
vendor/github.com/owncloud/reva/v2/pkg/ocm/provider/authorizer/json/json.go
generated
vendored
@@ -173,10 +173,12 @@ func (a *authorizer) IsProviderAllowed(ctx context.Context, pi *ocmprovider.Prov
|
||||
}
|
||||
|
||||
switch {
|
||||
case !providerAuthorized:
|
||||
return errtypes.NotFound(pi.GetDomain())
|
||||
case !a.conf.VerifyRequestHostname:
|
||||
log.Info().Msg("VerifyRequestHostname is disabled. any provider is allowed")
|
||||
return nil
|
||||
case !providerAuthorized:
|
||||
log.Info().Msg("providerAuthorized is false")
|
||||
return errtypes.NotFound(pi.GetDomain())
|
||||
case len(pi.Services) == 0:
|
||||
return ErrNoIP
|
||||
}
|
||||
|
||||
60
vendor/github.com/owncloud/reva/v2/pkg/ocm/user/user.go
generated
vendored
60
vendor/github.com/owncloud/reva/v2/pkg/ocm/user/user.go
generated
vendored
@@ -1,50 +1,76 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
)
|
||||
|
||||
// FederatedID creates a federated user id by
|
||||
// FederatedID creates a federated id for local users by
|
||||
// 1. stripping the protocol from the domain and
|
||||
// 2. base64 encoding the opaque id with the domain to get a unique identifier that cannot collide with other users
|
||||
// 2. concatenating the opaque id with the domain to get a unique identifier that cannot collide with other users
|
||||
func FederatedID(id *userpb.UserId, domain string) *userpb.UserId {
|
||||
opaqueId := base64.URLEncoding.EncodeToString([]byte(id.OpaqueId + "@" + id.Idp))
|
||||
return &userpb.UserId{
|
||||
if domain == "" {
|
||||
domain = id.Idp
|
||||
}
|
||||
// strip protocol from the domain
|
||||
idp := id.Idp
|
||||
if u, err := url.Parse(id.Idp); err == nil && u.Host != "" {
|
||||
idp = u.Host
|
||||
}
|
||||
opaqueId := id.OpaqueId
|
||||
if !strings.Contains(id.OpaqueId, "@") {
|
||||
opaqueId = id.OpaqueId + "@" + idp
|
||||
}
|
||||
|
||||
u := &userpb.UserId{
|
||||
Type: userpb.UserType_USER_TYPE_FEDERATED,
|
||||
Idp: domain,
|
||||
Idp: NormalizeOCMUserIPD(domain),
|
||||
OpaqueId: opaqueId,
|
||||
}
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
// RemoteID creates a remote user id by
|
||||
// 1. decoding the base64 encoded opaque id
|
||||
// 2. splitting the opaque id at the last @ to get the opaque id and the domain
|
||||
func RemoteID(id *userpb.UserId) *userpb.UserId {
|
||||
// DecodeRemoteUserFederatedID decodes opaque id into remote user's federated id by
|
||||
// splitting the opaque id at the last @ to get the opaque id and the domain
|
||||
func DecodeRemoteUserFederatedID(id *userpb.UserId) *userpb.UserId {
|
||||
remoteId := &userpb.UserId{
|
||||
Type: userpb.UserType_USER_TYPE_PRIMARY,
|
||||
Idp: id.Idp,
|
||||
OpaqueId: id.OpaqueId,
|
||||
}
|
||||
bytes, err := base64.URLEncoding.DecodeString(id.GetOpaqueId())
|
||||
if err != nil {
|
||||
return remoteId
|
||||
}
|
||||
remote := string(bytes)
|
||||
remote := id.OpaqueId
|
||||
last := strings.LastIndex(remote, "@")
|
||||
if last == -1 {
|
||||
return remoteId
|
||||
}
|
||||
remoteId.OpaqueId = remote[:last]
|
||||
remoteId.Idp = remote[last+1:]
|
||||
remoteId.Idp = NormalizeOCMUserIPD(remote[last+1:])
|
||||
|
||||
return remoteId
|
||||
}
|
||||
|
||||
// FormatOCMUser formats a user id in the form of <opaque-id>@<idp> used by the OCM API in shareWith, owner and creator fields
|
||||
func FormatOCMUser(u *userpb.UserId) string {
|
||||
return fmt.Sprintf("%s@%s", u.OpaqueId, u.Idp)
|
||||
if u.Idp == "" {
|
||||
return u.OpaqueId
|
||||
}
|
||||
// strip protocol from the domain
|
||||
idp := u.Idp
|
||||
if u, err := url.Parse(u.Idp); err == nil && u.Host != "" {
|
||||
idp = u.Host
|
||||
}
|
||||
return fmt.Sprintf("%s@%s", u.OpaqueId, idp)
|
||||
}
|
||||
|
||||
// NormalizeOCMUserIPD ensures that the idp has a scheme (https://) prefix if prefix is missing
|
||||
// to keep the idp consistent across shares and received shares in the OCM share store.
|
||||
func NormalizeOCMUserIPD(idp string) string {
|
||||
if strings.Contains(idp, "://") {
|
||||
return idp
|
||||
}
|
||||
return "https://" + idp
|
||||
}
|
||||
|
||||
2
vendor/github.com/studio-b12/gowebdav/file.go
generated
vendored
2
vendor/github.com/studio-b12/gowebdav/file.go
generated
vendored
@@ -32,7 +32,7 @@ func newFile(path, name string, p *propstat) *File {
|
||||
path = FixSlashes(path)
|
||||
|
||||
f.name = filepath.Base(name)
|
||||
f.path = filepath.Clean(filepath.Join(path, f.name))
|
||||
f.path = filepath.Clean(filepath.Join(path, name))
|
||||
f.modified = p.Modified()
|
||||
f.etag = p.ETag()
|
||||
f.contentType = p.ContentType()
|
||||
|
||||
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@@ -1247,7 +1247,7 @@ github.com/orcaman/concurrent-map
|
||||
# github.com/owncloud/libre-graph-api-go v1.0.5-0.20250217093259-fa3804be6c27
|
||||
## explicit; go 1.18
|
||||
github.com/owncloud/libre-graph-api-go
|
||||
# github.com/owncloud/reva/v2 v2.0.0-20251017104024-82c22e954c1c
|
||||
# github.com/owncloud/reva/v2 v2.0.0-20251106102926-751223b32d48
|
||||
## explicit; go 1.24.0
|
||||
github.com/owncloud/reva/v2/cmd/revad/internal/grace
|
||||
github.com/owncloud/reva/v2/cmd/revad/runtime
|
||||
@@ -1852,7 +1852,7 @@ github.com/stretchr/testify/assert
|
||||
github.com/stretchr/testify/assert/yaml
|
||||
github.com/stretchr/testify/mock
|
||||
github.com/stretchr/testify/require
|
||||
# github.com/studio-b12/gowebdav v0.9.0 => github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202
|
||||
# github.com/studio-b12/gowebdav v0.9.0 => github.com/kobergj/gowebdav v0.0.0-20251030165916-532350997dde
|
||||
## explicit; go 1.17
|
||||
github.com/studio-b12/gowebdav
|
||||
# github.com/tchap/go-patricia/v2 v2.3.3
|
||||
@@ -2470,7 +2470,7 @@ sigs.k8s.io/yaml
|
||||
# stash.kopano.io/kgol/rndm v1.1.2
|
||||
## explicit; go 1.13
|
||||
stash.kopano.io/kgol/rndm
|
||||
# github.com/studio-b12/gowebdav => github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202
|
||||
# github.com/studio-b12/gowebdav => github.com/kobergj/gowebdav v0.0.0-20251030165916-532350997dde
|
||||
# github.com/egirna/icap-client => github.com/kobergj/icap-client v0.0.0-20250116172800-8eaa5022532b
|
||||
# github.com/unrolled/secure => github.com/DeepDiver1975/secure v0.0.0-20240611112133-abc838fb797c
|
||||
# github.com/go-micro/plugins/v4/store/nats-js-kv => github.com/kobergj/plugins/v4/store/nats-js-kv v0.0.0-20240807130109-f62bb67e8c90
|
||||
|
||||
Reference in New Issue
Block a user