Spaces:
Running
Running
File size: 6,002 Bytes
ab82ffd 73d0319 ab82ffd 987726a ab82ffd 987726a 73d0319 ab82ffd 124871e ab82ffd 124871e ab82ffd 124871e ab82ffd c0722d3 ab82ffd 132b9f0 124871e ab82ffd c0722d3 ab82ffd c0722d3 ab82ffd c0722d3 ab82ffd 987726a c0722d3 987726a c0722d3 987726a a57273b 987726a 73d0319 027c2a2 73d0319 3577b8e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | package controllers
import (
"time"
"abdanhafidz.com/go-boilerplate/models/dto"
entity "abdanhafidz.com/go-boilerplate/models/entity"
"abdanhafidz.com/go-boilerplate/services"
"github.com/gin-gonic/gin"
)
type AuthenticationController interface {
SignUp(ctx *gin.Context)
SignIn(ctx *gin.Context)
ExternalAuth(ctx *gin.Context)
ChangePassword(ctx *gin.Context)
UpdateUserRole(ctx *gin.Context)
SeedSuperAdmin(ctx *gin.Context)
}
type authenticationController struct {
accountService services.AccountService
externalAuthService services.ExternalAuthService
emailVerification services.EmailVerificationService
}
func NewAuthenticationController(accountService services.AccountService, externalAuthService services.ExternalAuthService, emailVerification services.EmailVerificationService) AuthenticationController {
return &authenticationController{
accountService: accountService,
externalAuthService: externalAuthService,
emailVerification: emailVerification,
}
}
// SignUp godoc
// @Summary User Registration
// @Description Register a new user account
// @Tags Authentication
// @Accept json
// @Produce json
// @Param request body dto.SignUpRequest true "Sign Up Request"
// @Success 200 {object} dto.SuccessResponse[entity.Account]
// @Failure 400 {object} dto.ErrorResponse
// @Router /api/v1/authentication/register [post]
func (c *authenticationController) SignUp(ctx *gin.Context) {
req := RequestJSON[dto.SignUpRequest](ctx)
res, err := c.accountService.Create(ctx.Request.Context(), req.Name, req.Email, req.Username, req.Password, "user")
if err != nil {
ResponseJSON(ctx, req, entity.Account{}, err)
return
}
if _, err := c.emailVerification.CreateToken(ctx.Request.Context(), res.Email, 0, time.Time{}); err != nil {
ResponseJSON(ctx, req, entity.Account{}, err)
return
}
ResponseJSON(ctx, req, res, err)
}
// SignIn godoc
// @Summary User Login
// @Description Authenticate user and obtain access token
// @Tags Authentication
// @Accept json
// @Produce json
// @Param request body dto.SignInRequest true "Sign In Request"
// @Success 200 {object} dto.SuccessResponse[dto.AuthenticatedUser]
// @Failure 400 {object} dto.ErrorResponse
// @Router /api/v1/authentication/login [post]
func (c *authenticationController) SignIn(ctx *gin.Context) {
req := RequestJSON[dto.SignInRequest](ctx)
res, err := c.accountService.Validate(ctx, req.EmailorUsername, req.Password)
ResponseJSON(ctx, req, res, err)
}
// ChangePassword godoc
// @Summary Change User Password
// @Description Change the password of the authenticated user
// @Tags Authentication
// @Accept json
// @Produce json
// @Param request body dto.ChangePasswordRequest true "Change Password Request"
// @Success 200 {object} dto.SuccessResponse[dto.AuthenticatedUser]
// @Failure 400 {object} dto.ErrorResponse
// @Security BearerAuth
// @Router /api/v1/authentication/change-password [put]
func (c *authenticationController) ChangePassword(ctx *gin.Context) {
req := RequestJSON[dto.ChangePasswordRequest](ctx)
accountId := ParseAccountId(ctx)
res, err := c.accountService.ChangePassword(ctx.Request.Context(), accountId, req.OldPassword, req.NewPassword)
ResponseJSON(ctx, req, res, err)
}
// ExternalAuth godoc
// @Summary External Authentication
// @Description Authenticate user using external OAuth provider
// @Tags Authentication
// @Accept json
// @Produce json
// @Param request body dto.ExternalAuthRequest true "External Auth Request"
// @Success 200 {object} dto.SuccessResponse[dto.AuthenticatedUser]
// @Failure 400 {object} dto.ErrorResponse
// @Router /api/v1/authentication/external-login [post]
func (c *authenticationController) ExternalAuth(ctx *gin.Context) {
req := RequestJSON[dto.ExternalAuthRequest](ctx)
var (
res dto.AuthenticatedUser
err error
)
switch req.OauthProvider {
case "google":
res, err = c.externalAuthService.GoogleAuth(ctx.Request.Context(), req.OauthID)
default:
ResponseJSON(ctx, req, dto.AuthenticatedUser{}, nil)
return
}
ResponseJSON(ctx, req, res, err)
}
// UpdateUserRole godoc
// @Summary Update User Role
// @Description Update the role of a user account
// @Tags Authentication
// @Accept json
// @Produce json
// @Param accountId path string true "Account ID"
// @Param request body dto.UpdateUserRoleRequest true "Update User Role Request"
// @Success 200 {object} dto.SuccessResponse[entity.Account]
// @Failure 400 {object} dto.ErrorResponse
// @Security BearerAuth
// @Router /api/v1/admin/authentication/{account_id}/assign [put]
func (c *authenticationController) UpdateUserRole(ctx *gin.Context) {
req := RequestJSON[dto.UpdateUserRoleRequest](ctx)
accountId := ParseUUID(ctx, "accountId")
acc, err := c.accountService.GetById(ctx.Request.Context(), accountId)
if err != nil {
ResponseJSON(ctx, req, entity.Account{}, err)
return
}
accountToUpdate := acc
accountToUpdate.Role = req.Role
res, err := c.accountService.UpdateUserRole(ctx.Request.Context(), accountToUpdate)
ResponseJSON(ctx, req, res, err)
}
// SeedSuperAdmin godoc
// @Summary Seed Super Admin
// @Description Seed a super admin account using predefined credentials
// @Tags Authentication
// @Accept json
// @Produce json
// @Success 200 {object} dto.SuccessResponse[any]
// @Failure 400 {object} dto.ErrorResponse
// @Router /api/v1/authentication/seed-superadmin [post]
func (c *authenticationController) SeedSuperAdmin(ctx *gin.Context) {
err := c.accountService.SeedSuperAdmin(ctx.Request.Context())
ResponseJSON(ctx, interface{}(nil), interface{}(nil), err)
}
|