-
Notifications
You must be signed in to change notification settings - Fork 1
/
instance.go
177 lines (147 loc) · 4.64 KB
/
instance.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
//go:generate $GOPATH/src/github.com/fortifi/go-api/generate.sh
package api
import (
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/fortifi/go-api/client/authentication"
"github.com/fortifi/go-api/client"
"github.com/fortifi/go-api/models"
"github.com/go-openapi/runtime"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
const (
expiryBuffer = 14400
fortifiOrgHeader = "x-fortifi-org"
fortifiAuthHeader = "authorization"
fortifiBearerTokenSchema = "Bearer %s"
)
var (
debugFortifiRequests = false
unsecureSchemes = []string{"http"}
)
// Instance is a single org API instance
type Instance struct {
expiry int64
apiHost string
organisationFID string
authToken string
user string
key string
apiInstance *client.FortifiAPI
authenticator *Authenticator
hostingProductGroup string
domainProductGroup string
}
// Authenticator auths fortifi requests
type Authenticator struct {
organisationFID string
authtoken string
}
// NewInstance creates a new FortifiInstance with embeded tokenhelper
func NewInstance(orgFid, user, key string) (Instance, error) {
inst := Instance{}
inst.SetOrganisationFID(orgFid)
inst.SetUser(user)
inst.SetKey(key)
return inst, nil
}
// AuthenticateRequest handles request authentication
func (a *Authenticator) AuthenticateRequest(req runtime.ClientRequest, reg strfmt.Registry) error {
req.SetHeaderParam(fortifiOrgHeader, a.organisationFID)
req.SetHeaderParam(fortifiAuthHeader, fmt.Sprintf(fortifiBearerTokenSchema, a.authtoken))
return nil
}
func (a *Authenticator) AuthenticateStdRequest(req http.Request) error {
req.Header.Set(fortifiOrgHeader, a.organisationFID)
req.Header.Set(fortifiAuthHeader, fmt.Sprintf(fortifiBearerTokenSchema, a.authtoken))
return nil
}
// InitAPI called by main function to start the fortifi API and webhook listener
func (f *Instance) InitAPI() error {
_, err := f.GetAPIInstance()
return err
}
// GetAPIInstance returns current instance of fortifi API
func (f *Instance) GetAPIInstance() (*client.FortifiAPI, error) {
if f.apiInstance != nil && time.Now().Unix() < (f.expiry-expiryBuffer) {
return f.apiInstance, nil
}
if f.organisationFID == "" {
return nil, errors.New("Organization FID is required but not set")
}
if f.user == "" {
return nil, errors.New("User is required but not set")
}
if f.key == "" {
return nil, errors.New("Key is required but not set")
}
transport := httptransport.New(f.GetAPIHost(), client.DefaultBasePath, f.GetSchemes())
transport.DefaultAuthentication = f.GetAuthenticator()
transport.SetDebug(debugFortifiRequests)
err := f.getNewToken(transport)
if err != nil {
return nil, fmt.Errorf("Failed to authenticate with Fortifi: %s", err.Error())
}
f.apiInstance = client.New(transport, strfmt.Default)
return f.apiInstance, nil
}
func (f *Instance) getNewToken(transport *httptransport.Runtime) error {
c := client.New(transport, strfmt.Default)
p := authentication.NewGetServiceAuthTokenParams()
p.Payload = &models.ServiceAccountCredentialsPayload{
ID: &f.user,
Key: &f.key,
}
re, err := c.Authentication.GetServiceAuthToken(p)
if err != nil {
return err
}
f.expiry = re.Payload.Data.Expiry
f.authToken = re.Payload.Data.Token
return nil
}
// GetAuthenticator returns fortifi authenticator instance
func (f *Instance) GetAuthenticator() *Authenticator {
return &Authenticator{organisationFID: f.organisationFID, authtoken: f.authToken}
}
// GetSchemes returns the API protocol
func (f *Instance) GetSchemes() []string {
if strings.HasPrefix(f.apiHost, "http://") {
return unsecureSchemes
}
return client.DefaultSchemes
}
// SetLocalDebug determines if local debug vars and logging are used for API
func (f *Instance) SetLocalDebug(s bool) {
debugFortifiRequests = s
}
// SetAPIHost sets fortifi API endpoint
func (f *Instance) SetAPIHost(host string) {
f.apiHost = host
}
// GetAPIHost returns the API host (no schema as per swagger format)
func (f *Instance) GetAPIHost() string {
host := client.DefaultHost
if f.apiHost != "" {
host = strings.TrimPrefix(f.apiHost, "https://")
host = strings.TrimPrefix(host, "http://")
}
return host
}
// SetOrganisationFID sets the organisation fid used by the fortifi API
// this is case sensitive
func (f *Instance) SetOrganisationFID(of string) {
f.organisationFID = of
}
// SetUser sets the user ID (This should be a service account) used by the fortifi API
func (f *Instance) SetUser(u string) {
f.user = u
}
// SetKey sets the key for given User ID used by the fortifi API
func (f *Instance) SetKey(k string) {
f.key = k
}