generated from datumforge/go-template
-
Notifications
You must be signed in to change notification settings - Fork 5
/
login.go
135 lines (105 loc) · 3.13 KB
/
login.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
package datumclient
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
echo "github.com/datumforge/echox"
"golang.org/x/oauth2"
"github.com/datumforge/datum/internal/httpserve/handlers"
"github.com/datumforge/datum/internal/httpserve/route"
"github.com/datumforge/datum/pkg/auth"
"github.com/datumforge/datum/pkg/sessions"
)
// Login creates a login request to the Datum API
func Login(c *Client, ctx context.Context, login handlers.LoginRequest) (*oauth2.Token, error) {
method := http.MethodPost
endpoint := "login"
u := fmt.Sprintf("%s%s/%s", c.Client.BaseURL, route.V1Version, endpoint)
queryURL, err := url.Parse(u)
if err != nil {
return nil, err
}
req, err := http.NewRequestWithContext(ctx, method, queryURL.String(), nil)
if err != nil {
return nil, err
}
// Set Headers
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
b, err := json.Marshal(login)
if err != nil {
return nil, err
}
req.Body = io.NopCloser(bytes.NewBuffer(b))
resp, err := c.Client.Client.Do(req.WithContext(ctx))
if err != nil {
return nil, err
}
defer resp.Body.Close()
out := handlers.LoginReply{}
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, newAuthenticationError(resp.StatusCode, out.Message)
}
return getTokensFromCookiesFromResponse(resp), nil
}
// getTokensFromCookies returns the access and refresh tokens from the http cookies
func getTokensFromCookies(cookies []*http.Cookie) (token *oauth2.Token) {
token = &oauth2.Token{}
for _, c := range cookies {
if c.Name == auth.AccessTokenCookie {
token.AccessToken = c.Value
}
if c.Name == auth.RefreshTokenCookie {
token.RefreshToken = c.Value
}
}
return token
}
// getTokensFromCookiesFromResponse parses the HTTP Response for cookies and returns the access and refresh tokens
func getTokensFromCookiesFromResponse(resp *http.Response) (token *oauth2.Token) {
// parse cookies
cookies := resp.Cookies()
return getTokensFromCookies(cookies)
}
// getTokensFromCookieRequest parses the HTTP Request for cookies and returns the session and access and refresh tokens
func getTokensFromCookieRequest(r *http.Request, isDev bool) (token *oauth2.Token, session string) {
// parse cookies
cookies := r.Cookies()
cookieName := sessions.DefaultCookieName
// Use the dev cookie when running on localhost
if isDev {
cookieName = sessions.DevCookieName
}
for _, c := range cookies {
if c.Name == cookieName {
session = c.Value
}
}
return getTokensFromCookies(cookies), session
}
// GetSessionFromCookieJar parses the cookie jar for the session cookie
func GetSessionFromCookieJar(c *Client) (sessionID string, err error) {
u, err := url.Parse(c.Client.BaseURL)
if err != nil {
return "", err
}
cookies := c.Client.Client.Jar.Cookies(u)
cookieName := sessions.DefaultCookieName
// Use the dev cookie when running on localhost
if strings.Contains(u.Host, "localhost") {
cookieName = sessions.DevCookieName
}
for _, c := range cookies {
if c.Name == cookieName {
return c.Value, nil
}
}
return "", nil
}