Skip to content

Commit c80ac48

Browse files
author
lleadbet
committed
fixing typo + add validate endpoint
1 parent 723f5fc commit c80ac48

File tree

11 files changed

+159
-25
lines changed

11 files changed

+159
-25
lines changed

internal/mock_api/endpoints/bits/cheermotes.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ func getCheermotes(w http.ResponseWriter, r *http.Request) {
128128
cheermoteBody = append(cheermoteBody, cheermote)
129129
}
130130

131-
resposne, _ := json.Marshal(cheermoteBody)
132-
w.Write(resposne)
131+
response, _ := json.Marshal(cheermoteBody)
132+
w.Write(response)
133133
}
134134

135135
func generateCheermoteImageSizes(prefix string, theme string, imageType string, bits int) CheermoteImageSizes {

internal/mock_api/endpoints/clips/clips.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,21 @@ func getClips(w http.ResponseWriter, r *http.Request) {
9292
}
9393

9494
clips := dbr.Data.([]database.Clip)
95-
apiResposne := models.APIResponse{
95+
apiResponse := models.APIResponse{
9696
Data: clips,
9797
}
9898

99-
if len(apiResposne.Data.([]database.Clip)) == 0 {
100-
apiResposne.Data = []string{}
99+
if len(apiResponse.Data.([]database.Clip)) == 0 {
100+
apiResponse.Data = []string{}
101101
}
102102

103103
if dbr.Limit == len(dbr.Data.([]database.Clip)) {
104-
apiResposne.Pagination = &models.APIPagination{
104+
apiResponse.Pagination = &models.APIPagination{
105105
Cursor: dbr.Cursor,
106106
}
107107
}
108108

109-
bytes, _ := json.Marshal(apiResposne)
109+
bytes, _ := json.Marshal(apiResponse)
110110
w.Write(bytes)
111111
}
112112

internal/mock_api/endpoints/polls/polls.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,17 @@ func getPolls(w http.ResponseWriter, r *http.Request) {
110110
polls = append(polls, dbr.Data.([]database.Poll)...)
111111
}
112112

113-
apiResposne := models.APIResponse{
113+
apiResponse := models.APIResponse{
114114
Data: polls,
115115
}
116116

117117
if dbr != nil && dbr.Cursor != "" {
118-
apiResposne.Pagination = &models.APIPagination{
118+
apiResponse.Pagination = &models.APIPagination{
119119
Cursor: dbr.Cursor,
120120
}
121121
}
122122

123-
bytes, _ := json.Marshal(apiResposne)
123+
bytes, _ := json.Marshal(apiResponse)
124124
w.Write(bytes)
125125
}
126126

@@ -231,16 +231,16 @@ func patchPolls(w http.ResponseWriter, r *http.Request) {
231231
return
232232
}
233233

234-
apiResposne := models.APIResponse{
234+
apiResponse := models.APIResponse{
235235
Data: dbr.Data,
236236
}
237237

238238
if dbr.Cursor != "" {
239-
apiResposne.Pagination = &models.APIPagination{
239+
apiResponse.Pagination = &models.APIPagination{
240240
Cursor: dbr.Cursor,
241241
}
242242
}
243243

244-
bytes, _ := json.Marshal(apiResposne)
244+
bytes, _ := json.Marshal(apiResponse)
245245
w.Write(bytes)
246246
}

internal/mock_api/endpoints/predictions/predictions.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,17 @@ func getPredictions(w http.ResponseWriter, r *http.Request) {
110110
predictions = append(predictions, dbr.Data.([]database.Prediction)...)
111111
}
112112

113-
apiResposne := models.APIResponse{
113+
apiResponse := models.APIResponse{
114114
Data: predictions,
115115
}
116116

117117
if dbr != nil && dbr.Cursor != "" {
118-
apiResposne.Pagination = &models.APIPagination{
118+
apiResponse.Pagination = &models.APIPagination{
119119
Cursor: dbr.Cursor,
120120
}
121121
}
122122

123-
bytes, _ := json.Marshal(apiResposne)
123+
bytes, _ := json.Marshal(apiResponse)
124124
w.Write(bytes)
125125
}
126126

internal/mock_api/endpoints/streams/streamkey.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var streamKeyScopesByMethod = map[string][]string{
3232

3333
type StreamKey struct{}
3434

35-
type StreamKeyResposne struct {
35+
type StreamKeyResponse struct {
3636
StreamKey string `json:"stream_key"`
3737
}
3838

@@ -66,7 +66,7 @@ func getStreamKey(w http.ResponseWriter, r *http.Request) {
6666
return
6767
}
6868

69-
streamKeys := []StreamKeyResposne{{StreamKey: fmt.Sprintf("live_%v_%v", userCtx.UserID, util.RandomGUID())}}
69+
streamKeys := []StreamKeyResponse{{StreamKey: fmt.Sprintf("live_%v_%v", userCtx.UserID, util.RandomGUID())}}
7070

7171
bytes, _ := json.Marshal(models.APIResponse{Data: streamKeys})
7272
w.Write(bytes)

internal/mock_api/endpoints/teams/channel_teams.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var channelTeamsScopesByMethod = map[string][]string{
2828
}
2929

3030
type ChannelTeams struct{}
31-
type ChannelTeamResposne struct {
31+
type ChannelTeamResponse struct {
3232
ID string `json:"id"`
3333
BackgroundImageUrl *string `json:"background_image_url"`
3434
Banner *string `json:"banner"`
@@ -77,9 +77,9 @@ func getChannelTeams(w http.ResponseWriter, r *http.Request) {
7777
if len(team) == 0 {
7878
dbr.Data = make([]database.Team, 0)
7979
}
80-
response := []ChannelTeamResposne{}
80+
response := []ChannelTeamResponse{}
8181
for _, t := range team {
82-
response = append(response, ChannelTeamResposne{
82+
response = append(response, ChannelTeamResponse{
8383
ID: t.ID,
8484
Info: t.Info,
8585
BackgroundImageUrl: t.BackgroundImageUrl,

internal/mock_auth/app_access_token.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type AppAccessTokenRequestBody struct {
2222
Scope string `json:"scope"`
2323
}
2424

25-
type AppAccessTokenEndpointResposne struct {
25+
type AppAccessTokenEndpointResponse struct {
2626
AccessToken string `json:"access_token"`
2727
RefreshToken string `json:"refresh_token"`
2828
ExpiresIn int `json:"expires_in"`
@@ -111,7 +111,7 @@ func (e AppAccessTokenEndpoint) ServeHTTP(w http.ResponseWriter, r *http.Request
111111
return
112112
}
113113
ea, _ := time.Parse(time.RFC3339, a.ExpiresAt)
114-
ater := AppAccessTokenEndpointResposne{
114+
ater := AppAccessTokenEndpointResponse{
115115
AccessToken: auth.Token,
116116
RefreshToken: "",
117117
ExpiresIn: int(ea.Sub(time.Now().UTC()).Seconds()),

internal/mock_auth/mock_auth.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ var validScopesByTokenType = map[string]map[string]bool{
5858

5959
func All() []AuthEndpoint {
6060
return []AuthEndpoint{
61-
UserTokenEndpoint{},
6261
AppAccessTokenEndpoint{},
62+
UserTokenEndpoint{},
63+
ValidateTokenEndpoint{},
6364
}
6465
}
6566

internal/mock_auth/mock_auth_test.go

+48
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ package mock_auth
44

55
import (
66
"context"
7+
"fmt"
78
"log"
89
"net/http"
910
"net/http/httptest"
11+
"os"
1012
"testing"
13+
"time"
1114

1215
"github.com/stretchr/testify/assert"
1316
"github.com/twitchdev/twitch-cli/internal/database"
@@ -19,6 +22,10 @@ var a *assert.Assertions
1922
var firstRun = true
2023
var ac = database.AuthenticationClient{ID: "222", Secret: "333", Name: "test_client", IsExtension: false}
2124

25+
func TestMain(m *testing.M) {
26+
27+
os.Exit(m.Run())
28+
}
2229
func TestAreValidScopes(t *testing.T) {
2330
a := test_setup.SetupTestEnv(t)
2431

@@ -70,6 +77,46 @@ func TestUserToken(t *testing.T) {
7077
a.Equal(400, resp.StatusCode)
7178
}
7279

80+
func TestValidateToken(t *testing.T) {
81+
a = test_setup.SetupTestEnv(t)
82+
ts := httptest.NewServer(baseMiddleware(ValidateTokenEndpoint{}))
83+
84+
req, _ := http.NewRequest(http.MethodGet, ts.URL+ValidateTokenEndpoint{}.Path(), nil)
85+
resp, err := http.DefaultClient.Do(req)
86+
a.Nil(err, err)
87+
a.Equal(401, resp.StatusCode)
88+
89+
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", "auth.Token"))
90+
resp, err = http.DefaultClient.Do(req)
91+
a.Nil(err, err)
92+
a.Equal(401, resp.StatusCode)
93+
94+
db, err := database.NewConnection()
95+
a.Nil(err, err)
96+
defer db.DB.Close()
97+
98+
auth, err := db.NewQuery(nil, 0).CreateAuthorization(database.Authorization{
99+
ClientID: ac.ID,
100+
ExpiresAt: util.GetTimestamp().Add(time.Hour * 4).Format(time.RFC3339),
101+
Scopes: "",
102+
})
103+
104+
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", auth.Token))
105+
resp, err = http.DefaultClient.Do(req)
106+
a.Nil(err, err)
107+
a.Equal(200, resp.StatusCode)
108+
109+
auth, err = db.NewQuery(nil, 0).CreateAuthorization(database.Authorization{
110+
ClientID: ac.ID,
111+
ExpiresAt: util.GetTimestamp().Add(time.Hour * 4).Format(time.RFC3339),
112+
Scopes: "user:read:email",
113+
UserID: "1",
114+
})
115+
req.Header.Set("Authorization", fmt.Sprintf("Oauth %v", auth.Token))
116+
resp, err = http.DefaultClient.Do(req)
117+
a.Nil(err, err)
118+
a.Equal(200, resp.StatusCode)
119+
}
73120
func TestAppAccessToken(t *testing.T) {
74121
a = test_setup.SetupTestEnv(t)
75122
ts := httptest.NewServer(baseMiddleware(AppAccessTokenEndpoint{}))
@@ -99,6 +146,7 @@ func TestAppAccessToken(t *testing.T) {
99146
a.Nil(err)
100147
a.Equal(200, resp.StatusCode)
101148
}
149+
102150
func baseMiddleware(next http.Handler) http.Handler {
103151
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
104152
ctx := context.Background()

internal/mock_auth/user_token.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func (e UserTokenEndpoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {
7777
return
7878
}
7979
ea, _ := time.Parse(time.RFC3339, a.ExpiresAt)
80-
ater := AppAccessTokenEndpointResposne{
80+
ater := AppAccessTokenEndpointResponse{
8181
AccessToken: auth.Token,
8282
RefreshToken: "",
8383
ExpiresIn: int(ea.Sub(time.Now().UTC()).Seconds()),

internal/mock_auth/validate.go

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
package mock_auth
4+
5+
import (
6+
"encoding/json"
7+
"net/http"
8+
"strings"
9+
"time"
10+
11+
"github.com/twitchdev/twitch-cli/internal/database"
12+
)
13+
14+
type ValidateTokenEndpoint struct{}
15+
16+
type ValidateTokenEndpointResponse struct {
17+
ClientID string `json:"client_id"`
18+
UserID string `json:"user_id,omitempty"`
19+
UserLogin string `json:"login,omitempty"`
20+
ExpiresIn int `json:"expires_in"`
21+
Scopes []string `json:"scopes"`
22+
}
23+
24+
func (e ValidateTokenEndpoint) Path() string { return "/validate" }
25+
26+
func (e ValidateTokenEndpoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {
27+
db = r.Context().Value("db").(database.CLIDatabase)
28+
29+
if r.Method != http.MethodGet {
30+
w.WriteHeader(http.StatusMethodNotAllowed)
31+
return
32+
}
33+
34+
tokenHeader := r.Header.Get("Authorization")
35+
if tokenHeader == "" || len(tokenHeader) < 7 {
36+
w.WriteHeader(http.StatusUnauthorized)
37+
return
38+
}
39+
40+
token := ""
41+
// handle prefixes
42+
h := strings.ToLower(tokenHeader)
43+
if strings.HasPrefix(h, "oauth ") {
44+
token = tokenHeader[6:]
45+
} else if strings.HasPrefix(h, "bearer ") {
46+
token = tokenHeader[7:]
47+
}
48+
println(token)
49+
auth, err := db.NewQuery(r, 100).GetAuthorizationByToken(token)
50+
if err != nil || auth.ID == 0 {
51+
w.WriteHeader(http.StatusUnauthorized)
52+
return
53+
}
54+
55+
expiresAt, _ := time.Parse(time.RFC3339, auth.ExpiresAt)
56+
57+
diff := expiresAt.Sub(time.Now())
58+
59+
scopes := []string{}
60+
for _, s := range strings.Split(auth.Scopes, " ") {
61+
if s != "" {
62+
scopes = append(scopes, s)
63+
}
64+
}
65+
resp := ValidateTokenEndpointResponse{
66+
ClientID: auth.ClientID,
67+
UserID: auth.UserID,
68+
Scopes: scopes,
69+
ExpiresIn: int(diff.Seconds()),
70+
}
71+
if auth.UserID != "" {
72+
user, err := db.NewQuery(r, 100).GetUser(database.User{ID: auth.UserID})
73+
if err != nil {
74+
w.WriteHeader(http.StatusInternalServerError)
75+
return
76+
}
77+
resp.UserLogin = user.UserLogin
78+
}
79+
80+
err = json.NewEncoder(w).Encode(resp)
81+
if err != nil {
82+
w.WriteHeader(http.StatusInternalServerError)
83+
return
84+
}
85+
}

0 commit comments

Comments
 (0)