mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] add authorization to the already-existing authentication (#365)
* add ensureUserIsAuthorizedOrRedirect to /oauth/authorize * adding authorization (email confirm, account approve, etc) to TokenCheck * revert un-needed changes to signin.go * oops what happened here * error css * add account.SuspendedAt check * remove redundant checks from oauth util Authed function * wip tests * tests passing * stop stripping useful information from ErrAlreadyExists * that feeling of scraping the dryer LINT off the screen * oops I didn't mean to get rid of this NewTestRouter function * make tests work with recorder * re-add ConfigureTemplatesWithGin to handle template path err Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
This commit is contained in:
113
internal/api/client/auth/authorize_test.go
Normal file
113
internal/api/client/auth/authorize_test.go
Normal file
@ -0,0 +1,113 @@
|
||||
package auth_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"codeberg.org/gruf/go-errors"
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/client/auth"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
)
|
||||
|
||||
type AuthAuthorizeTestSuite struct {
|
||||
AuthStandardTestSuite
|
||||
}
|
||||
|
||||
type authorizeHandlerTestCase struct {
|
||||
description string
|
||||
mutateUserAccount func(*gtsmodel.User, *gtsmodel.Account)
|
||||
expectedStatusCode int
|
||||
expectedLocationHeader string
|
||||
}
|
||||
|
||||
func (suite *AuthAuthorizeTestSuite) TestAccountAuthorizeHandler() {
|
||||
|
||||
var tests = []authorizeHandlerTestCase{
|
||||
{
|
||||
description: "user has their email unconfirmed",
|
||||
mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) {
|
||||
// nothing to do, weed_lord420 already has their email unconfirmed
|
||||
},
|
||||
expectedStatusCode: http.StatusSeeOther,
|
||||
expectedLocationHeader: auth.CheckYourEmailPath,
|
||||
},
|
||||
{
|
||||
description: "user has their email confirmed but is not approved",
|
||||
mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) {
|
||||
user.ConfirmedAt = time.Now()
|
||||
user.Email = user.UnconfirmedEmail
|
||||
},
|
||||
expectedStatusCode: http.StatusSeeOther,
|
||||
expectedLocationHeader: auth.WaitForApprovalPath,
|
||||
},
|
||||
{
|
||||
description: "user has their email confirmed and is approved, but User entity has been disabled",
|
||||
mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) {
|
||||
user.ConfirmedAt = time.Now()
|
||||
user.Email = user.UnconfirmedEmail
|
||||
user.Approved = true
|
||||
user.Disabled = true
|
||||
},
|
||||
expectedStatusCode: http.StatusSeeOther,
|
||||
expectedLocationHeader: auth.AccountDisabledPath,
|
||||
},
|
||||
{
|
||||
description: "user has their email confirmed and is approved, but Account entity has been suspended",
|
||||
mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) {
|
||||
user.ConfirmedAt = time.Now()
|
||||
user.Email = user.UnconfirmedEmail
|
||||
user.Approved = true
|
||||
user.Disabled = false
|
||||
account.SuspendedAt = time.Now()
|
||||
},
|
||||
expectedStatusCode: http.StatusSeeOther,
|
||||
expectedLocationHeader: auth.AccountDisabledPath,
|
||||
},
|
||||
}
|
||||
|
||||
doTest := func(testCase authorizeHandlerTestCase) {
|
||||
ctx, recorder := suite.newContext(http.MethodGet, auth.OauthAuthorizePath)
|
||||
|
||||
user := suite.testUsers["unconfirmed_account"]
|
||||
account := suite.testAccounts["unconfirmed_account"]
|
||||
|
||||
testSession := sessions.Default(ctx)
|
||||
testSession.Set(sessionUserID, user.ID)
|
||||
testSession.Set(sessionClientID, suite.testApplications["application_1"].ClientID)
|
||||
if err := testSession.Save(); err != nil {
|
||||
panic(errors.WrapMsgf(err, "failed on case: %s", testCase.description))
|
||||
}
|
||||
|
||||
testCase.mutateUserAccount(user, account)
|
||||
|
||||
testCase.description = fmt.Sprintf("%s, %t, %s", user.Email, user.Disabled, account.SuspendedAt)
|
||||
|
||||
user.UpdatedAt = time.Now()
|
||||
err := suite.db.UpdateByPrimaryKey(context.Background(), user)
|
||||
suite.NoError(err)
|
||||
_, err = suite.db.UpdateAccount(context.Background(), account)
|
||||
suite.NoError(err)
|
||||
|
||||
// call the handler
|
||||
suite.authModule.AuthorizeGETHandler(ctx)
|
||||
|
||||
// 1. we should have a redirect
|
||||
suite.Equal(testCase.expectedStatusCode, recorder.Code, fmt.Sprintf("failed on case: %s", testCase.description))
|
||||
|
||||
// 2. we should have a redirect to the check your email path, as this user has not confirmed their email yet.
|
||||
suite.Equal(testCase.expectedLocationHeader, recorder.Header().Get("Location"), fmt.Sprintf("failed on case: %s", testCase.description))
|
||||
}
|
||||
|
||||
for _, testCase := range tests {
|
||||
doTest(testCase)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountUpdateTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(AuthAuthorizeTestSuite))
|
||||
}
|
Reference in New Issue
Block a user