feat(auth): implement user and device authentication

This commit is contained in:
QiuSW
2026-07-26 15:18:48 +08:00
parent c5d3b215ff
commit 49db5b8305
66 changed files with 6216 additions and 271 deletions
+67 -2
View File
@@ -15,10 +15,14 @@ import (
"cmroubao/backend-api/internal/platform/assetstore"
"cmroubao/backend-api/internal/platform/database"
"cmroubao/backend-api/internal/platform/migration"
"cmroubao/backend-api/internal/platform/password"
repository "cmroubao/backend-api/internal/repository/sqlite"
"cmroubao/backend-api/internal/transport/authcommon"
"cmroubao/backend-api/internal/transport/httpapi"
"cmroubao/backend-api/internal/transport/webui"
"cmroubao/backend-api/internal/usecase"
"github.com/gin-gonic/gin"
)
func main() {
@@ -67,6 +71,13 @@ func run() error {
serverErrors := make(chan error, 1)
go func() {
if cfg.TLSCertificate != "" {
serverErrors <- server.ListenAndServeTLS(
cfg.TLSCertificate,
cfg.TLSPrivateKey,
)
return
}
serverErrors <- server.ListenAndServe()
}()
@@ -158,6 +169,20 @@ func buildRouter(
if err != nil {
return nil, err
}
passwords, err := password.NewBcrypt(12)
if err != nil {
return nil, err
}
auth, err := usecase.NewAuthService(
store,
passwords,
clock,
ids,
usecase.CryptoTokenGenerator{},
)
if err != nil {
return nil, err
}
webService, err := webui.NewUsecaseAdapter(tasks, assets)
if err != nil {
@@ -171,6 +196,33 @@ func buildRouter(
if err != nil {
return nil, err
}
authWebService, err := webui.NewAuthUsecaseAdapter(auth)
if err != nil {
return nil, err
}
loginLimiter, err := authcommon.NewAttemptLimiter(
10,
5*time.Minute,
4096,
)
if err != nil {
return nil, err
}
authWebHandler, err := webui.NewAuthHandler(
authWebService,
renderer,
loginLimiter,
)
if err != nil {
return nil, err
}
registerPublicAuth, err := httpapi.NewPublicAuthRegistrar(
auth,
loginLimiter,
)
if err != nil {
return nil, err
}
registerAdminRoutes, err := httpapi.NewAdminRouteRegistrar(
httpapi.AdminServices{
Assets: assets,
@@ -181,9 +233,22 @@ func buildRouter(
if err != nil {
return nil, err
}
registerProtectedRoutes := func(routes gin.IRoutes) error {
if err := registerAdminRoutes(routes); err != nil {
return err
}
authWebHandler.RegisterProtected(routes)
return nil
}
return httpapi.NewRouter(httpapi.RouterDependencies{
Database: db,
RegisterAdminRoutes: registerAdminRoutes,
Database: db,
RegisterPublicRoutes: func(routes gin.IRoutes) error {
webHandler.RegisterStatic(routes)
authWebHandler.RegisterPublic(routes)
return registerPublicAuth(routes)
},
RegisterAdminRoutes: registerProtectedRoutes,
AdminSessions: auth,
LogEvent: func(event string) {
log.Print(event)
},