github.com/cs3org/reva/v2@v2.27.7/pkg/storage/migrate/shares.go (about)

     1  // Copyright 2018-2021 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 migrate
    20  
    21  import (
    22  	"bufio"
    23  	"context"
    24  	"encoding/json"
    25  	"log"
    26  	"os"
    27  	"path"
    28  
    29  	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
    30  	user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
    31  	rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
    32  	collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
    33  	provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
    34  )
    35  
    36  // share representation in the import metadata
    37  type share struct {
    38  	Path           string `json:"path"`
    39  	ShareType      string `json:"shareType"`
    40  	Type           string `json:"type"`
    41  	Owner          string `json:"owner"`
    42  	SharedBy       string `json:"sharedBy"`
    43  	SharedWith     string `json:"sharedWith"`
    44  	Permissions    int    `json:"permissions"`
    45  	ExpirationDate string `json:"expirationDate"`
    46  	Password       string `json:"password"`
    47  	Name           string `json:"name"`
    48  	Token          string `json:"token"`
    49  }
    50  
    51  // ImportShares from a shares.jsonl file in exportPath. The files must already be present on the storage
    52  func ImportShares(ctx context.Context, client gateway.GatewayAPIClient, exportPath string, ns string) error {
    53  
    54  	sharesJSONL, err := os.Open(path.Join(exportPath, "shares.jsonl"))
    55  	if err != nil {
    56  		return err
    57  	}
    58  	jsonLines := bufio.NewScanner(sharesJSONL)
    59  	sharesJSONL.Close()
    60  
    61  	for jsonLines.Scan() {
    62  		var shareData share
    63  		if err := json.Unmarshal(jsonLines.Bytes(), &shareData); err != nil {
    64  			log.Fatal(err)
    65  			return err
    66  		}
    67  
    68  		// Stat file, skip share creation if it does not exist on the target system
    69  		resourcePath := path.Join(ns, path.Base(exportPath), shareData.Path)
    70  		statReq := &provider.StatRequest{Ref: &provider.Reference{Path: resourcePath}}
    71  		statResp, err := client.Stat(ctx, statReq)
    72  
    73  		if err != nil {
    74  			log.Fatal(err)
    75  		}
    76  
    77  		if statResp.Status.Code == rpc.Code_CODE_NOT_FOUND {
    78  			log.Print("File does not exist on target system, skipping share import: " + resourcePath)
    79  			continue
    80  		}
    81  
    82  		_, err = client.CreateShare(ctx, shareReq(statResp.Info, &shareData))
    83  		if err != nil {
    84  			return err
    85  		}
    86  	}
    87  	return nil
    88  }
    89  
    90  func shareReq(info *provider.ResourceInfo, share *share) *collaboration.CreateShareRequest {
    91  	return &collaboration.CreateShareRequest{
    92  		ResourceInfo: info,
    93  		Grant: &collaboration.ShareGrant{
    94  			Grantee: &provider.Grantee{
    95  				Type: provider.GranteeType_GRANTEE_TYPE_USER,
    96  				Id: &provider.Grantee_UserId{UserId: &user.UserId{
    97  					OpaqueId: share.SharedWith,
    98  				}},
    99  			},
   100  			Permissions: &collaboration.SharePermissions{
   101  				Permissions: convertPermissions(share.Permissions),
   102  			},
   103  		},
   104  	}
   105  }
   106  
   107  // Maps oc10 permissions to roles
   108  var ocPermToRole = map[int]string{
   109  	1:  "viewer",
   110  	15: "co-owner",
   111  	31: "editor",
   112  }
   113  
   114  // Create resource permission-set from ownCloud permissions int
   115  func convertPermissions(ocPermissions int) *provider.ResourcePermissions {
   116  	perms := &provider.ResourcePermissions{}
   117  	switch ocPermToRole[ocPermissions] {
   118  	case "viewer":
   119  		perms.Stat = true
   120  		perms.ListContainer = true
   121  		perms.InitiateFileDownload = true
   122  		perms.ListGrants = true
   123  	case "editor":
   124  		perms.Stat = true
   125  		perms.ListContainer = true
   126  		perms.InitiateFileDownload = true
   127  
   128  		perms.CreateContainer = true
   129  		perms.InitiateFileUpload = true
   130  		perms.Delete = true
   131  		perms.Move = true
   132  		perms.ListGrants = true
   133  	case "co-owner":
   134  		perms.Stat = true
   135  		perms.ListContainer = true
   136  		perms.InitiateFileDownload = true
   137  
   138  		perms.CreateContainer = true
   139  		perms.InitiateFileUpload = true
   140  		perms.Delete = true
   141  		perms.Move = true
   142  
   143  		perms.ListGrants = true
   144  		perms.AddGrant = true
   145  		perms.RemoveGrant = true
   146  		perms.UpdateGrant = true
   147  	}
   148  
   149  	return perms
   150  }