token_test.go (6772B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package auth_test 19 20 import ( 21 "context" 22 "encoding/json" 23 "io/ioutil" 24 "net/http" 25 "testing" 26 "time" 27 28 "github.com/stretchr/testify/suite" 29 apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" 30 "github.com/superseriousbusiness/gotosocial/internal/db" 31 "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 32 "github.com/superseriousbusiness/gotosocial/testrig" 33 ) 34 35 type TokenTestSuite struct { 36 AuthStandardTestSuite 37 } 38 39 func (suite *TokenTestSuite) TestPOSTTokenEmptyForm() { 40 ctx, recorder := suite.newContext(http.MethodPost, "oauth/token", []byte{}, "") 41 ctx.Request.Header.Set("accept", "application/json") 42 43 suite.authModule.TokenPOSTHandler(ctx) 44 45 suite.Equal(http.StatusBadRequest, recorder.Code) 46 47 result := recorder.Result() 48 defer result.Body.Close() 49 50 b, err := ioutil.ReadAll(result.Body) 51 suite.NoError(err) 52 53 suite.Equal(`{"error":"invalid_request","error_description":"Bad Request: grant_type was not set in the token request form, but must be set to authorization_code or client_credentials: client_id was not set in the token request form: client_secret was not set in the token request form: redirect_uri was not set in the token request form"}`, string(b)) 54 } 55 56 func (suite *TokenTestSuite) TestRetrieveClientCredentialsOK() { 57 testClient := suite.testClients["local_account_1"] 58 59 requestBody, w, err := testrig.CreateMultipartFormData( 60 "", "", 61 map[string]string{ 62 "grant_type": "client_credentials", 63 "client_id": testClient.ID, 64 "client_secret": testClient.Secret, 65 "redirect_uri": "http://localhost:8080", 66 }) 67 if err != nil { 68 panic(err) 69 } 70 bodyBytes := requestBody.Bytes() 71 72 ctx, recorder := suite.newContext(http.MethodPost, "oauth/token", bodyBytes, w.FormDataContentType()) 73 ctx.Request.Header.Set("accept", "application/json") 74 75 suite.authModule.TokenPOSTHandler(ctx) 76 77 suite.Equal(http.StatusOK, recorder.Code) 78 79 result := recorder.Result() 80 defer result.Body.Close() 81 82 b, err := ioutil.ReadAll(result.Body) 83 suite.NoError(err) 84 85 t := &apimodel.Token{} 86 err = json.Unmarshal(b, t) 87 suite.NoError(err) 88 89 suite.Equal("Bearer", t.TokenType) 90 suite.NotEmpty(t.AccessToken) 91 suite.NotEmpty(t.CreatedAt) 92 suite.WithinDuration(time.Now(), time.Unix(t.CreatedAt, 0), 1*time.Minute) 93 94 // there should be a token in the database now too 95 dbToken := >smodel.Token{} 96 err = suite.db.GetWhere(context.Background(), []db.Where{{Key: "access", Value: t.AccessToken}}, dbToken) 97 suite.NoError(err) 98 suite.NotNil(dbToken) 99 } 100 101 func (suite *TokenTestSuite) TestRetrieveAuthorizationCodeOK() { 102 testClient := suite.testClients["local_account_1"] 103 testUserAuthorizationToken := suite.testTokens["local_account_1_user_authorization_token"] 104 105 requestBody, w, err := testrig.CreateMultipartFormData( 106 "", "", 107 map[string]string{ 108 "grant_type": "authorization_code", 109 "client_id": testClient.ID, 110 "client_secret": testClient.Secret, 111 "redirect_uri": "http://localhost:8080", 112 "code": testUserAuthorizationToken.Code, 113 }) 114 if err != nil { 115 panic(err) 116 } 117 bodyBytes := requestBody.Bytes() 118 119 ctx, recorder := suite.newContext(http.MethodPost, "oauth/token", bodyBytes, w.FormDataContentType()) 120 ctx.Request.Header.Set("accept", "application/json") 121 122 suite.authModule.TokenPOSTHandler(ctx) 123 124 suite.Equal(http.StatusOK, recorder.Code) 125 126 result := recorder.Result() 127 defer result.Body.Close() 128 129 b, err := ioutil.ReadAll(result.Body) 130 suite.NoError(err) 131 132 t := &apimodel.Token{} 133 err = json.Unmarshal(b, t) 134 suite.NoError(err) 135 136 suite.Equal("Bearer", t.TokenType) 137 suite.NotEmpty(t.AccessToken) 138 suite.NotEmpty(t.CreatedAt) 139 suite.WithinDuration(time.Now(), time.Unix(t.CreatedAt, 0), 1*time.Minute) 140 141 dbToken := >smodel.Token{} 142 err = suite.db.GetWhere(context.Background(), []db.Where{{Key: "access", Value: t.AccessToken}}, dbToken) 143 suite.NoError(err) 144 suite.NotNil(dbToken) 145 } 146 147 func (suite *TokenTestSuite) TestRetrieveAuthorizationCodeNoCode() { 148 testClient := suite.testClients["local_account_1"] 149 150 requestBody, w, err := testrig.CreateMultipartFormData( 151 "", "", 152 map[string]string{ 153 "grant_type": "authorization_code", 154 "client_id": testClient.ID, 155 "client_secret": testClient.Secret, 156 "redirect_uri": "http://localhost:8080", 157 }) 158 if err != nil { 159 panic(err) 160 } 161 bodyBytes := requestBody.Bytes() 162 163 ctx, recorder := suite.newContext(http.MethodPost, "oauth/token", bodyBytes, w.FormDataContentType()) 164 ctx.Request.Header.Set("accept", "application/json") 165 166 suite.authModule.TokenPOSTHandler(ctx) 167 168 suite.Equal(http.StatusBadRequest, recorder.Code) 169 170 result := recorder.Result() 171 defer result.Body.Close() 172 173 b, err := ioutil.ReadAll(result.Body) 174 suite.NoError(err) 175 176 suite.Equal(`{"error":"invalid_request","error_description":"Bad Request: code was not set in the token request form, but must be set since grant_type is authorization_code"}`, string(b)) 177 } 178 179 func (suite *TokenTestSuite) TestRetrieveAuthorizationCodeWrongGrantType() { 180 testClient := suite.testClients["local_account_1"] 181 182 requestBody, w, err := testrig.CreateMultipartFormData( 183 "", "", 184 map[string]string{ 185 "grant_type": "client_credentials", 186 "client_id": testClient.ID, 187 "client_secret": testClient.Secret, 188 "redirect_uri": "http://localhost:8080", 189 "code": "peepeepoopoo", 190 }) 191 if err != nil { 192 panic(err) 193 } 194 bodyBytes := requestBody.Bytes() 195 196 ctx, recorder := suite.newContext(http.MethodPost, "oauth/token", bodyBytes, w.FormDataContentType()) 197 ctx.Request.Header.Set("accept", "application/json") 198 199 suite.authModule.TokenPOSTHandler(ctx) 200 201 suite.Equal(http.StatusBadRequest, recorder.Code) 202 203 result := recorder.Result() 204 defer result.Body.Close() 205 206 b, err := ioutil.ReadAll(result.Body) 207 suite.NoError(err) 208 209 suite.Equal(`{"error":"invalid_request","error_description":"Bad Request: a code was provided in the token request form, but grant_type was not set to authorization_code"}`, string(b)) 210 } 211 212 func TestTokenTestSuite(t *testing.T) { 213 suite.Run(t, &TokenTestSuite{}) 214 }