github.com/cs3org/reva/v2@v2.27.7/pkg/mentix/exchangers/reqexchanger.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 exchangers 20 21 import ( 22 "fmt" 23 "net/http" 24 "net/url" 25 "strings" 26 27 "github.com/rs/zerolog" 28 29 "github.com/cs3org/reva/v2/pkg/mentix/config" 30 "github.com/cs3org/reva/v2/pkg/mentix/meshdata" 31 ) 32 33 // RequestExchanger is the interface implemented by exchangers that offer an HTTP endpoint. 34 type RequestExchanger interface { 35 // Endpoint returns the (relative) endpoint of the exchanger. 36 Endpoint() string 37 // IsProtectedEndpoint returns true if the endpoint can only be accessed with authorization. 38 IsProtectedEndpoint() bool 39 // WantsRequest returns whether the exchanger wants to handle the incoming request. 40 WantsRequest(r *http.Request) bool 41 // HandleRequest handles the actual HTTP request. 42 HandleRequest(resp http.ResponseWriter, req *http.Request, conf *config.Configuration, log *zerolog.Logger) 43 } 44 45 type queryCallback func(*meshdata.MeshData, url.Values, *config.Configuration, *zerolog.Logger) (int, []byte, error) 46 type extendedQueryCallback func(*meshdata.MeshData, []byte, url.Values, *config.Configuration, *zerolog.Logger) (meshdata.Vector, int, []byte, error) 47 48 // BaseRequestExchanger implements basic exporter functionality common to all request exporters. 49 type BaseRequestExchanger struct { 50 RequestExchanger 51 52 endpoint string 53 isProtectedEndpoint bool 54 55 actionHandlers map[string]queryCallback 56 extendedActionHandlers map[string]extendedQueryCallback 57 } 58 59 // Endpoint returns the (relative) endpoint of the exchanger. 60 func (exchanger *BaseRequestExchanger) Endpoint() string { 61 // Ensure that the endpoint starts with a / 62 endpoint := exchanger.endpoint 63 if !strings.HasPrefix(endpoint, "/") { 64 endpoint = "/" + endpoint 65 } 66 return strings.TrimSpace(endpoint) 67 } 68 69 // IsProtectedEndpoint returns true if the endpoint can only be accessed with authorization. 70 func (exchanger *BaseRequestExchanger) IsProtectedEndpoint() bool { 71 return exchanger.isProtectedEndpoint 72 } 73 74 // SetEndpoint sets the (relative) endpoint of the exchanger. 75 func (exchanger *BaseRequestExchanger) SetEndpoint(endpoint string, isProtected bool) { 76 exchanger.endpoint = endpoint 77 exchanger.isProtectedEndpoint = isProtected 78 } 79 80 // WantsRequest returns whether the exchanger wants to handle the incoming request. 81 func (exchanger *BaseRequestExchanger) WantsRequest(r *http.Request) bool { 82 return r.URL.Path == exchanger.Endpoint() 83 } 84 85 // HandleRequest handles the actual HTTP request. 86 func (exchanger *BaseRequestExchanger) HandleRequest(resp http.ResponseWriter, req *http.Request, conf *config.Configuration, log *zerolog.Logger) error { 87 return nil 88 } 89 90 // RegisterActionHandler registers a new handler for the specified action. 91 func (exchanger *BaseRequestExchanger) RegisterActionHandler(action string, callback queryCallback) { 92 if exchanger.actionHandlers == nil { 93 exchanger.actionHandlers = make(map[string]queryCallback) 94 } 95 exchanger.actionHandlers[action] = callback 96 } 97 98 // RegisterExtendedActionHandler registers a new handler for the specified extended action. 99 func (exchanger *BaseRequestExchanger) RegisterExtendedActionHandler(action string, callback extendedQueryCallback) { 100 if exchanger.extendedActionHandlers == nil { 101 exchanger.extendedActionHandlers = make(map[string]extendedQueryCallback) 102 } 103 exchanger.extendedActionHandlers[action] = callback 104 } 105 106 // HandleAction executes the registered handler for the specified action, if any. 107 func (exchanger *BaseRequestExchanger) HandleAction(meshData *meshdata.MeshData, body []byte, params url.Values, isExtended bool, conf *config.Configuration, log *zerolog.Logger) (meshdata.Vector, int, []byte, error) { 108 reqAction := params.Get("action") 109 110 if isExtended { 111 for action, handler := range exchanger.extendedActionHandlers { 112 if strings.EqualFold(action, reqAction) { 113 return handler(meshData, body, params, conf, log) 114 } 115 } 116 } else { 117 for action, handler := range exchanger.actionHandlers { 118 if strings.EqualFold(action, reqAction) { 119 status, data, err := handler(meshData, params, conf, log) 120 return nil, status, data, err 121 } 122 } 123 } 124 125 return nil, http.StatusNotFound, []byte{}, fmt.Errorf("unhandled query for action '%v'", reqAction) 126 }