2022-12-07 09:23:38 +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"
2022-08-05 06:14:53 +07:00
package main
import (
2024-02-04 15:15:37 +07:00
"context"
2022-11-30 11:16:11 +07:00
_ "embed"
2022-08-05 06:14:53 +07:00
"flag"
"fmt"
"net"
"net/http"
2022-08-07 09:52:14 +07:00
"os"
2023-04-22 11:46:18 +07:00
"path/filepath"
"strings"
2022-09-29 04:30:34 +07:00
"time"
2022-08-05 06:14:53 +07:00
2023-04-22 11:46:18 +07:00
"github.com/IceWhaleTech/CasaOS-Common/external"
2022-10-29 04:28:04 +07:00
"github.com/IceWhaleTech/CasaOS-Common/model"
2022-11-30 11:16:11 +07:00
util_http "github.com/IceWhaleTech/CasaOS-Common/utils/http"
2023-04-22 11:46:18 +07:00
"github.com/IceWhaleTech/CasaOS-Common/utils/jwt"
2022-08-05 06:14:53 +07:00
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
2024-02-04 15:15:37 +07:00
"github.com/IceWhaleTech/CasaOS-UserService/codegen/message_bus"
2022-09-29 04:38:35 +07:00
"github.com/IceWhaleTech/CasaOS-UserService/common"
2022-08-05 06:14:53 +07:00
"github.com/IceWhaleTech/CasaOS-UserService/pkg/config"
"github.com/IceWhaleTech/CasaOS-UserService/pkg/sqlite"
"github.com/IceWhaleTech/CasaOS-UserService/pkg/utils/encryption"
"github.com/IceWhaleTech/CasaOS-UserService/pkg/utils/random"
"github.com/IceWhaleTech/CasaOS-UserService/route"
"github.com/IceWhaleTech/CasaOS-UserService/service"
2022-09-07 06:13:00 +07:00
"github.com/coreos/go-systemd/daemon"
2022-08-26 04:36:24 +07:00
"go.uber.org/zap"
2022-08-05 06:14:53 +07:00
)
2022-09-02 06:09:54 +07:00
const localhost = "127.0.0.1"
2022-08-05 06:14:53 +07:00
2022-11-30 11:16:11 +07:00
var (
2022-12-30 06:19:49 +07:00
commit = "private build"
date = "private build"
2022-11-30 11:16:11 +07:00
//go:embed api/index.html
_docHTML string
//go:embed api/user-service/openapi.yaml
_docYAML string
2023-07-31 16:18:09 +07:00
//go:embed build/sysroot/etc/casaos/user-service.conf.sample
_confSample string
2022-11-30 11:16:11 +07:00
)
2022-08-05 06:14:53 +07:00
func init ( ) {
2022-08-07 09:52:14 +07:00
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" )
2022-08-05 06:14:53 +07:00
flag . Parse ( )
2022-08-07 09:52:14 +07:00
if * versionFlag {
2022-08-31 11:29:50 +07:00
fmt . Printf ( "v%s\n" , common . Version )
2022-08-07 09:52:14 +07:00
os . Exit ( 0 )
}
2022-12-30 06:19:49 +07:00
println ( "git commit:" , commit )
println ( "build date:" , date )
2023-07-31 16:18:09 +07:00
config . InitSetup ( * configFlag , _confSample )
2022-08-05 06:14:53 +07:00
logger . LogInit ( config . AppInfo . LogPath , config . AppInfo . LogSaveName , config . AppInfo . LogFileExt )
if len ( * dbFlag ) == 0 {
2022-08-29 07:40:51 +07:00
* dbFlag = config . AppInfo . DBPath
2022-08-05 06:14:53 +07:00
}
2022-08-07 09:52:14 +07:00
sqliteDB := sqlite . GetDb ( * dbFlag )
2022-08-05 06:14:53 +07:00
service . MyService = service . NewService ( sqliteDB , config . CommonInfo . RuntimePath )
2022-08-07 09:52:14 +07:00
if * resetUserFlag {
if userFlag == nil || len ( * userFlag ) == 0 {
2022-08-05 06:14:53 +07:00
fmt . Println ( "user is empty" )
return
}
2022-08-07 09:52:14 +07:00
userData := service . MyService . User ( ) . GetUserAllInfoByName ( * userFlag )
2022-08-05 06:14:53 +07:00
if userData . Id == 0 {
fmt . Println ( "user not exist" )
return
}
2022-08-07 09:52:14 +07:00
2022-08-05 06:14:53 +07:00
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 )
}
2022-08-07 09:52:14 +07:00
}
func main ( ) {
2022-11-30 11:16:11 +07:00
v1Router := route . InitRouter ( )
v2Router := route . InitV2Router ( )
v2DocRouter := route . InitV2DocRouter ( _docHTML , _docYAML )
2023-04-22 11:46:18 +07:00
_ , publicKey := service . MyService . User ( ) . GetKeyPair ( )
jswkJSON , err := jwt . GenerateJwksJSON ( publicKey )
if err != nil {
panic ( err )
}
2022-11-30 11:16:11 +07:00
mux := & util_http . HandlerMultiplexer {
HandlerMap : map [ string ] http . Handler {
2023-04-22 11:46:18 +07:00
"v1" : v1Router ,
"v2" : v2Router ,
"doc" : v2DocRouter ,
strings . SplitN ( jwt . JWKSPath , "/" , 2 ) [ 0 ] : jwt . JWKSHandler ( jswkJSON ) ,
2022-11-30 11:16:11 +07:00
} ,
}
2022-08-05 06:14:53 +07:00
listener , err := net . Listen ( "tcp" , net . JoinHostPort ( localhost , "0" ) )
if err != nil {
panic ( err )
}
2022-11-30 11:16:11 +07:00
apiPaths := [ ] string {
"/v1/users" ,
route . V2APIPath ,
route . V2DocPath ,
2023-04-22 11:46:18 +07:00
"/" + jwt . JWKSPath ,
2022-11-30 11:16:11 +07:00
}
for _ , v := range apiPaths {
err = service . MyService . Gateway ( ) . CreateRoute ( & model . Route {
Path : v ,
Target : "http://" + listener . Addr ( ) . String ( ) ,
} )
if err != nil {
panic ( err )
}
2022-08-05 06:14:53 +07:00
}
2023-04-22 11:46:18 +07:00
// write address file
addressFilePath , err := writeAddressFile ( config . CommonInfo . RuntimePath , external . UserServiceAddressFilename , "http://" + listener . Addr ( ) . String ( ) )
if err != nil {
panic ( err )
}
2022-09-07 06:13:00 +07:00
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." )
}
2022-12-07 10:01:33 +07:00
go route . EventListen ( )
2023-04-22 11:46:18 +07:00
logger . Info ( "User service is listening..." , zap . Any ( "address" , listener . Addr ( ) . String ( ) ) , zap . String ( "filepath" , addressFilePath ) )
2022-09-29 04:30:34 +07:00
2024-02-04 15:15:37 +07:00
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 )
}
2022-09-29 04:30:34 +07:00
s := & http . Server {
2022-11-30 11:16:11 +07:00
Handler : mux ,
2022-09-29 04:30:34 +07:00
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)
2022-08-05 06:14:53 +07:00
if err != nil {
panic ( err )
}
}
2023-04-22 11:46:18 +07:00
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 )
}