Skip to content

Commit

Permalink
extract share creation into its own method
Browse files Browse the repository at this point in the history
  • Loading branch information
David Christofas committed May 10, 2021
1 parent 892438b commit 50066eb
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,30 +80,5 @@ func (h *Handler) createGroupShare(w http.ResponseWriter, r *http.Request, statI
},
}

createShareResponse, err := c.CreateShare(ctx, createShareReq)
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc create share request", err)
return
}
if createShareResponse.Status.Code != rpc.Code_CODE_OK {
if createShareResponse.Status.Code == rpc.Code_CODE_NOT_FOUND {
response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil)
return
}
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc create share request failed", err)
return
}
s, err := conversions.CS3Share2ShareData(ctx, createShareResponse.Share)
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err)
return
}
err = h.addFileInfo(ctx, s, statInfo)
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error adding fileinfo to share", err)
return
}
h.mapUserIds(ctx, c, s)

response.WriteOCSSuccess(w, r, s)
h.createCs3Share(ctx, w, r, c, createShareReq, statInfo)
}
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ func (h *Handler) createShare(w http.ResponseWriter, r *http.Request) {
func (h *Handler) extractPermissions(w http.ResponseWriter, r *http.Request, ri *provider.ResourceInfo, defaultPermissions *conversions.Role) (*conversions.Role, []byte, error) {
reqRole, reqPermissions := r.FormValue("role"), r.FormValue("permissions")
var role *conversions.Role
var permissions conversions.Permissions

// the share role overrides the requested permissions
if reqRole != "" {
Expand All @@ -291,7 +290,7 @@ func (h *Handler) extractPermissions(w http.ResponseWriter, r *http.Request, ri
response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "permissions must be an integer", nil)
return nil, nil, err
}
permissions, err = conversions.NewPermissions(pint)
perm, err := conversions.NewPermissions(pint)
if err != nil {
if err == conversions.ErrPermissionNotInRange {
response.WriteOCSError(w, r, http.StatusNotFound, err.Error(), nil)
Expand All @@ -300,25 +299,25 @@ func (h *Handler) extractPermissions(w http.ResponseWriter, r *http.Request, ri
}
return nil, nil, err
}
role = conversions.RoleFromOCSPermissions(permissions)
role = conversions.RoleFromOCSPermissions(perm)
}
}

permissions = role.OCSPermissions()
permissions := role.OCSPermissions()
if ri != nil && ri.Type == provider.ResourceType_RESOURCE_TYPE_FILE {
// Single file shares should never have delete or create permissions
permissions &^= conversions.PermissionCreate
permissions &^= conversions.PermissionDelete
if permissions == conversions.PermissionInvalid {
response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "Cannot set the requested share permissions", nil)
return nil, nil, fmt.Errorf("Cannot set the requested share permissions")
return nil, nil, errors.New("cannot set the requested share permissions")
}
}

existingPermissions := conversions.RoleFromResourcePermissions(ri.PermissionSet).OCSPermissions()
if permissions == conversions.PermissionInvalid || !existingPermissions.Contain(permissions) {
response.WriteOCSError(w, r, http.StatusNotFound, "Cannot set the requested share permissions", nil)
return nil, nil, fmt.Errorf("Cannot set the requested share permissions")
return nil, nil, errors.New("cannot set the requested share permissions")
}

