gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 := &gtsmodel.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 := &gtsmodel.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 }