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