gtsocial-umbx

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

passwordchange_test.go (6367B)


      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 user_test
     19 
     20 import (
     21 	"context"
     22 	"fmt"
     23 	"io/ioutil"
     24 	"net/http"
     25 	"net/http/httptest"
     26 	"net/url"
     27 	"testing"
     28 
     29 	"github.com/stretchr/testify/suite"
     30 	"github.com/superseriousbusiness/gotosocial/internal/api/client/user"
     31 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
     32 	"github.com/superseriousbusiness/gotosocial/internal/oauth"
     33 	"github.com/superseriousbusiness/gotosocial/testrig"
     34 	"golang.org/x/crypto/bcrypt"
     35 )
     36 
     37 type PasswordChangeTestSuite struct {
     38 	UserStandardTestSuite
     39 }
     40 
     41 func (suite *PasswordChangeTestSuite) TestPasswordChangePOST() {
     42 	t := suite.testTokens["local_account_1"]
     43 	oauthToken := oauth.DBTokenToToken(t)
     44 
     45 	recorder := httptest.NewRecorder()
     46 	ctx, _ := testrig.CreateGinTestContext(recorder, nil)
     47 	ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
     48 	ctx.Set(oauth.SessionAuthorizedToken, oauthToken)
     49 	ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"])
     50 	ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"])
     51 	ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080%s", user.PasswordChangePath), nil)
     52 	ctx.Request.Header.Set("accept", "application/json")
     53 	ctx.Request.Form = url.Values{
     54 		"old_password": {"password"},
     55 		"new_password": {"peepeepoopoopassword"},
     56 	}
     57 	suite.userModule.PasswordChangePOSTHandler(ctx)
     58 
     59 	// check response
     60 	suite.EqualValues(http.StatusOK, recorder.Code)
     61 
     62 	dbUser := &gtsmodel.User{}
     63 	err := suite.db.GetByID(context.Background(), suite.testUsers["local_account_1"].ID, dbUser)
     64 	suite.NoError(err)
     65 
     66 	// new password should pass
     67 	err = bcrypt.CompareHashAndPassword([]byte(dbUser.EncryptedPassword), []byte("peepeepoopoopassword"))
     68 	suite.NoError(err)
     69 
     70 	// old password should fail
     71 	err = bcrypt.CompareHashAndPassword([]byte(dbUser.EncryptedPassword), []byte("password"))
     72 	suite.EqualError(err, "crypto/bcrypt: hashedPassword is not the hash of the given password")
     73 }
     74 
     75 func (suite *PasswordChangeTestSuite) TestPasswordMissingOldPassword() {
     76 	t := suite.testTokens["local_account_1"]
     77 	oauthToken := oauth.DBTokenToToken(t)
     78 
     79 	recorder := httptest.NewRecorder()
     80 	ctx, _ := testrig.CreateGinTestContext(recorder, nil)
     81 	ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
     82 	ctx.Set(oauth.SessionAuthorizedToken, oauthToken)
     83 	ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"])
     84 	ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"])
     85 	ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080%s", user.PasswordChangePath), nil)
     86 	ctx.Request.Header.Set("accept", "application/json")
     87 	ctx.Request.Form = url.Values{
     88 		"new_password": {"peepeepoopoopassword"},
     89 	}
     90 	suite.userModule.PasswordChangePOSTHandler(ctx)
     91 
     92 	// check response
     93 	suite.EqualValues(http.StatusBadRequest, recorder.Code)
     94 
     95 	result := recorder.Result()
     96 	defer result.Body.Close()
     97 	b, err := ioutil.ReadAll(result.Body)
     98 	suite.NoError(err)
     99 	suite.Equal(`{"error":"Bad Request: password change request missing field old_password"}`, string(b))
    100 }
    101 
    102 func (suite *PasswordChangeTestSuite) TestPasswordIncorrectOldPassword() {
    103 	t := suite.testTokens["local_account_1"]
    104 	oauthToken := oauth.DBTokenToToken(t)
    105 
    106 	recorder := httptest.NewRecorder()
    107 	ctx, _ := testrig.CreateGinTestContext(recorder, nil)
    108 	ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
    109 	ctx.Set(oauth.SessionAuthorizedToken, oauthToken)
    110 	ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"])
    111 	ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"])
    112 	ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080%s", user.PasswordChangePath), nil)
    113 	ctx.Request.Header.Set("accept", "application/json")
    114 	ctx.Request.Form = url.Values{
    115 		"old_password": {"notright"},
    116 		"new_password": {"peepeepoopoopassword"},
    117 	}
    118 	suite.userModule.PasswordChangePOSTHandler(ctx)
    119 
    120 	// check response
    121 	suite.EqualValues(http.StatusUnauthorized, recorder.Code)
    122 
    123 	result := recorder.Result()
    124 	defer result.Body.Close()
    125 	b, err := ioutil.ReadAll(result.Body)
    126 	suite.NoError(err)
    127 	suite.Equal(`{"error":"Unauthorized: old password was incorrect"}`, string(b))
    128 }
    129 
    130 func (suite *PasswordChangeTestSuite) TestPasswordWeakNewPassword() {
    131 	t := suite.testTokens["local_account_1"]
    132 	oauthToken := oauth.DBTokenToToken(t)
    133 
    134 	recorder := httptest.NewRecorder()
    135 	ctx, _ := testrig.CreateGinTestContext(recorder, nil)
    136 	ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
    137 	ctx.Set(oauth.SessionAuthorizedToken, oauthToken)
    138 	ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"])
    139 	ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"])
    140 	ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080%s", user.PasswordChangePath), nil)
    141 	ctx.Request.Header.Set("accept", "application/json")
    142 	ctx.Request.Form = url.Values{
    143 		"old_password": {"password"},
    144 		"new_password": {"peepeepoopoo"},
    145 	}
    146 	suite.userModule.PasswordChangePOSTHandler(ctx)
    147 
    148 	// check response
    149 	suite.EqualValues(http.StatusBadRequest, recorder.Code)
    150 
    151 	result := recorder.Result()
    152 	defer result.Body.Close()
    153 	b, err := ioutil.ReadAll(result.Body)
    154 	suite.NoError(err)
    155 	suite.Equal(`{"error":"Bad Request: password is only 94% strength, try including more special characters, using uppercase letters, using numbers or using a longer password"}`, string(b))
    156 }
    157 
    158 func TestPasswordChangeTestSuite(t *testing.T) {
    159 	suite.Run(t, &PasswordChangeTestSuite{})
    160 }