This repository has been archived by the owner on Jan 24, 2023. It is now read-only.
/
oauth_requests.go
111 lines (91 loc) · 3.22 KB
/
oauth_requests.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
package main
import (
"errors"
"fmt"
"net/http"
"time"
"github.com/SUSE/stratos-ui/repository/interfaces"
log "github.com/Sirupsen/logrus"
)
func (p *portalProxy) doOauthFlowRequest(cnsiRequest *interfaces.CNSIRequest, req *http.Request) (*http.Response, error) {
log.Debug("doOauthFlowRequest")
// get a cnsi token record and a cnsi record
tokenRec, cnsi, err := p.getCNSIRequestRecords(cnsiRequest)
if err != nil {
return nil, fmt.Errorf("Unable to retrieve CNSI records: %v", err)
}
got401 := false
// Only need to get Client ID once
clientID, err := p.GetClientId(cnsi.CNSIType)
if err != nil {
return nil, interfaces.NewHTTPShadowError(
http.StatusBadRequest,
"Endpoint type has not been registered",
"Endpoint type has not been registered %s: %s", cnsi.CNSIType, err)
}
for {
expTime := time.Unix(tokenRec.TokenExpiry, 0)
if got401 || expTime.Before(time.Now()) {
refreshedTokenRec, err := p.RefreshOAuthToken(cnsi.SkipSSLValidation, cnsiRequest.GUID, cnsiRequest.UserGUID, clientID, "", cnsi.TokenEndpoint)
if err != nil {
log.Info(err)
return nil, fmt.Errorf("Couldn't refresh token for CNSI with GUID %s", cnsiRequest.GUID)
}
tokenRec = refreshedTokenRec
}
req.Header.Set("Authorization", "bearer "+tokenRec.AuthToken)
var client http.Client
if cnsi.SkipSSLValidation {
client = httpClientSkipSSL
} else {
client = httpClient
}
res, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("Request failed: %v", err)
}
if res.StatusCode != 401 {
return res, nil
}
if got401 {
return res, errors.New("Failed to authorize")
}
got401 = true
}
}
func (p *portalProxy) getCNSIRequestRecords(r *interfaces.CNSIRequest) (t interfaces.TokenRecord, c interfaces.CNSIRecord, err error) {
log.Debug("getCNSIRequestRecords")
// look up token
t, ok := p.GetCNSITokenRecord(r.GUID, r.UserGUID)
if !ok {
return t, c, fmt.Errorf("Could not find token for csni:user %s:%s", r.GUID, r.UserGUID)
}
c, err = p.GetCNSIRecord(r.GUID)
if err != nil {
return t, c, fmt.Errorf("Info could not be found for CNSI with GUID %s: %s", r.GUID, err)
}
return t, c, nil
}
func (p *portalProxy) RefreshOAuthToken(skipSSLValidation bool, cnsiGUID, userGUID, client, clientSecret, tokenEndpoint string) (t interfaces.TokenRecord, err error) {
log.Debug("refreshToken")
userToken, ok := p.GetCNSITokenRecordWithDisconnected(cnsiGUID, userGUID)
if !ok {
return t, fmt.Errorf("Info could not be found for user with GUID %s", userGUID)
}
tokenEndpointWithPath := fmt.Sprintf("%s/oauth/token", tokenEndpoint)
uaaRes, err := p.getUAATokenWithRefreshToken(skipSSLValidation, userToken.RefreshToken, client, clientSecret, tokenEndpointWithPath, "")
if err != nil {
return t, fmt.Errorf("Token refresh request failed: %v", err)
}
u, err := p.GetUserTokenInfo(uaaRes.AccessToken)
if err != nil {
return t, fmt.Errorf("Could not get user token info from access token")
}
u.UserGUID = userGUID
tokenRecord := p.InitEndpointTokenRecord(u.TokenExpiry, uaaRes.AccessToken, uaaRes.RefreshToken, userToken.Disconnected)
err = p.setCNSITokenRecord(cnsiGUID, userGUID, tokenRecord)
if err != nil {
return t, fmt.Errorf("Couldn't save new token: %v", err)
}
return tokenRecord, nil
}