From 152ab6dfd5ed9a56d48fa6b1e5b64bbdec079c5e Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Fri, 31 Dec 2021 23:06:06 +0530 Subject: [PATCH] feat: add admin logout --- server/__test__/admin_logout_test.go | 25 ++++++++++++++ server/__test__/resolvers_test.go | 1 + server/graph/generated/generated.go | 50 ++++++++++++++++++++++++++++ server/graph/schema.graphqls | 1 + server/graph/schema.resolvers.go | 4 +++ server/resolvers/admin_logout.go | 29 ++++++++++++++++ server/utils/cookie.go | 2 +- 7 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 server/__test__/admin_logout_test.go create mode 100644 server/resolvers/admin_logout.go diff --git a/server/__test__/admin_logout_test.go b/server/__test__/admin_logout_test.go new file mode 100644 index 0000000..413c756 --- /dev/null +++ b/server/__test__/admin_logout_test.go @@ -0,0 +1,25 @@ +package test + +import ( + "testing" + + "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/resolvers" + "github.com/authorizerdev/authorizer/server/utils" + "github.com/stretchr/testify/assert" +) + +func adminLogoutTests(s TestSetup, t *testing.T) { + t.Run(`should get admin session`, func(t *testing.T) { + req, ctx := createContext(s) + _, err := resolvers.AdminLogout(ctx) + assert.NotNil(t, err) + + h, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET) + assert.Nil(t, err) + req.Header.Add("Authorization", "Bearer "+h) + _, err = resolvers.AdminLogout(ctx) + + assert.Nil(t, err) + }) +} diff --git a/server/__test__/resolvers_test.go b/server/__test__/resolvers_test.go index 59224e7..c307fc4 100644 --- a/server/__test__/resolvers_test.go +++ b/server/__test__/resolvers_test.go @@ -45,6 +45,7 @@ func TestResolvers(t *testing.T) { deleteUserTest(s, t) updateUserTest(s, t) adminLoginTests(s, t) + adminLogoutTests(s, t) adminSessionTests(s, t) updateConfigTests(s, t) configTests(s, t) diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index c7f2882..da1cdab 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -107,6 +107,7 @@ type ComplexityRoot struct { Mutation struct { AdminLogin func(childComplexity int, params model.AdminLoginInput) int + AdminLogout func(childComplexity int) int DeleteUser func(childComplexity int, params model.DeleteUserInput) int ForgotPassword func(childComplexity int, params model.ForgotPasswordInput) int Login func(childComplexity int, params model.LoginInput) int @@ -179,6 +180,7 @@ type MutationResolver interface { DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error) AdminLogin(ctx context.Context, params model.AdminLoginInput) (*model.AdminLoginResponse, error) + AdminLogout(ctx context.Context) (*model.Response, error) UpdateConfig(ctx context.Context, params model.UpdateConfigInput) (*model.Response, error) } type QueryResolver interface { @@ -547,6 +549,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.AdminLogin(childComplexity, args["params"].(model.AdminLoginInput)), true + case "Mutation._admin_logout": + if e.complexity.Mutation.AdminLogout == nil { + break + } + + return e.complexity.Mutation.AdminLogout(childComplexity), true + case "Mutation._delete_user": if e.complexity.Mutation.DeleteUser == nil { break @@ -1214,6 +1223,7 @@ type Mutation { _delete_user(params: DeleteUserInput!): Response! _update_user(params: UpdateUserInput!): User! _admin_login(params: AdminLoginInput!): AdminLoginResponse! + _admin_logout: Response! _update_config(params: UpdateConfigInput!): Response! } @@ -3520,6 +3530,41 @@ func (ec *executionContext) _Mutation__admin_login(ctx context.Context, field gr return ec.marshalNAdminLoginResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAdminLoginResponse(ctx, field.Selections, res) } +func (ec *executionContext) _Mutation__admin_logout(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().AdminLogout(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Response) + fc.Result = res + return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res) +} + func (ec *executionContext) _Mutation__update_config(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -6979,6 +7024,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { invalids++ } + case "_admin_logout": + out.Values[i] = ec._Mutation__admin_logout(ctx, field) + if out.Values[i] == graphql.Null { + invalids++ + } case "_update_config": out.Values[i] = ec._Mutation__update_config(ctx, field) if out.Values[i] == graphql.Null { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index cfb5ad8..ba2add6 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -233,6 +233,7 @@ type Mutation { _delete_user(params: DeleteUserInput!): Response! _update_user(params: UpdateUserInput!): User! _admin_login(params: AdminLoginInput!): AdminLoginResponse! + _admin_logout: Response! _update_config(params: UpdateConfigInput!): Response! } diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go index 4bf8a5a..a3172b9 100644 --- a/server/graph/schema.resolvers.go +++ b/server/graph/schema.resolvers.go @@ -59,6 +59,10 @@ func (r *mutationResolver) AdminLogin(ctx context.Context, params model.AdminLog return resolvers.AdminLoginResolver(ctx, params) } +func (r *mutationResolver) AdminLogout(ctx context.Context) (*model.Response, error) { + return resolvers.AdminLogout(ctx) +} + func (r *mutationResolver) UpdateConfig(ctx context.Context, params model.UpdateConfigInput) (*model.Response, error) { return resolvers.UpdateConfigResolver(ctx, params) } diff --git a/server/resolvers/admin_logout.go b/server/resolvers/admin_logout.go new file mode 100644 index 0000000..d6bb2f8 --- /dev/null +++ b/server/resolvers/admin_logout.go @@ -0,0 +1,29 @@ +package resolvers + +import ( + "context" + "fmt" + + "github.com/authorizerdev/authorizer/server/graph/model" + "github.com/authorizerdev/authorizer/server/utils" +) + +func AdminLogout(ctx context.Context) (*model.Response, error) { + gc, err := utils.GinContextFromContext(ctx) + var res *model.Response + + if err != nil { + return res, err + } + + if !utils.IsSuperAdmin(gc) { + return res, fmt.Errorf("unauthorized") + } + + utils.DeleteAdminCookie(gc) + + res = &model.Response{ + Message: "admin logged out successfully", + } + return res, nil +} diff --git a/server/utils/cookie.go b/server/utils/cookie.go index 996bee7..7319a21 100644 --- a/server/utils/cookie.go +++ b/server/utils/cookie.go @@ -64,7 +64,7 @@ func GetAdminCookie(gc *gin.Context) (string, error) { return cookie.Value, nil } -func DeleteAdminCookie(gc *gin.Context, token string) { +func DeleteAdminCookie(gc *gin.Context) { secure := true httpOnly := true host, _ := GetHostParts(constants.EnvData.AUTHORIZER_URL)