101 lines
2.2 KiB
Go
101 lines
2.2 KiB
Go
package controllers
|
|
|
|
import (
|
|
"addrss/pkg/auth"
|
|
"addrss/pkg/router"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type Auth struct{}
|
|
|
|
func (a Auth) AddRoutes() {
|
|
router.AddPost(`/auth/guest`, guest).Anonymous()
|
|
router.AddPost(`/auth/login`, login).Anonymous()
|
|
router.AddPost(`/auth/logout`, logout).Anonymous()
|
|
router.AddPost(`/auth/refresh`, refresh).Anonymous()
|
|
router.AddPut(`/auth/password`, changePassword)
|
|
}
|
|
func guest(ctx *router.Context) {
|
|
tokens, err := auth.AuthenticateGuest()
|
|
if err != nil {
|
|
ctx.Response.Unauthorized(err)
|
|
return
|
|
}
|
|
|
|
ctx.Response.OK(tokens)
|
|
}
|
|
|
|
func login(ctx *router.Context) {
|
|
user := auth.UserLogin{}
|
|
if err := ctx.Request.Bind(user); err != nil {
|
|
ctx.Response.BadRequest(err)
|
|
}
|
|
|
|
tokens, err := auth.AuthenticateUserLogin(user)
|
|
if err != nil {
|
|
switch err.(type) {
|
|
case *auth.ErrorUnauthorized:
|
|
ctx.Response.Unauthorized(err)
|
|
case *auth.ErrorForbidden:
|
|
ctx.Response.Forbidden(err)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
ctx.Response.OK(tokens)
|
|
}
|
|
|
|
func logout(ctx *router.Context) {
|
|
// Logout uses the refresh token
|
|
authSegments := strings.Split(ctx.Request.Header.Get("Authorization"), " ")
|
|
|
|
if len(authSegments) != 2 || authSegments[0] != "Bearer" {
|
|
ctx.Response.BadRequest(fmt.Errorf("invalid token"))
|
|
}
|
|
|
|
claims := auth.RefreshClaims{}
|
|
if err := auth.ValidateJwtToken(authSegments[1], &claims); err != nil {
|
|
ctx.Response.Unauthorized(fmt.Errorf("invalid token signature"))
|
|
}
|
|
|
|
if err := auth.DestroySession(claims.Sub); err != nil {
|
|
ctx.Response.BadRequest(fmt.Errorf("failed to destroy session"))
|
|
}
|
|
|
|
ctx.Response.NoContent()
|
|
}
|
|
|
|
func refresh(ctx *router.Context) {
|
|
tokens := auth.Tokens{}
|
|
if err := ctx.Request.Bind(&tokens); err != nil {
|
|
ctx.Response.BadRequest(err)
|
|
}
|
|
|
|
tokens, err := auth.AuthenticateUserRefresh(tokens.RefreshToken)
|
|
if err != nil {
|
|
ctx.Response.Unauthorized(err)
|
|
}
|
|
|
|
ctx.Response.OK(tokens)
|
|
}
|
|
|
|
func changePassword(ctx *router.Context) {
|
|
pc := auth.PasswordChange{}
|
|
if err := ctx.Request.Bind(&pc); err != nil {
|
|
ctx.Response.BadRequest(err)
|
|
}
|
|
|
|
if pc.UserId != ctx.Claims.Sub {
|
|
err := fmt.Errorf("user id/sub claim mismatch")
|
|
ctx.Response.Forbidden(err)
|
|
}
|
|
|
|
if err := auth.ChangePassword(pc); err != nil {
|
|
ctx.Response.BadRequest(err)
|
|
}
|
|
|
|
ctx.Response.NoContent()
|
|
}
|