mirror of
https://github.com/KaySar12/NextZen-UserService.git
synced 2025-03-15 15:15:35 +07:00
221 lines
6.8 KiB
Go
221 lines
6.8 KiB
Go
//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 (
|
|
"context"
|
|
_ "embed"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"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/codegen/message_bus"
|
|
"github.com/KaySar12/NextZen-UserService/common"
|
|
model2 "github.com/KaySar12/NextZen-UserService/model"
|
|
"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/file"
|
|
"github.com/KaySar12/NextZen-UserService/pkg/utils/random"
|
|
"github.com/KaySar12/NextZen-UserService/route"
|
|
"github.com/KaySar12/NextZen-UserService/service"
|
|
"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)
|
|
}
|
|
// create default app path
|
|
defaultDir := config.AppInfo.UserDataPath + "/" + "default"
|
|
if err := file.IsNotExistMkDir(defaultDir); err != nil {
|
|
panic(err)
|
|
}
|
|
appData := convertMapToSlice(config.DefaultAppInfo.Apps)
|
|
initApp, err := json.Marshal(appData)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if err := file.WriteToPath(initApp, defaultDir, "link.json"); err != nil {
|
|
panic(err)
|
|
}
|
|
apiPaths := []string{
|
|
"/v1/users",
|
|
"/v1/1panel",
|
|
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))
|
|
|
|
var events []message_bus.EventType
|
|
events = append(events, message_bus.EventType{Name: "zimaos:user:save_config", SourceID: common.SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}})
|
|
// register at message bus
|
|
for i := 0; i < 10; i++ {
|
|
response, err := service.MyService.MessageBus().RegisterEventTypesWithResponse(context.Background(), events)
|
|
if err != nil {
|
|
logger.Error("error when trying to register one or more event types - some event type will not be discoverable", zap.Error(err))
|
|
}
|
|
if response != nil && response.StatusCode() != http.StatusOK {
|
|
logger.Error("error when trying to register one or more event types - some event type will not be discoverable", zap.String("status", response.Status()), zap.String("body", string(response.Body)))
|
|
}
|
|
if response.StatusCode() == http.StatusOK {
|
|
break
|
|
}
|
|
time.Sleep(time.Second)
|
|
}
|
|
|
|
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 convertMapToSlice(appsMap map[string]model2.AppInfo) []model2.AppInfo {
|
|
appsSlice := make([]model2.AppInfo, 0, len(appsMap))
|
|
|
|
for _, app := range appsMap {
|
|
appsSlice = append(appsSlice, app)
|
|
}
|
|
|
|
return appsSlice
|
|
}
|
|
func writeAddressFile(runtimePath string, filename string, address string) (string, error) {
|
|
err := os.MkdirAll(runtimePath, 0o755)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
filepath := filepath.Join(runtimePath, filename)
|
|
return filepath, os.WriteFile(filepath, []byte(address), 0o600)
|
|
}
|