oauth.GetGithubData   B
last analyzed

Complexity

Conditions 7

Size

Total Lines 35
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 20
dl 0
loc 35
rs 8
c 0
b 0
f 0
nop 2
1
package oauth
2
3
import (
4
	"bytes"
5
	"context"
6
	"fmt"
7
	"io"
8
	"net/http"
9
10
	"github.com/pkg/errors"
11
)
12
13
const (
14
	githubAccessTokenURL = "https://github.com/login/oauth/access_token" //nolint:gosec //This is a URL, not a password.
15
	githubAPIURL         = "https://api.github.com/user"                 //nolint:gosec //This is a URL, not a password.
16
)
17
18
// githubAccessTokenResponse Represents the response received from Github.
19
type githubAccessTokenResponse struct {
20
	AccessToken string `json:"access_token"`
21
	TokenType   string `json:"token_type"`
22
	Scope       string `json:"scope"`
23
}
24
25
// GetGithubAccessToken gets the access token from Github using the code.
26
func GetGithubAccessToken(ctx context.Context, code string) (string, error) {
27
	// Set us the request body as JSON
28
	requestBodyMap := map[string]string{
29
		"client_id":     githubConfig.ClientID,
30
		"client_secret": githubConfig.ClientSecret,
31
		"code":          code,
32
	}
33
	requestJSON, _ := GetJSONHelperInstance().GetJSONHelper().Marshal(requestBodyMap)
34
35
	// POST request to set URL
36
	req, err := http.NewRequestWithContext(ctx,
37
		http.MethodPost,
38
		githubAccessTokenURL,
39
		bytes.NewBuffer(requestJSON),
40
	)
41
	if err != nil || req == nil || req.Body == nil || req.Header == nil {
42
		return "", errors.Wrap(err, RequestFailed)
43
	}
44
	req.Header.Set("Content-Type", "application/json")
45
	req.Header.Set("Accept", "application/json")
46
47
	// Get the response
48
	resp, err := http.DefaultClient.Do(req)
49
	if err != nil {
50
		return "", errors.Wrap(err, ResponseFailed)
51
	}
52
53
	defer func(resp *http.Response) {
54
		if resp != nil && resp.Body != nil {
55
			resp.Body.Close()
56
		}
57
	}(resp)
58
	// Response body converted to stringified JSON.
59
	respbody, _ := io.ReadAll(resp.Body)
60
61
	// Convert stringified JSON to a struct object of type githubAccessTokenResponse
62
	var ghresp githubAccessTokenResponse
63
	err = GetJSONHelperInstance().GetJSONHelper().Unmarshal(respbody, &ghresp)
64
	if err != nil {
65
		return "", err
66
	}
67
68
	// Return the access token (as the rest of the
69
	// details are relatively unnecessary for us)
70
	return ghresp.AccessToken, nil
71
}
72
73
// GetGithubData gets the user data from Github using the access token.
74
func GetGithubData(ctx context.Context, accessToken string) (string, error) {
75
	// Get request to a set URL
76
	req, err := http.NewRequestWithContext(ctx,
77
		http.MethodGet,
78
		"https://api.github.com/user",
79
		nil,
80
	)
81
	if err != nil {
82
		return "", err
83
	}
84
85
	// Set the Authorization header before sending the request
86
	// Authorization: token XXXXXXXXXXXXXXXXXXXXXXXXXXX
87
	authorizationHeaderValue := fmt.Sprintf("token %s", accessToken)
88
	req.Header.Set("Authorization", authorizationHeaderValue)
89
90
	// Make the request
91
	resp, err := http.DefaultClient.Do(req)
92
	if err != nil {
93
		return "", err
94
	}
95
96
	defer func(resp *http.Response) {
97
		if resp != nil && resp.Body != nil {
98
			resp.Body.Close()
99
		}
100
	}(resp)
101
	// Read the response as a byte slice
102
	respbody, err := io.ReadAll(resp.Body)
103
	if err != nil {
104
		return "", err
105
	}
106
107
	// Convert byte slice to string and return
108
	return string(respbody), nil
109
}
110