-
Notifications
You must be signed in to change notification settings - Fork 14
/
oci_client.go
107 lines (89 loc) · 3.12 KB
/
oci_client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright © 2019, Oracle and/or its affiliates.
package ociauth
import (
"errors"
"fmt"
"net/http"
"net/url"
"path"
"strings"
"time"
"github.com/hashicorp/errwrap"
"github.com/oracle/oci-go-sdk/v59/common"
)
// OciClient stores the client and configuration details for making API requests to OCI Identity Service
type OciClient struct {
common.BaseClient
config *common.ConfigurationProvider
}
// These constants store information related to signing the http request
const (
// requestHeaderDate The key for passing a header to indicate Date
requestHeaderDate = "Date"
// requestHeaderUserAgent The key for passing a header to indicate User Agent
requestHeaderUserAgent = "User-Agent"
defaultScheme = "https"
)
// NewIdentityClientWithConfigurationProvider Creates a new default Identity client with the given configuration provider.
// the configuration provider will be used for the default signer as well as reading the region
func NewOciClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (client OciClient, err error) {
baseClient, err := common.NewClientWithConfig(configProvider)
if err != nil {
return client, err
}
client = OciClient{BaseClient: baseClient}
err = client.setConfigurationProvider(configProvider)
return client, err
}
// SetConfigurationProvider sets the configuration provider including the region, returns an error if is not valid
func (client *OciClient) setConfigurationProvider(configProvider common.ConfigurationProvider) error {
if ok, err := common.IsConfigurationProviderValid(configProvider); !ok {
return err
}
// Error has been checked already
client.config = &configProvider
return nil
}
// ConstructLoginRequest takes in a path and returns a signed http request
func (client OciClient) ConstructLoginRequest(path string) (request http.Request, err error) {
httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, path, request)
if err != nil {
return
}
err = client.prepareRequest(&httpRequest)
if err != nil {
return
}
err = client.Signer.Sign(&httpRequest)
if err != nil {
return
}
request = httpRequest
return
}
// prepareRequest takes in a http request and adds the required information for signing it
func (client *OciClient) prepareRequest(request *http.Request) (err error) {
if client.UserAgent == "" {
return errors.New("user agent can not be blank")
}
if request.Header == nil {
request.Header = http.Header{}
}
request.Header.Set(requestHeaderUserAgent, client.UserAgent)
request.Header.Set(requestHeaderDate, time.Now().UTC().Format(http.TimeFormat))
if !strings.HasPrefix(client.Host, "http://") &&
!strings.HasPrefix(client.Host, "https://") {
client.Host = fmt.Sprintf("%s://%s", defaultScheme, client.Host)
}
clientURL, err := url.Parse(client.Host)
if err != nil {
return errwrap.Wrapf("host is invalid. {{err}}", err)
}
request.URL.Host = clientURL.Host
request.URL.Scheme = clientURL.Scheme
currentPath := request.URL.Path
if !strings.Contains(currentPath, fmt.Sprintf("/%s", client.BasePath)) {
request.URL.Path = path.Clean(fmt.Sprintf("/%s/%s", client.BasePath, currentPath))
}
return
}