github.com/cs3org/reva/v2@v2.27.7/internal/http/services/ocmd/protocols.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 ocmd
    20  
    21  import (
    22  	"encoding/json"
    23  	"errors"
    24  	"fmt"
    25  	"reflect"
    26  	"strings"
    27  
    28  	ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
    29  	providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
    30  	ocmshare "github.com/cs3org/reva/v2/pkg/ocm/share"
    31  	utils "github.com/cs3org/reva/v2/pkg/utils"
    32  )
    33  
    34  // Protocols is the list of protocols.
    35  type Protocols []Protocol
    36  
    37  // Protocol represents the way of access the resource
    38  // in the OCM share.
    39  type Protocol interface {
    40  	// ToOCMProtocol convert the protocol to a ocm Protocol struct
    41  	ToOCMProtocol() *ocm.Protocol
    42  }
    43  
    44  // protocols supported by the OCM API
    45  
    46  // WebDAV contains the parameters for the WebDAV protocol.
    47  type WebDAV struct {
    48  	SharedSecret string   `json:"sharedSecret" validate:"required"`
    49  	Permissions  []string `json:"permissions" validate:"required,dive,required,oneof=read write share"`
    50  	URL          string   `json:"url" validate:"required"`
    51  }
    52  
    53  // ToOCMProtocol convert the protocol to a ocm Protocol struct.
    54  func (w *WebDAV) ToOCMProtocol() *ocm.Protocol {
    55  	perms := &ocm.SharePermissions{
    56  		Permissions: &providerv1beta1.ResourcePermissions{},
    57  	}
    58  	for _, p := range w.Permissions {
    59  		switch p {
    60  		case "read":
    61  			perms.Permissions.GetPath = true
    62  			perms.Permissions.GetQuota = true
    63  			perms.Permissions.InitiateFileDownload = true
    64  			perms.Permissions.ListContainer = true
    65  			perms.Permissions.ListRecycle = true
    66  			perms.Permissions.Stat = true
    67  		case "write":
    68  			perms.Permissions.InitiateFileUpload = true
    69  			perms.Permissions.RestoreRecycleItem = true
    70  			perms.Permissions.CreateContainer = true
    71  			perms.Permissions.Delete = true
    72  			perms.Permissions.Move = true
    73  		}
    74  	}
    75  
    76  	return ocmshare.NewWebDAVProtocol(w.URL, w.SharedSecret, perms)
    77  }
    78  
    79  // Webapp contains the parameters for the Webapp protocol.
    80  type Webapp struct {
    81  	URITemplate string `json:"uriTemplate" validate:"required"`
    82  	ViewMode    string `json:"viewMode" validate:"required,dive,required,oneof=view read write"`
    83  }
    84  
    85  // ToOCMProtocol convert the protocol to a ocm Protocol struct.
    86  func (w *Webapp) ToOCMProtocol() *ocm.Protocol {
    87  	return ocmshare.NewWebappProtocol(w.URITemplate, utils.GetAppViewMode(w.ViewMode))
    88  }
    89  
    90  // Datatx contains the parameters for the Datatx protocol.
    91  type Datatx struct {
    92  	SharedSecret string `json:"sharedSecret" validate:"required"`
    93  	SourceURI    string `json:"srcUri" validate:"required"`
    94  	Size         uint64 `json:"size" validate:"required"`
    95  }
    96  
    97  // ToOCMProtocol convert the protocol to a ocm Protocol struct.
    98  func (w *Datatx) ToOCMProtocol() *ocm.Protocol {
    99  	return ocmshare.NewTransferProtocol(w.SourceURI, w.SharedSecret, w.Size)
   100  }
   101  
   102  var protocolImpl = map[string]reflect.Type{
   103  	"webdav": reflect.TypeOf(WebDAV{}),
   104  	"webapp": reflect.TypeOf(Webapp{}),
   105  	"datatx": reflect.TypeOf(Datatx{}),
   106  }
   107  
   108  // UnmarshalJSON implements the Unmarshaler interface.
   109  func (p *Protocols) UnmarshalJSON(data []byte) error {
   110  	var prot map[string]json.RawMessage
   111  	if err := json.Unmarshal(data, &prot); err != nil {
   112  		return err
   113  	}
   114  
   115  	*p = []Protocol{}
   116  
   117  	for name, d := range prot {
   118  		var res Protocol
   119  
   120  		// we do not support the OCM v1.0 properties for now, therefore just skip or bail out
   121  		if name == "name" {
   122  			continue
   123  		}
   124  		if name == "options" {
   125  			var opt map[string]any
   126  			if err := json.Unmarshal(d, &opt); err != nil || len(opt) > 0 {
   127  				return fmt.Errorf("protocol options not supported: %s", string(d))
   128  			}
   129  			continue
   130  		}
   131  		ctype, ok := protocolImpl[name]
   132  		if !ok {
   133  			return fmt.Errorf("protocol %s not recognised", name)
   134  		}
   135  		res = reflect.New(ctype).Interface().(Protocol)
   136  		if err := json.Unmarshal(d, &res); err != nil {
   137  			return err
   138  		}
   139  
   140  		*p = append(*p, res)
   141  	}
   142  	return nil
   143  }
   144  
   145  // MarshalJSON implements the Marshaler interface.
   146  func (p Protocols) MarshalJSON() ([]byte, error) {
   147  	if len(p) == 0 {
   148  		return nil, errors.New("no protocol defined")
   149  	}
   150  	d := make(map[string]any)
   151  	for _, prot := range p {
   152  		d[getProtocolName(prot)] = prot
   153  	}
   154  	// fill in the OCM v1.0 properties
   155  	d["name"] = "multi"
   156  	d["options"] = map[string]any{}
   157  	return json.Marshal(d)
   158  }
   159  
   160  func getProtocolName(p Protocol) string {
   161  	n := reflect.TypeOf(p).String()
   162  	s := strings.Split(n, ".")
   163  	return strings.ToLower(s[len(s)-1])
   164  }