feature: add nextWeb Service

This commit is contained in:
KaySar12 2024-10-02 16:52:10 +07:00
parent 9f885c9df9
commit db526c2796
7 changed files with 169 additions and 2 deletions

2
.vscode/launch.json vendored
View File

@ -6,7 +6,7 @@
"type": "go",
"debugAdapter": "dlv-dap",
"request": "launch",
"port": 45307,
"port": 34933,
"host": "127.0.0.1",
"mode": "exec",
"program": "${workspaceFolder}/dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service"

View File

@ -43,6 +43,8 @@ func InitRouter() *gin.Engine {
r.GET("/v1/users/oidc/health", v1.OIDCHealthCheck)
r.GET("/v1/users/oidc/settings", v1.GetOIDCSettings)
r.POST("/v1/users/oidc/saveSettings", v1.SaveOIDCSettings)
r.GET("/v1/users/1panel/health", v1.OnePanelHealthCheck)
r.POST("/v1/users/1panel/login", v1.OnePanelLogin)
v1Group := r.Group("/v1")
v1Group.Use(jwt.JWT(

View File

@ -53,6 +53,9 @@ var (
//authURL = "http://10.0.0.26:9000/application/o/nextzenos-oidc/"
callbackURL = "http://nextzenos.local/v1/users/oidc/callback"
//callbackURL = "http://172.20.60.244:8080/v1/users/oidc/callback"
onePanelServer = "http://172.20.60.244:13000"
onePanelName = "nextzen"
onePanelPassword = "Smartyourlife123@*"
)
type OIDCSetting struct {
@ -122,6 +125,34 @@ var limiter = rate.NewLimiter(rate.Every(time.Minute), 5)
// @Param pwd query string true "password"
// @Success 200 {string} string "ok"
// @Router /user/login [post]
func OnePanelLogin(c *gin.Context) {
var cred = model2.OnePanelCredentials{
Name: onePanelName,
Password: onePanelPassword,
IgnoreCaptcha: true,
Captcha: "",
CaptchaID: "",
AuthMethod: "session",
Language: "en",
}
response, cookies, err := service.MyService.OnePanel().Login(cred, "http://172.20.60.244:13000")
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
for _, cookie := range cookies {
c.SetCookie(cookie.Name, cookie.Value, 3600, "/", "", false, true)
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: response,
})
}
func PostUserLogin(c *gin.Context) {
if !limiter.Allow() {
c.JSON(common_err.TOO_MANY_REQUEST,
@ -502,6 +533,14 @@ func determineUserRole(isSuperuser bool) string {
}
return "user"
}
func OnePanelHealthCheck(c *gin.Context) {
status, err := service.MyService.OnePanel().HealthCheck(onePanelServer)
if err != nil || status == "Offline" {
c.JSON(http.StatusOK, model.Result{Success: common_err.OIDC_OFFLINE, Message: common_err.GetMsg(common_err.OIDC_OFFLINE), Data: "Offline"})
return
}
c.JSON(http.StatusOK, model.Result{Success: common_err.OIDC_LIVE, Message: common_err.GetMsg(common_err.OIDC_LIVE), Data: "Live"})
}
func hashPassword() string {
generatePassword, err := randString(16)

93
service/1panel.go Normal file
View File

@ -0,0 +1,93 @@
package service
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
model2 "github.com/KaySar12/NextZen-UserService/service/model"
)
type OnePanelService interface {
Login(m model2.OnePanelCredentials, baseURL string) (model2.LoginResponse, []*http.Cookie, error)
Logout(m model2.OnePanelCredentials, baseURL string) (model2.LogoutResponse, error)
HealthCheck(baseURL string) (string, error)
}
var (
prefixV1 = "/api/v1"
)
type onePanelService struct {
}
func (o *onePanelService) Login(m model2.OnePanelCredentials, baseURL string) (model2.LoginResponse, []*http.Cookie, error) {
path := baseURL + prefixV1 + "/auth/login"
// Create the request body by marshaling the credentials into JSON
reqBody, err := json.Marshal(m)
if err != nil {
return model2.LoginResponse{}, []*http.Cookie{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.LoginResponse{}, []*http.Cookie{}, fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
// Reuse the HTTP client (consider making it a field in onePanelService)
client := &http.Client{}
resp, err := client.Do(req)
cookies := resp.Cookies()
if err != nil {
return model2.LoginResponse{}, []*http.Cookie{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.LoginResponse{}, []*http.Cookie{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.LoginResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.LoginResponse{}, []*http.Cookie{}, fmt.Errorf("error decoding response: %v", err)
}
return result, cookies, nil
}
func (o *onePanelService) Logout(m model2.OnePanelCredentials, baseURL string) (model2.LogoutResponse, error) {
return model2.LogoutResponse{}, nil
}
func (o *onePanelService) HealthCheck(baseURL string) (string, error) {
path := baseURL + "/health"
req, err := http.NewRequest("GET", path, nil)
if err != nil {
log.Println("Error creating health/live request:", err)
return "Offline", err
}
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return nil // Always follow redirects
},
}
respLive, err := client.Do(req)
if err != nil {
log.Println("Error on health/live request:", err)
return "Offline", err // Exit if the request fails
}
defer respLive.Body.Close()
if respLive.StatusCode == http.StatusOK {
return "Live", nil
}
return "Offline", err
}
func NewOnePanelService() OnePanelService {
return &onePanelService{}
}

View File

@ -67,7 +67,6 @@ func (a *authentikService) GetSettings() (model2.AuthentikCredentialsDBModel, er
return m, nil
}
// TODO SHOULD BE Migrate to NEXTZENOS
func (a *authentikService) HealthCheck(baseURL string) (string, error) {
// Check health/live first
pathLive := baseURL + "/-/health/live/"

View File

@ -0,0 +1,28 @@
package model
type OnePanelCredentials struct {
Name string `json:"name"`
Password string `json:"password"`
IgnoreCaptcha bool `json:"ignoreCaptcha"`
Captcha string `json:"captcha"`
CaptchaID string `json:"captchaID"`
AuthMethod string `json:"authMethod"`
Language string `json:"language"`
}
type LoginResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Name string `json:"name"`
Token string `json:"token"`
MfaStatus string `json:"mfaStatus"`
} `json:"data"`
}
type LogoutResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
} `json:"data"`
}

View File

@ -16,6 +16,7 @@ type Repository interface {
Event() EventService
OMV() OMVService
Authentik() AuthentikService
OnePanel() OnePanelService
}
func NewService(db *gorm.DB, RuntimePath string) Repository {
@ -31,6 +32,7 @@ func NewService(db *gorm.DB, RuntimePath string) Repository {
event: NewEventService(db),
omv: NewOMVService(),
authentik: NewAuthentikService(db),
onePanel: NewOnePanelService(),
}
}
@ -40,8 +42,12 @@ type store struct {
event EventService
omv OMVService
authentik AuthentikService
onePanel OnePanelService
}
func (c *store) OnePanel() OnePanelService {
return c.onePanel
}
func (c *store) Event() EventService {
return c.event
}