github.com/cs3org/reva/v2@v2.27.7/pkg/cbox/utils/conversions.go (about) 1 // Copyright 2018-2023 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package utils 20 21 import ( 22 "context" 23 "errors" 24 "time" 25 26 gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" 27 grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" 28 userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" 29 rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" 30 collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" 31 link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1" 32 provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" 33 typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" 34 "github.com/cs3org/reva/v2/pkg/conversions" 35 ) 36 37 // DBShare stores information about user and public shares. 38 type DBShare struct { 39 ID string 40 UIDOwner string 41 UIDInitiator string 42 Prefix string 43 ItemSource string 44 ItemType string 45 ShareWith string 46 Token string 47 Expiration string 48 Permissions int 49 ShareType int 50 ShareName string 51 STime int 52 FileTarget string 53 State int 54 Quicklink bool 55 Description string 56 NotifyUploads bool 57 NotifyUploadsExtraRecipients string 58 } 59 60 // FormatGrantee formats a CS3API grantee to a string. 61 func FormatGrantee(g *provider.Grantee) (int, string) { 62 var granteeType int 63 var formattedID string 64 switch g.Type { 65 case provider.GranteeType_GRANTEE_TYPE_USER: 66 granteeType = 0 67 formattedID = FormatUserID(g.GetUserId()) 68 case provider.GranteeType_GRANTEE_TYPE_GROUP: 69 granteeType = 1 70 formattedID = FormatGroupID(g.GetGroupId()) 71 default: 72 granteeType = -1 73 } 74 return granteeType, formattedID 75 } 76 77 // ExtractGrantee retrieves the CS3API grantee from a formatted string. 78 func ExtractGrantee(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, t int, g string) (*provider.Grantee, error) { 79 var grantee provider.Grantee 80 switch t { 81 case 0: 82 grantee.Type = provider.GranteeType_GRANTEE_TYPE_USER 83 user, err := ExtractUserID(ctx, gateway, g) 84 if err != nil { 85 return nil, err 86 } 87 grantee.Id = &provider.Grantee_UserId{UserId: user} 88 case 1: 89 grantee.Type = provider.GranteeType_GRANTEE_TYPE_GROUP 90 group, err := ExtractGroupID(ctx, gateway, g) 91 if err != nil { 92 return nil, err 93 } 94 grantee.Id = &provider.Grantee_GroupId{GroupId: group} 95 default: 96 grantee.Type = provider.GranteeType_GRANTEE_TYPE_INVALID 97 } 98 return &grantee, nil 99 } 100 101 // ResourceTypeToItem maps a resource type to a string. 102 func ResourceTypeToItem(r provider.ResourceType) string { 103 switch r { 104 case provider.ResourceType_RESOURCE_TYPE_FILE: 105 return "file" 106 case provider.ResourceType_RESOURCE_TYPE_CONTAINER: 107 return "folder" 108 case provider.ResourceType_RESOURCE_TYPE_REFERENCE: 109 return "reference" 110 case provider.ResourceType_RESOURCE_TYPE_SYMLINK: 111 return "symlink" 112 default: 113 return "" 114 } 115 } 116 117 // ResourceTypeToItemInt maps a resource type to an integer. 118 func ResourceTypeToItemInt(r provider.ResourceType) int { 119 switch r { 120 case provider.ResourceType_RESOURCE_TYPE_CONTAINER: 121 return 0 122 case provider.ResourceType_RESOURCE_TYPE_FILE: 123 return 1 124 default: 125 return -1 126 } 127 } 128 129 // SharePermToInt maps read/write permissions to an integer. 130 func SharePermToInt(p *provider.ResourcePermissions) int { 131 var perm int 132 switch { 133 case p.InitiateFileUpload && !p.InitiateFileDownload: 134 perm = 4 135 case p.InitiateFileUpload: 136 perm = 15 137 case p.InitiateFileDownload: 138 perm = 1 139 } 140 // TODO map denials and resharing; currently, denials are mapped to 0 141 return perm 142 } 143 144 // IntTosharePerm retrieves read/write permissions from an integer. 145 func IntTosharePerm(p int, itemType string) *provider.ResourcePermissions { 146 switch p { 147 case 1: 148 return conversions.NewViewerRole().CS3ResourcePermissions() 149 case 15: 150 if itemType == "folder" { 151 return conversions.NewEditorRole().CS3ResourcePermissions() 152 } 153 return conversions.NewFileEditorRole().CS3ResourcePermissions() 154 case 4: 155 return conversions.NewUploaderRole().CS3ResourcePermissions() 156 default: 157 // TODO we may have other options, for now this is a denial 158 return &provider.ResourcePermissions{} 159 } 160 } 161 162 // IntToShareState retrieves the received share state from an integer. 163 func IntToShareState(g int) collaboration.ShareState { 164 switch g { 165 case 0: 166 return collaboration.ShareState_SHARE_STATE_PENDING 167 case 1: 168 return collaboration.ShareState_SHARE_STATE_ACCEPTED 169 case -1: 170 return collaboration.ShareState_SHARE_STATE_REJECTED 171 default: 172 return collaboration.ShareState_SHARE_STATE_INVALID 173 } 174 } 175 176 // FormatUserID formats a CS3API user ID to a string. 177 func FormatUserID(u *userpb.UserId) string { 178 return u.OpaqueId 179 } 180 181 // ExtractUserID retrieves a CS3API user ID from a string. 182 func ExtractUserID(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, u string) (*userpb.UserId, error) { 183 userRes, err := gateway.GetUser(ctx, &userpb.GetUserRequest{ 184 UserId: &userpb.UserId{OpaqueId: u}, 185 }) 186 if err != nil { 187 return nil, err 188 } 189 if userRes.Status.Code != rpcv1beta1.Code_CODE_OK { 190 return nil, errors.New(userRes.Status.Message) 191 } 192 193 return userRes.User.Id, nil 194 } 195 196 // FormatGroupID formats a CS3API group ID to a string. 197 func FormatGroupID(u *grouppb.GroupId) string { 198 return u.OpaqueId 199 } 200 201 // ExtractGroupID retrieves a CS3API group ID from a string. 202 func ExtractGroupID(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, u string) (*grouppb.GroupId, error) { 203 groupRes, err := gateway.GetGroup(ctx, &grouppb.GetGroupRequest{ 204 GroupId: &grouppb.GroupId{OpaqueId: u}, 205 }) 206 if err != nil { 207 return nil, err 208 } 209 if groupRes.Status.Code != rpcv1beta1.Code_CODE_OK { 210 return nil, errors.New(groupRes.Status.Message) 211 } 212 return groupRes.Group.Id, nil 213 } 214 215 // ConvertToCS3Share converts a DBShare to a CS3API collaboration share. 216 func ConvertToCS3Share(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, s DBShare) (*collaboration.Share, error) { 217 ts := &typespb.Timestamp{ 218 Seconds: uint64(s.STime), 219 } 220 owner, err := ExtractUserID(ctx, gateway, s.UIDOwner) 221 if err != nil { 222 return nil, err 223 } 224 creator, err := ExtractUserID(ctx, gateway, s.UIDInitiator) 225 if err != nil { 226 return nil, err 227 } 228 grantee, err := ExtractGrantee(ctx, gateway, s.ShareType, s.ShareWith) 229 if err != nil { 230 return nil, err 231 } 232 233 return &collaboration.Share{ 234 Id: &collaboration.ShareId{ 235 OpaqueId: s.ID, 236 }, 237 //ResourceId: &provider.Reference{StorageId: s.Prefix, NodeId: s.ItemSource}, 238 ResourceId: &provider.ResourceId{ 239 StorageId: s.Prefix, 240 OpaqueId: s.ItemSource, 241 }, 242 Permissions: &collaboration.SharePermissions{Permissions: IntTosharePerm(s.Permissions, s.ItemType)}, 243 Grantee: grantee, 244 Owner: owner, 245 Creator: creator, 246 Ctime: ts, 247 Mtime: ts, 248 }, nil 249 } 250 251 // ConvertToCS3ReceivedShare converts a DBShare to a CS3API collaboration received share. 252 func ConvertToCS3ReceivedShare(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, s DBShare) (*collaboration.ReceivedShare, error) { 253 share, err := ConvertToCS3Share(ctx, gateway, s) 254 if err != nil { 255 return nil, err 256 } 257 return &collaboration.ReceivedShare{ 258 Share: share, 259 State: IntToShareState(s.State), 260 }, nil 261 } 262 263 // ConvertToCS3PublicShare converts a DBShare to a CS3API public share. 264 func ConvertToCS3PublicShare(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, s DBShare) (*link.PublicShare, error) { 265 ts := &typespb.Timestamp{ 266 Seconds: uint64(s.STime), 267 } 268 pwd := false 269 if s.ShareWith != "" { 270 pwd = true 271 } 272 var expires *typespb.Timestamp 273 if s.Expiration != "" { 274 t, err := time.Parse("2006-01-02 15:04:05", s.Expiration) 275 if err == nil { 276 expires = &typespb.Timestamp{ 277 Seconds: uint64(t.Unix()), 278 } 279 } 280 } 281 owner, err := ExtractUserID(ctx, gateway, s.UIDOwner) 282 if err != nil { 283 return nil, err 284 } 285 creator, err := ExtractUserID(ctx, gateway, s.UIDInitiator) 286 if err != nil { 287 return nil, err 288 } 289 return &link.PublicShare{ 290 Id: &link.PublicShareId{ 291 OpaqueId: s.ID, 292 }, 293 ResourceId: &provider.ResourceId{ 294 StorageId: s.Prefix, 295 OpaqueId: s.ItemSource, 296 }, 297 Permissions: &link.PublicSharePermissions{Permissions: IntTosharePerm(s.Permissions, s.ItemType)}, 298 Owner: owner, 299 Creator: creator, 300 Token: s.Token, 301 DisplayName: s.ShareName, 302 PasswordProtected: pwd, 303 Expiration: expires, 304 Ctime: ts, 305 Mtime: ts, 306 Quicklink: s.Quicklink, 307 Description: s.Description, 308 NotifyUploads: s.NotifyUploads, 309 NotifyUploadsExtraRecipients: s.NotifyUploadsExtraRecipients, 310 }, nil 311 }