github.com/cs3org/reva/v2@v2.27.7/pkg/auth/manager/nextcloud/nextcloud_server_mock.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 nextcloud
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  	"io"
    25  	"net"
    26  	"net/http"
    27  	"net/http/httptest"
    28  	"strings"
    29  )
    30  
    31  // Response contains data for the Nextcloud mock server to respond
    32  // and to switch to a new server state
    33  type Response struct {
    34  	code           int
    35  	body           string
    36  	newServerState string
    37  }
    38  
    39  const serverStateError = "ERROR"
    40  const serverStateEmpty = "EMPTY"
    41  const serverStateHome = "HOME"
    42  
    43  var serverState = serverStateEmpty
    44  
    45  var responses = map[string]Response{
    46  	`POST /apps/sciencemesh/~einstein/api/auth/Authenticate {"clientID":"einstein","clientSecret":"relativity"}`: {200, `{"user":{"id":{"idp":"some-idp","opaque_id":"some-opaque-user-id","type":1}},"scopes":{"user":{"resource":{"decoder":"json","value":"eyJyZXNvdXJjZV9pZCI6eyJzdG9yYWdlX2lkIjoic3RvcmFnZS1pZCIsIm9wYXF1ZV9pZCI6Im9wYXF1ZS1pZCJ9LCJwYXRoIjoic29tZS9maWxlL3BhdGgudHh0In0="},"role":1}}}`, serverStateHome},
    47  }
    48  
    49  // GetNextcloudServerMock returns a handler that pretends to be a remote Nextcloud server
    50  func GetNextcloudServerMock(called *[]string) http.Handler {
    51  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    52  		buf := new(strings.Builder)
    53  		_, err := io.Copy(buf, r.Body)
    54  		if err != nil {
    55  			panic("Error reading response into buffer")
    56  		}
    57  		var key = fmt.Sprintf("%s %s %s", r.Method, r.URL, buf.String())
    58  		*called = append(*called, key)
    59  		response := responses[key]
    60  		if (response == Response{}) {
    61  			key = fmt.Sprintf("%s %s %s %s", r.Method, r.URL, buf.String(), serverState)
    62  			response = responses[key]
    63  		}
    64  		if (response == Response{}) {
    65  			fmt.Printf("%s %s %s %s", r.Method, r.URL, buf.String(), serverState)
    66  			response = Response{500, fmt.Sprintf("response not defined! %s", key), serverStateEmpty}
    67  		}
    68  		serverState = responses[key].newServerState
    69  		if serverState == `` {
    70  			serverState = serverStateError
    71  		}
    72  		w.WriteHeader(response.code)
    73  		// w.Header().Set("Etag", "mocker-etag")
    74  		_, err = w.Write([]byte(responses[key].body))
    75  		if err != nil {
    76  			panic(err)
    77  		}
    78  	})
    79  }
    80  
    81  // TestingHTTPClient thanks to https://itnext.io/how-to-stub-requests-to-remote-hosts-with-go-6c2c1db32bf2
    82  // Ideally, this function would live in tests/helpers, but
    83  // if we put it there, it gets excluded by .dockerignore, and the
    84  // Docker build fails (see https://github.com/cs3org/reva/issues/1999)
    85  // So putting it here for now - open to suggestions if someone knows
    86  // a better way to inject this.
    87  func TestingHTTPClient(handler http.Handler) (*http.Client, func()) {
    88  	s := httptest.NewServer(handler)
    89  
    90  	cli := &http.Client{
    91  		Transport: &http.Transport{
    92  			DialContext: func(_ context.Context, network, _ string) (net.Conn, error) {
    93  				return net.Dial(network, s.Listener.Addr().String())
    94  			},
    95  		},
    96  	}
    97  
    98  	return cli, s.Close
    99  }