role = conversions.RoleFromOCSPermissions(permissions)
Expand Down Expand Up @@ -591,19 +590,7 @@ const (

func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) {
// which pending state to list
var stateFilter collaboration.ShareState
switch r.FormValue("state") {
case "all":
stateFilter = ocsStateUnknown // no filter
case "0": // accepted
stateFilter = collaboration.ShareState_SHARE_STATE_ACCEPTED
case "1": // pending
stateFilter = collaboration.ShareState_SHARE_STATE_PENDING
case "2": // rejected
stateFilter = collaboration.ShareState_SHARE_STATE_REJECTED
default:
stateFilter = collaboration.ShareState_SHARE_STATE_ACCEPTED
}
stateFilter := getStateFilter(r.FormValue("state"))

client, err := pool.GetGatewayServiceClient(h.gatewayAddr)
if err != nil {
Expand Down Expand Up @@ -857,14 +844,13 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf
}

// mustGetIdentifiers always returns a struct with identifiers, if the user or group could not be found they will all be empty
func (h *Handler) mustGetIdentifiers(ctx context.Context, c gateway.GatewayAPIClient, id string, isGroup bool) *userIdentifiers {
func (h *Handler) mustGetIdentifiers(ctx context.Context, client gateway.GatewayAPIClient, id string, isGroup bool) *userIdentifiers {
sublog := appctx.GetLogger(ctx).With().Str("id", id).Logger()
if id == "" {
return &userIdentifiers{}
}

idIf, err := h.userIdentifierCache.Get(id)
if err == nil {
if idIf, err := h.userIdentifierCache.Get(id); err == nil {
sublog.Debug().Msg("cache hit")
return idIf.(*userIdentifiers)
}
Expand All @@ -873,7 +859,7 @@ func (h *Handler) mustGetIdentifiers(ctx context.Context, c gateway.GatewayAPICl
var ui *userIdentifiers

if isGroup {
res, err := c.GetGroup(ctx, &grouppb.GetGroupRequest{
res, err := client.GetGroup(ctx, &grouppb.GetGroupRequest{
GroupId: &grouppb.GroupId{
OpaqueId: id,
},
Expand Down Expand Up @@ -902,7 +888,7 @@ func (h *Handler) mustGetIdentifiers(ctx context.Context, c gateway.GatewayAPICl
Mail: res.Group.Mail,
}
} else {
res, err := c.GetUser(ctx, &userpb.GetUserRequest{
res, err := client.GetUser(ctx, &userpb.GetUserRequest{
UserId: &userpb.UserId{
OpaqueId: id,
},
Expand Down Expand Up @@ -936,9 +922,9 @@ func (h *Handler) mustGetIdentifiers(ctx context.Context, c gateway.GatewayAPICl
return ui
}

func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s *conversions.ShareData) {
func (h *Handler) mapUserIds(ctx context.Context, client gateway.GatewayAPIClient, s *conversions.ShareData) {
if s.UIDOwner != "" {
owner := h.mustGetIdentifiers(ctx, c, s.UIDOwner, false)
owner := h.mustGetIdentifiers(ctx, client, s.UIDOwner, false)
s.UIDOwner = owner.Username
if s.DisplaynameOwner == "" {
s.DisplaynameOwner = owner.DisplayName
Expand All @@ -949,7 +935,7 @@ func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s
}

if s.UIDFileOwner != "" {
fileOwner := h.mustGetIdentifiers(ctx, c, s.UIDFileOwner, false)
fileOwner := h.mustGetIdentifiers(ctx, client, s.UIDFileOwner, false)
s.UIDFileOwner = fileOwner.Username
if s.DisplaynameFileOwner == "" {
s.DisplaynameFileOwner = fileOwner.DisplayName
Expand All @@ -960,7 +946,7 @@ func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s
}

if s.ShareWith != "" && s.ShareWith != "***redacted***" {
shareWith := h.mustGetIdentifiers(ctx, c, s.ShareWith, s.ShareType == conversions.ShareTypeGroup)
shareWith := h.mustGetIdentifiers(ctx, client, s.ShareWith, s.ShareType == conversions.ShareTypeGroup)
s.ShareWith = shareWith.Username
if s.ShareWithDisplayname == "" {
s.ShareWithDisplayname = shareWith.DisplayName
Expand All @@ -972,13 +958,13 @@ func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s
}

func (h *Handler) getAdditionalInfoAttribute(ctx context.Context, u *userIdentifiers) string {
b := bytes.Buffer{}
if err := h.additionalInfoTemplate.Execute(&b, u); err != nil {
var buf bytes.Buffer
if err := h.additionalInfoTemplate.Execute(&buf, u); err != nil {
log := appctx.GetLogger(ctx)
log.Warn().Err(err).Msg("failed to parse additional info template")
return ""
}
return b.String()
return buf.String()
}

func (h *Handler) getResourceInfoByPath(ctx context.Context, client gateway.GatewayAPIClient, path string) (*provider.ResourceInfo, *rpc.Status, error) {
Expand Down Expand Up @@ -1032,6 +1018,35 @@ func (h *Handler) getResourceInfo(ctx context.Context, client gateway.GatewayAPI
return pinfo, status, nil
}

func (h *Handler) createCs3Share(ctx context.Context, w http.ResponseWriter, r *http.Request, client gateway.GatewayAPIClient, req *collaboration.CreateShareRequest, info *provider.ResourceInfo) {
createShareResponse, err := client.CreateShare(ctx, req)
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc create share request", err)
return
}
if createShareResponse.Status.Code != rpc.Code_CODE_OK {
if createShareResponse.Status.Code == rpc.Code_CODE_NOT_FOUND {
response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil)
return
}
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc create share request failed", err)
return
}
s, err := conversions.CS3Share2ShareData(ctx, createShareResponse.Share)
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err)
return
}
err = h.addFileInfo(ctx, s, info)
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error adding fileinfo to share", err)
return
}
h.mapUserIds(ctx, client, s)

response.WriteOCSSuccess(w, r, s)
}

func mapState(state collaboration.ShareState) int {
var mapped int
switch state {
Expand All @@ -1046,3 +1061,20 @@ func mapState(state collaboration.ShareState) int {
}
return mapped
}

func getStateFilter(s string) collaboration.ShareState {
var stateFilter collaboration.ShareState
switch s {
case "all":
stateFilter = ocsStateUnknown // no filter
case "0": // accepted
stateFilter = collaboration.ShareState_SHARE_STATE_ACCEPTED
case "1": // pending
stateFilter = collaboration.ShareState_SHARE_STATE_PENDING
case "2": // rejected
stateFilter = collaboration.ShareState_SHARE_STATE_REJECTED
default:
stateFilter = collaboration.ShareState_SHARE_STATE_ACCEPTED
}
return stateFilter
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2021 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 shares
package shares

import (
"testing"

collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
)

func TestGetStateFilter(t *testing.T) {
tests := []struct {
input string
expected collaboration.ShareState
}{
{"all", ocsStateUnknown},
{"0", collaboration.ShareState_SHARE_STATE_ACCEPTED},
{"1", collaboration.ShareState_SHARE_STATE_PENDING},
{"2", collaboration.ShareState_SHARE_STATE_REJECTED},
{"something_invalid", collaboration.ShareState_SHARE_STATE_ACCEPTED},
{"", collaboration.ShareState_SHARE_STATE_ACCEPTED},
}

for _, tt := range tests {
state := getStateFilter(tt.input)
if state != tt.expected {
t.Errorf("getStateFilter(\"%s\") returned %s instead of expected %s", tt.input, state, tt.expected)
}
}
}

func TestMapState(t *testing.T) {
// case collaboration.ShareState_SHARE_STATE_PENDING:
// mapped = ocsStatePending
// case collaboration.ShareState_SHARE_STATE_ACCEPTED:
// mapped = ocsStateAccepted
// case collaboration.ShareState_SHARE_STATE_REJECTED:
// mapped = ocsStateRejected
// default:
// mapped = ocsStateUnknown
tests := []struct {
input collaboration.ShareState
expected int
}{
{collaboration.ShareState_SHARE_STATE_PENDING, ocsStatePending},
{collaboration.ShareState_SHARE_STATE_ACCEPTED, ocsStateAccepted},
{collaboration.ShareState_SHARE_STATE_REJECTED, ocsStateRejected},
{42, ocsStateUnknown},
}

for _, tt := range tests {
state := mapState(tt.input)
if state != tt.expected {
t.Errorf("mapState(%d) returned %d instead of expected %d", tt.input, state, tt.expected)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,32 +82,7 @@ func (h *Handler) createUserShare(w http.ResponseWriter, r *http.Request, statIn
},
}

createShareResponse, err := c.CreateShare(ctx, createShareReq)
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc create share request", err)
return
}
if createShareResponse.Status.Code != rpc.Code_CODE_OK {
if createShareResponse.Status.Code == rpc.Code_CODE_NOT_FOUND {
response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil)
return
}
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc create share request failed", err)
return
}
s, err := conversions.CS3Share2ShareData(ctx, createShareResponse.Share)
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err)
return
}
err = h.addFileInfo(ctx, s, statInfo)
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error adding fileinfo to share", err)
return
}
h.mapUserIds(ctx, c, s)

response.WriteOCSSuccess(w, r, s)
h.createCs3Share(ctx, w, r, c, createShareReq, statInfo)
}

func (h *Handler) removeUserShare(w http.ResponseWriter, r *http.Request, shareID string) {
Expand Down

0 comments on commit 50066eb

Please sign in to comment.