2024-02-21 11:45:10 +07:00
//go:generate bash -c "mkdir -p codegen/user_service && go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4 -generate types,server,spec -package codegen api/user-service/openapi.yaml > codegen/user_service/user_service_api.go"
//go:generate bash -c "mkdir -p codegen/message_bus && go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4 -package message_bus https://raw.githubusercontent.com/IceWhaleTech/CasaOS-MessageBus/main/api/message_bus/openapi.yaml > codegen/message_bus/api.go"
package main
import (
_ "embed"
"flag"
"fmt"
"net"
"net/http"
"os"
"path/filepath"
"strings"
"time"
2024-02-21 12:06:40 +07:00
"github.com/KaySar12/NextZen-Common/external"
"github.com/KaySar12/NextZen-Common/model"
util_http "github.com/KaySar12/NextZen-Common/utils/http"
"github.com/KaySar12/NextZen-Common/utils/jwt"
"github.com/KaySar12/NextZen-Common/utils/logger"
"github.com/KaySar12/NextZen-UserService/common"
"github.com/KaySar12/NextZen-UserService/pkg/config"
"github.com/KaySar12/NextZen-UserService/pkg/sqlite"
"github.com/KaySar12/NextZen-UserService/pkg/utils/encryption"
"github.com/KaySar12/NextZen-UserService/pkg/utils/random"
"github.com/KaySar12/NextZen-UserService/route"
"github.com/KaySar12/NextZen-UserService/service"
2024-02-21 11:45:10 +07:00
"github.com/coreos/go-systemd/daemon"
"go.uber.org/zap"
)
const localhost = "127.0.0.1"
var (
commit = "private build"
date = "private build"
//go:embed api/index.html
_docHTML string
//go:embed api/user-service/openapi.yaml
_docYAML string
//go:embed build/sysroot/etc/casaos/user-service.conf.sample
_confSample string
)
func init ( ) {
configFlag := flag . String ( "c" , "" , "config address" )
dbFlag := flag . String ( "db" , "" , "db path" )
resetUserFlag := flag . Bool ( "ru" , false , "reset user" )
userFlag := flag . String ( "user" , "" , "user name" )
versionFlag := flag . Bool ( "v" , false , "version" )
flag . Parse ( )
if * versionFlag {
fmt . Printf ( "v%s\n" , common . Version )
os . Exit ( 0 )
}
println ( "git commit:" , commit )
println ( "build date:" , date )
config . InitSetup ( * configFlag , _confSample )
logger . LogInit ( config . AppInfo . LogPath , config . AppInfo . LogSaveName , config . AppInfo . LogFileExt )
if len ( * dbFlag ) == 0 {
* dbFlag = config . AppInfo . DBPath
}
sqliteDB := sqlite . GetDb ( * dbFlag )
service . MyService = service . NewService ( sqliteDB , config . CommonInfo . RuntimePath )
if * resetUserFlag {
if userFlag == nil || len ( * userFlag ) == 0 {
fmt . Println ( "user is empty" )
return
}
userData := service . MyService . User ( ) . GetUserAllInfoByName ( * userFlag )
if userData . Id == 0 {
fmt . Println ( "user not exist" )
return
}
password := random . RandomString ( 6 , false )
userData . Password = encryption . GetMD5ByStr ( password )
service . MyService . User ( ) . UpdateUserPassword ( userData )
fmt . Println ( "User reset successful" )
fmt . Println ( "UserName:" + userData . Username )
fmt . Println ( "Password:" + password )
}
}
func main ( ) {
v1Router := route . InitRouter ( )
v2Router := route . InitV2Router ( )
v2DocRouter := route . InitV2DocRouter ( _docHTML , _docYAML )
_ , publicKey := service . MyService . User ( ) . GetKeyPair ( )
jswkJSON , err := jwt . GenerateJwksJSON ( publicKey )
if err != nil {
panic ( err )
}
mux := & util_http . HandlerMultiplexer {
HandlerMap : map [ string ] http . Handler {
"v1" : v1Router ,
"v2" : v2Router ,
"doc" : v2DocRouter ,
strings . SplitN ( jwt . JWKSPath , "/" , 2 ) [ 0 ] : jwt . JWKSHandler ( jswkJSON ) ,
} ,
}
listener , err := net . Listen ( "tcp" , net . JoinHostPort ( localhost , "0" ) )
if err != nil {
panic ( err )
}
apiPaths := [ ] string {
"/v1/users" ,
route . V2APIPath ,
route . V2DocPath ,
"/" + jwt . JWKSPath ,
}
for _ , v := range apiPaths {
err = service . MyService . Gateway ( ) . CreateRoute ( & model . Route {
Path : v ,
Target : "http://" + listener . Addr ( ) . String ( ) ,
} )
if err != nil {
panic ( err )
}
}
// write address file
addressFilePath , err := writeAddressFile ( config . CommonInfo . RuntimePath , external . UserServiceAddressFilename , "http://" + listener . Addr ( ) . String ( ) )
if err != nil {
panic ( err )
}
if supported , err := daemon . SdNotify ( false , daemon . SdNotifyReady ) ; err != nil {
logger . Error ( "Failed to notify systemd that user service is ready" , zap . Any ( "error" , err ) )
} else if supported {
logger . Info ( "Notified systemd that user service is ready" )
} else {
logger . Info ( "This process is not running as a systemd service." )
}
go route . EventListen ( )
logger . Info ( "User service is listening..." , zap . Any ( "address" , listener . Addr ( ) . String ( ) ) , zap . String ( "filepath" , addressFilePath ) )
s := & http . Server {
Handler : mux ,
ReadHeaderTimeout : 5 * time . Second , // fix G112: Potential slowloris attack (see https://github.com/securego/gosec)
}
err = s . Serve ( listener ) // not using http.serve() to fix G114: Use of net/http serve function that has no support for setting timeouts (see https://github.com/securego/gosec)
if err != nil {
panic ( err )
}
}
func writeAddressFile ( runtimePath string , filename string , address string ) ( string , error ) {
err := os . MkdirAll ( runtimePath , 0 o755 )
if err != nil {
return "" , err
}
filepath := filepath . Join ( runtimePath , filename )
return filepath , os . WriteFile ( filepath , [ ] byte ( address ) , 0 o600 )
}