11 Commits

25 changed files with 1220 additions and 182 deletions
+1
View File
@@ -44,3 +44,4 @@ dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-
.env
.vscode/launch.json
dist/metadata.json
*.gz
+1 -1
View File
@@ -6,7 +6,7 @@
"type": "go",
"debugAdapter": "dlv-dap",
"request": "launch",
"port": 39117,
"port": 2345,
"host": "127.0.0.1",
"mode": "exec",
"program": "${workspaceFolder}/dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service"
+7 -3
View File
@@ -12,14 +12,18 @@ CUR_DIR=$(PWD)
CUR_TAG ?= $(shell git describe --tags --match '*.*.*' | sort -V | tail -n1 | sed 's/-[0-9]*-g[0-9a-f]*//')
PREV_TAG ?= $(shell git describe --tags --match '*.*.*' | sort -V | head -n2 | tail -n1 | sed 's/-[0-9]*-g[0-9a-f]*//')
ARCHIVE_PATH=buildzip
PACKAGE_NAME=$(OS)-$(ARCHITECHTURE)-nextzenos-user-service-$(TAG)
ifeq ($(TAG),)
PACKAGE_NAME := $(OS)-$(ARCHITECHTURE)-nextzenos-user-service
else
PACKAGE_NAME := $(OS)-$(ARCHITECHTURE)-nextzenos-user-service-$(TAG)
endif
COMMIT_MESSAGE ?="update"
build_service:
$(GORELEASERBUILD) --clean --snapshot -f .goreleaser.debug.yaml --id $(SERVICE)-$(ARCHITECHTURE)
package:
cp -f $(CUR_DIR)/dist/$(SERVICE)-$(ARCHITECHTURE)_$(OS)_$(ARCHITECHTURE)_$(VERSION)/$(BIN_PATH)/$(SERVICE) $(CUR_DIR)/$(BIN_PATH) \
&& tar -czvf $(PACKAGE_NAME).tar.gz $(CUR_DIR)/$(BUILD_PATH)
cp $(CUR_DIR)/dist/$(SERVICE)-$(ARCHITECHTURE)_$(OS)_$(ARCHITECHTURE)_$(VERSION)/$(BIN_PATH)/$(SERVICE) $(CUR_DIR)/$(BIN_PATH) \
&& tar -czvf $(PACKAGE_NAME).tar.gz $(BUILD_PATH)
archive_package:
@mkdir -p $(CUR_DIR)/$(ARCHIVE_PATH)/$(CUR_TAG)
View File
View File
View File
View File
+21 -3
View File
@@ -7,6 +7,24 @@ LogSaveName = user-service
LogFileExt = log
DBPath = /var/lib/casaos/db
UserDataPath = /var/lib/casaos
OMVServer = http://10.0.0.4:1081/rpc.php
SecretKey = N1PCdw3M2B1TfJhoaY2mL736p2vCUc47
AuthentikServer = http://10.0.0.26:9000
[oidc]
AuthServer = https://account.nextzenvn.com
ClientID = WzN5QB9e0LfCSAYTB542RLpIGKcAWNNZgVbeTLaz
ClientSecret = D1mbEz1VHkPnhvMGPfj5aAmjOuZ1ZIYGm7qAReMCivdXwiQ60BJoa4cpdX5m9Z5aKgtR8d56xgmYAy7TR86MEV6zJXfjxy2lf0TTAPXc8ftEcst8fPi6B9IFe3aDBo8x
AuthURL = https://account.nextzenvn.com/application/o/nextzenos/
CallbackURL = https://home.nextzenvn.com/v1/users/oidc/callback
[nextweb]
Server = http://127.0.0.1:10086
UserName = nextzen
Password = Smartyourlife123@*
EntranceCode =
[default-app]
NextFireWall = NextFirewall-https://firewall.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/ded8610b855ac31cb08514460e78b93fff9ea127/NextFirewall/nextfirewall.png-DefaultApp-running
NextWeb = NextWeb-https://web.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/c68656087a0387281a1345ff78c89eb36cb925a4/NextWeb/nextweb.png-DefaultApp-running
AccountCenter = AccountCenter-https://account.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/f8c809f8ade653db6cec0915d1e7fadfcdb15241/AccountManager/account.png-DefaultApp-running
NextVPN = NextVPN-https://vpn.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/f5507a5bfa811eae29b67b1f1fc5ac5d8fc5c3e8/NextVPN/nextvpn.png-DefaultApp-running
NextNAS = NextNAS-https://nas.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/0693ac3497cb5c46b7e797ec7afb511fdb5d8804/NextNAS/nextnas.jpg-DefaultApp-running
NextDNS = NextDNS-https://dns.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/874a16e2647e8633f60845dd2d770bbd4aaccfd4/NextDNS/nextdns.png-DefaultApp-running
@@ -0,0 +1,14 @@
[Unit]
After=casaos-message-bus.service
ConditionFileNotEmpty=/etc/casaos/user-service.conf
Description=CasaOS User Service
[Service]
ExecStartPre=/usr/bin/casaos-user-service -v
ExecStart=/usr/bin/casaos-user-service -c /etc/casaos/user-service.conf
PIDFile=/var/run/casaos/user-service.pid
Restart=always
Type=notify
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,13 @@
[Unit]
After=casaos-message-bus.service
Description=CasaOS User Service
[Service]
ExecStartPre=/usr/bin/casaos-user-service -v
ExecStart=/usr/bin/casaos-user-service -c /etc/casaos/user-service.conf
PIDFile=/var/run/casaos/user-service.pid
Restart=always
Type=notify
[Install]
WantedBy=multi-user.target
-2
View File
@@ -2,8 +2,6 @@ module github.com/KaySar12/NextZen-UserService
go 1.21
toolchain go1.22.0
require (
github.com/KaySar12/NextZen-Common v1.0.0-alpha6
github.com/coreos/go-oidc/v3 v3.11.0
+25 -1
View File
@@ -5,6 +5,7 @@ package main
import (
"context"
_ "embed"
"encoding/json"
"flag"
"fmt"
"net"
@@ -21,9 +22,11 @@ import (
"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"
@@ -122,7 +125,19 @@ func main() {
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",
@@ -130,6 +145,7 @@ func main() {
route.V2DocPath,
"/" + jwt.JWKSPath,
}
for _, v := range apiPaths {
err = service.MyService.Gateway().CreateRoute(&model.Route{
Path: v,
@@ -184,7 +200,15 @@ func main() {
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 {
+31 -8
View File
@@ -5,16 +5,39 @@ type CommonModel struct {
}
type APPModel struct {
LogPath string
LogSaveName string
LogFileExt string
UserDataPath string
DBPath string
OMVServer string
AuthentikServer string
SecretKey string
LogPath string
LogSaveName string
LogFileExt string
UserDataPath string
DBPath string
}
type OIDCModel struct {
AuthServer string
ClientID string
ClientSecret string
AuthURL string
CallbackURL string
}
type NextWebModel struct {
Server string
UserName string
Password string
EntranceCode string
}
type DefaultModel struct {
Apps map[string]AppInfo
}
type AppInfo struct {
Hostname string `json:"hostname,omitempty"`
Name string `json:"name,omitempty"`
Icon string `json:"icon,omitempty"`
AppType string `json:"app_type,omitempty"`
Status string `json:"status,omitempty"`
}
type Result struct {
Success int `json:"success" example:"200"`
Message string `json:"message" example:"ok"`
+44 -1
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"log"
"os"
"strings"
"github.com/KaySar12/NextZen-Common/utils/constants"
"github.com/KaySar12/NextZen-UserService/model"
@@ -24,7 +25,22 @@ var (
LogSaveName: "user",
LogFileExt: "log",
}
OIDCInfo = &model.OIDCModel{
AuthServer: "",
ClientID: "",
ClientSecret: "",
AuthURL: "",
CallbackURL: "",
}
NextWebInfo = &model.NextWebModel{
Server: "",
UserName: "",
Password: "",
EntranceCode: "",
}
DefaultAppInfo = &model.DefaultModel{
Apps: map[string]model.AppInfo{},
}
Cfg *ini.File
ConfigFilePath string
)
@@ -60,10 +76,37 @@ func InitSetup(config string, sample string) {
os.Exit(1)
}
mapTo("oidc", OIDCInfo)
mapTo("nextweb", NextWebInfo)
mapTo("common", CommonInfo)
mapTo("app", AppInfo)
mapToDefaultApp("default-app", DefaultAppInfo)
fmt.Println(DefaultAppInfo)
}
func mapToDefaultApp(section string, v interface{}) {
sectionData := Cfg.Section(section)
dm, ok := v.(*model.DefaultModel)
if !ok {
log.Fatal("Invalid type passed to mapToDefaultApp")
}
// Iterate through all keys in the section
for key, value := range sectionData.KeysHash() {
// Split the value string into components (Name, URL, Icon)
parts := strings.Split(value, "-")
if len(parts) == 5 {
dm.Apps[key] = model.AppInfo{
Name: parts[0],
Hostname: parts[1],
Icon: parts[2],
AppType: parts[3],
Status: parts[4],
}
} else {
log.Printf("Invalid app info format for key: %s, value: %s", key, value)
}
}
}
func SaveSetup(config string) {
reflectFrom("common", CommonInfo)
reflectFrom("app", AppInfo)
+34
View File
@@ -0,0 +1,34 @@
package config
import (
"fmt"
"github.com/KaySar12/NextZen-UserService/pkg/config"
"gopkg.in/ini.v1"
)
var (
Cfg *ini.File
)
func init() {
var err error
Cfg, err = ini.Load(config.UserServiceConfigFilePath)
if err != nil {
panic(err)
}
}
func WriteMapToConfig(configData map[string]string, section string) {
sectionData := Cfg.Section(section)
for key, value := range sectionData.KeysHash() {
if value != configData[key] {
sectionData.Key(key).SetValue(configData[key])
}
}
err := Cfg.SaveTo(config.UserServiceConfigFilePath)
if err != nil {
fmt.Println("Failed to save file:", err)
return
}
}
+2 -3
View File
@@ -15,15 +15,14 @@ import (
"crypto/md5"
"crypto/rand"
"encoding/hex"
"github.com/KaySar12/NextZen-UserService/pkg/config"
)
var (
// We're using a 32 byte long secret key.
// This is probably something you generate first
// then put into and environment variable.
secretKey string = config.AppInfo.SecretKey
// secretKey string = config.AppInfo.SecretKey
secretKey string = ""
)
func GetMD5ByStr(str string) string {
+2 -1
View File
@@ -39,7 +39,7 @@ func InitRouter() *gin.Engine {
r.POST("/v1/users/refresh", v1.PostUserRefreshToken)
r.GET("/v1/users/image", v1.GetUserImage)
r.GET("/v1/users/:username", v1.GetUserInfoByUsername)
r.GET("/v1/users/status", v1.GetUserStatus) // init/check
r.GET("/v1/users/status", v1.InitializedUser) //init
r.POST("/v1/users/oidc/login", v1.OIDCLogin)
r.GET("/v1/users/oidc/callback", v1.OIDCCallback)
r.GET("/v1/users/oidc/profile", v1.OIDCProfile)
@@ -56,6 +56,7 @@ func InitRouter() *gin.Engine {
r.POST("/v1/1panel/website/create", v1.ExternalAPIMiddleware, v1.OnePanelCreateWebsite)
r.POST("/v1/1panel/website/delete", v1.ExternalAPIMiddleware, v1.OnePanelDeleteWebsite)
r.POST("/v1/1panel/website/update-proxy", v1.ExternalAPIMiddleware, v1.OnePanelUpdateProxyWebsite)
r.POST("/v1/1panel/website/update", v1.ExternalAPIMiddleware, v1.OnePanelUpdateWebsite)
v1Group := r.Group("/v1")
v1Group.Use(jwt.JWT(
+579 -107
View File
@@ -7,13 +7,13 @@ import (
"encoding/base64"
"encoding/json"
json2 "encoding/json"
"errors"
"fmt"
"image"
"image/png"
"io"
"log"
"net/http"
"net/url"
url2 "net/url"
"os"
"path"
@@ -31,6 +31,7 @@ import (
"github.com/KaySar12/NextZen-UserService/model"
"github.com/KaySar12/NextZen-UserService/model/system_model"
"github.com/KaySar12/NextZen-UserService/pkg/config"
cfg "github.com/KaySar12/NextZen-UserService/pkg/utils/config"
"github.com/KaySar12/NextZen-UserService/pkg/utils/encryption"
"github.com/KaySar12/NextZen-UserService/pkg/utils/file"
"github.com/KaySar12/NextZen-UserService/service"
@@ -46,15 +47,11 @@ import (
)
var (
authServer = "http://accessmanager.local"
clientID = "6KwKSxLCtaQ4r6HoAn3gdNMbNOAf75j3SejLIAx7"
clientSecret = "PE05fcDP4qESUmyZ1TNYpZNBxRPq70VpFI81vehsoJ6WhGz5yPXMljrFrOdMRdRhrYmF03fHWTZHgO9ZdNENrLN13BzL8CAgtEkTsyjXfgx9GvISheIjYfpSfvo219fL"
authURL = "http://accessmanager.local/application/o/nextzenos-oidc/"
callbackURL = "http://nextzenos.local/v1/users/oidc/callback"
onePanelServer = "http://nextweb.local"
onePanelName = "nextzen"
onePanelPassword = "Smartyourlife123@*"
authentik_api_token = "jidFioAIXpgl8awyk2O17K8W7vZzlXhOO0QXGxEhMDJdn9g747EQjmaI0i3e"
authServer string
clientID string
clientSecret string
authURL string
callbackURL string
)
type OIDCSetting struct {
@@ -145,8 +142,8 @@ func ExternalAPIMiddleware(c *gin.Context) {
}
func OnePanelLogin(c *gin.Context) error {
cred := model2.OnePanelCredentials{
Name: onePanelName,
Password: onePanelPassword,
Name: config.NextWebInfo.UserName,
Password: config.NextWebInfo.Password,
IgnoreCaptcha: true,
Captcha: "",
CaptchaID: "",
@@ -154,10 +151,10 @@ func OnePanelLogin(c *gin.Context) error {
Language: "en",
}
response, cookies, err := service.MyService.OnePanel().Login(cred, onePanelServer)
response, cookies, err := service.MyService.OnePanel().Login(cred, config.NextWebInfo.Server, config.NextWebInfo.EntranceCode)
fmt.Println(response)
if err != nil {
logger.Error("OnePanel login failed", zap.Error(err))
logger.Error("NextWeb login failed", zap.Error(err))
return err
}
@@ -176,38 +173,6 @@ func OnePanelLogin(c *gin.Context) error {
return nil
}
// 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, onePanelServer)
// if err != nil {
// c.JSON(common_err.SERVICE_ERROR,
// model.Result{
// Success: common_err.SERVICE_ERROR,
// Message: common_err.GetMsg(common_err.SERVICE_ERROR),
// })
// }
// session := sessions.Default(c)
// for _, cookie := range cookies {
// session.Set(cookie.Name, cookie.Value)
// c.SetCookie(cookie.Name, cookie.Value, 3600, "/", "", false, true)
// }
// session.Save()
// c.JSON(common_err.SUCCESS,
// model.Result{
// Success: common_err.SUCCESS,
// Message: common_err.GetMsg(common_err.SUCCESS),
// Data: response,
// })
// }
func OnePanelUpdateProxyWebsite(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
@@ -227,7 +192,7 @@ func OnePanelUpdateProxyWebsite(c *gin.Context) {
headers[key] = value[0]
}
var search model2.SearchWebsiteResponse
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, onePanelServer, headers)
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
@@ -239,7 +204,7 @@ func OnePanelUpdateProxyWebsite(c *gin.Context) {
var proxy model2.ProxyWebsiteRequest
proxy.ID = search.Data.Items[0].ID
var proxyResult model2.ProxyWebsiteResponse
proxyResult, err := service.MyService.OnePanel().GetProxyWebsite(proxy, onePanelServer, headers)
proxyResult, err := service.MyService.OnePanel().GetProxyWebsite(proxy, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
@@ -247,11 +212,11 @@ func OnePanelUpdateProxyWebsite(c *gin.Context) {
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
var updateProxy model2.ProxyDetail
updateProxy := model2.ProxyDetail{}
updateProxy = proxyResult.Data[0]
updateProxy.Operate = "edit"
updateProxy.ProxyPass = protocol + "://" + hostname + ":" + port
updateProxyResult, err := service.MyService.OnePanel().UpdateProxyWebsite(updateProxy, onePanelServer, headers)
updateProxyResult, err := service.MyService.OnePanel().UpdateProxyWebsite(updateProxy, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
@@ -273,6 +238,157 @@ func OnePanelUpdateProxyWebsite(c *gin.Context) {
Message: common_err.GetMsg(common_err.SUCCESS),
})
}
func OnePanelUpdateWebsite(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
domain := json["domain"]
port := json["port"]
protocol := json["protocol"]
hostname := json["hostname"]
sslProvider := json["sslProvider"]
headers := make(map[string]string)
for key, value := range c.Request.Header {
headers[key] = value[0]
}
var searchParam model2.SearchWebsiteRequest
searchParam.Name = domain
searchParam.Page = 1
searchParam.PageSize = 1
searchParam.OrderBy = "created_at"
searchParam.Order = "null"
searchParam.WebsiteGroupID = 0
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
if search.Data.Total > 0 {
//TODO get Website ProxyData
var proxy model2.ProxyWebsiteRequest
proxy.ID = search.Data.Items[0].ID
var proxyResult model2.ProxyWebsiteResponse
proxyResult, err := service.MyService.OnePanel().GetProxyWebsite(proxy, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
//TODO Update Website Proxies (update root)
updateProxy := model2.ProxyDetail{}
updateProxy = proxyResult.Data[0]
updateProxy.Operate = "edit"
updateProxy.ProxyPass = "http://" + hostname + ":" + port
updateProxyResult, err := service.MyService.OnePanel().UpdateProxyWebsite(updateProxy, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
fmt.Println(updateProxyResult)
sslId := -1
acmeId := 0
var validSSL bool
var searchSSLParam model2.SearchSSLRequest
if sslProvider == "selfSigned" {
searchSSLParam.AcmeAccountID = strconv.Itoa(acmeId)
}
searchSSLParam.Page = 0
searchSSLParam.PageSize = 0
searchSSL, err := service.MyService.OnePanel().SearchWebsiteSSl(searchSSLParam, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
return
}
for _, item := range searchSSL.Data {
if item.Provider == sslProvider && item.PrimaryDomain == domain && item.Status == "ready" {
sslId = item.ID
validSSL = true
break
}
}
if search.Data.Items[0].Protocol != protocol && protocol == "http" {
//TODO disable HTTPS
if sslId > 0 {
var updateHttps, err = UpdateWebsiteHttps(false, acmeId, sslId, search.Data.Items[0].ID, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
fmt.Println(updateHttps)
return
}
}
if sslId < 0 {
//TODO create new SSL if not exist
if sslProvider == "http" {
sslId, err = OnePanelApplyWebsiteSSl(domain, search.Data.Items[0].ID, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
if sslId > 0 {
validSSL, err = checkGlobalSSLStatus(sslId, headers, domain, 10)
if err != nil {
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.COMMAND_ERROR_INVALID_OPERATION,
Message: fmt.Sprintf("Fail to upgrade %s from http to https", domain),
Data: false,
})
return
}
}
} else {
sslId, err = IssueSelfSignedCert(domain, search.Data.Items[0].ID, headers, 3)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
validSSL = true
}
}
if sslId < 0 || !validSSL {
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.COMMAND_ERROR_INVALID_OPERATION,
Message: fmt.Sprintf("Fail to Create SSL or domain %s is invalid to create global SSL", domain),
Data: false,
})
return
}
updateHttps, err := UpdateWebsiteHttps(true, acmeId, sslId, search.Data.Items[0].ID, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
fmt.Println(updateHttps)
return
}
}
func OnePanelCreateWebsite(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
@@ -280,20 +396,21 @@ func OnePanelCreateWebsite(c *gin.Context) {
port := json["port"]
protocol := json["protocol"]
hostname := json["hostname"]
sslProvider := json["sslProvider"]
var website model2.CreateWebsiteRequest
website.PrimaryDomain = domain
website.Type = "proxy"
website.Alias = domain
website.AppType = "installed"
website.WebSiteGroupID = 2
website.Proxy = protocol + "://" + hostname + ":" + port
website.Proxy = "http://" + hostname + ":" + port
portInt, err := strconv.ParseInt(port, 10, 64)
if err != nil {
log.Printf("Error converting port to integer: %v", err)
}
website.Port = portInt
website.ProxyProtocol = protocol
website.ProxyProtocol = "http"
website.ProxyAddress = hostname + ":" + port
website.RuntimeType = "php"
headers := make(map[string]string)
@@ -307,7 +424,7 @@ func OnePanelCreateWebsite(c *gin.Context) {
searchParam.OrderBy = "created_at"
searchParam.Order = "null"
searchParam.WebsiteGroupID = 0
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, onePanelServer, headers)
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
@@ -316,7 +433,7 @@ func OnePanelCreateWebsite(c *gin.Context) {
})
}
if search.Data.Total == 0 {
response, err := service.MyService.OnePanel().CreateWebsite(website, onePanelServer, headers)
response, err := service.MyService.OnePanel().CreateWebsite(website, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
@@ -324,13 +441,136 @@ func OnePanelCreateWebsite(c *gin.Context) {
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: response,
})
return
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
if protocol == "https" {
//TODO Find SSL
var validSSL bool
var searchSSL model2.SearchSSLRequest
searchSSL.Page = 0
searchSSL.PageSize = 0
sslId := -1
ssl, err := service.MyService.OnePanel().SearchWebsiteSSl(searchSSL, config.NextWebInfo.Server, headers)
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 _, item := range ssl.Data {
if item.PrimaryDomain == domain && item.Provider == sslProvider && item.Status == "ready" {
sslId = item.ID
validSSL = true
break
}
}
if sslId < 0 {
if sslProvider == "http" {
sslId, err = OnePanelApplyWebsiteSSl(domain, search.Data.Items[0].ID, headers)
if err != nil {
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.COMMAND_ERROR_INVALID_OPERATION,
Message: fmt.Sprintf("Fail to upgrade %s from http to https", domain),
Data: false,
})
return
}
if sslId > 0 {
validSSL, err = checkGlobalSSLStatus(sslId, headers, domain, 10)
if err != nil {
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.COMMAND_ERROR_INVALID_OPERATION,
Message: fmt.Sprintf("Fail to upgrade %s from http to https", domain),
Data: false,
})
return
}
}
} else {
sslId, err = IssueSelfSignedCert(domain, search.Data.Items[0].ID, headers, 3)
if err != nil {
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.COMMAND_ERROR_INVALID_OPERATION,
Message: fmt.Sprintf("Fail to upgrade %s from http to https", domain),
Data: false,
})
return
}
validSSL = true
}
}
if sslId < 0 || !validSSL {
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.COMMAND_ERROR_INVALID_OPERATION,
Message: fmt.Sprintf("Fail to Create SSL or domain %s is invalid to create global SSL", domain),
Data: false,
})
return
}
// TODO Enable HTTPS
var searchAcme model2.AcmeSearchRequest
acmeId := 0
searchAcme.Page = 1
searchAcme.PageSize = 1000
if sslProvider == "http" {
acme, err := service.MyService.OnePanel().AcmeAccountSearch(searchAcme, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
return
}
acmeId = acme.Data.Items[0].ID
}
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
updateWebsite, err := UpdateWebsiteHttps(true, acmeId, sslId, search.Data.Items[0].ID, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
return
}
if updateWebsite.Code < 200 || updateWebsite.Code > 300 {
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.COMMAND_ERROR_INVALID_OPERATION,
Message: fmt.Sprintf("Fail to upgrade %s from http to https", domain),
Data: false,
})
return
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: response,
})
return
}
}
c.JSON(common_err.SUCCESS,
model.Result{
@@ -338,10 +578,153 @@ func OnePanelCreateWebsite(c *gin.Context) {
Message: common_err.GetMsg(common_err.SUCCESS),
})
}
func checkGlobalSSLStatus(sslId int, headers map[string]string, domain string, retries int) (bool, error) {
if retries <= 0 {
return false, errors.New("timeout waiting for SSL certificate to become ready")
}
sslDetail, err := service.MyService.OnePanel().GetSSLDetail(sslId, config.NextWebInfo.Server, headers)
if err != nil {
return false, err
}
if sslDetail.Data.Status == "ready" {
return true, nil
}
if sslDetail.Data.Status == "applyError" {
return false, nil
}
time.Sleep(3 * time.Second)
return checkGlobalSSLStatus(sslId, headers, domain, retries-1)
}
func IssueSelfSignedCert(domain string, websiteId int, headers map[string]string, maxAttempts int) (int, error) {
if maxAttempts <= 0 {
return 0, errors.New("maximum attempts reached")
}
var searchSelfSignedCert model2.SelfSignedCertSearchRequest
searchSelfSignedCert.Page = 1
searchSelfSignedCert.PageSize = 1000
selfsignedCert, err := service.MyService.OnePanel().SelfSignedCertSearch(searchSelfSignedCert, config.NextWebInfo.Server, headers)
if err != nil {
return 0, err
}
if selfsignedCert.Data.Total == 0 {
var createParam model2.CreateSelfSignedCertRequest
createParam.Name = "nextweb"
createParam.KeyType = "P256"
createParam.CommonName = "nextweb"
createParam.Country = "VN"
createParam.Organization = "nextweb"
createParam.OrganizationUint = "nextweb"
createParam.Province = "HaDong"
createParam.City = "HaNoi"
createNewSelfSignCert, err := service.MyService.OnePanel().CreateSelfSignedCert(createParam, config.NextWebInfo.Server, headers)
if err != nil {
return 0, err
}
fmt.Println(createNewSelfSignCert)
return IssueSelfSignedCert(domain, websiteId, headers, maxAttempts-1)
} else {
var issueSelfSignedCertReq model2.SelfSignedIssueRequest
issueSelfSignedCertReq.KeyType = "P256"
issueSelfSignedCertReq.Domains = domain
issueSelfSignedCertReq.ID = selfsignedCert.Data.Items[0].ID
issueSelfSignedCertReq.Time = 10
issueSelfSignedCertReq.Unit = "year"
issueSelfSignedCertReq.PushDir = false
issueSelfSignedCertReq.Dir = ""
issueSelfSignedCertReq.AutoRenew = true
issueSelfSignedCertReq.Description = ""
issueSelfSignedCertReq.ExecShell = false
issueSelfSignedCertReq.Shell = ""
issueSelfSignedCertRes, err := service.MyService.OnePanel().IssueSelfSignedCert(issueSelfSignedCertReq, config.NextWebInfo.Server, headers)
if err != nil {
return 0, err
}
fmt.Println(issueSelfSignedCertRes)
var searchSSL model2.SearchSSLRequest
searchSSL.Page = 0
searchSSL.PageSize = 0
ssl, err := service.MyService.OnePanel().SearchWebsiteSSl(searchSSL, config.NextWebInfo.Server, headers)
if err != nil {
return 0, err
}
for _, item := range ssl.Data {
if item.PrimaryDomain == domain {
return item.ID, nil
}
}
return 0, err
}
}
func OnePanelApplyWebsiteSSl(domain string, websiteId int, headers map[string]string) (int, error) {
var searchAcme model2.AcmeSearchRequest
searchAcme.Page = 1
searchAcme.PageSize = 10000
acme, err := service.MyService.OnePanel().AcmeAccountSearch(searchAcme, config.NextWebInfo.Server, headers)
if err != nil {
return 0, err
}
if acme.Data.Total > 0 {
var createSSL model2.CreateSSLRequest
createSSL.ID = 1
createSSL.PrimaryDomain = domain
createSSL.OtherDomains = ""
createSSL.Provider = "http"
createSSL.WebsiteID = websiteId
createSSL.AcmeAccountID = acme.Data.Items[0].ID
createSSL.AutoRenew = true
createSSL.KeyType = "P256"
createSSL.PushDir = false
createSSL.Dir = ""
createSSL.Description = ""
createSSL.DisableCNAME = false
createSSL.Nameserver1 = ""
createSSL.Nameserver2 = ""
createSSL.ExecShell = false
createSSL.Shell = ""
createSSLRes, err := service.MyService.OnePanel().ApplyWebsiteSSl(createSSL, config.NextWebInfo.Server, headers)
return createSSLRes.Data.ID, err
}
return 0, err
}
func UpdateWebsiteHttps(enable bool, acmeAccountID int, websiteSSLID int, websiteId int, headers map[string]string) (model2.GenericResponse, error) {
var updateConfig model2.WebsiteHttpsConfigRequest
updateConfig.AcmeAccountID = acmeAccountID
updateConfig.Enable = enable
updateConfig.WebsiteSSLID = websiteSSLID
updateConfig.WebsiteID = websiteId
updateConfig.Type = "existed"
updateConfig.ImportType = "paste"
updateConfig.PrivateKey = ""
updateConfig.Certificate = ""
updateConfig.PrivateKeyPath = ""
updateConfig.HTTPConfig = "HTTPToHTTPS"
updateConfig.Hsts = true
updateConfig.Algorithm = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED"
updateConfig.SSLProtocol = append(updateConfig.SSLProtocol, "TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1")
updateWebsite, err := service.MyService.OnePanel().UpdateWebsiteProtocol(updateConfig, config.NextWebInfo.Server, headers)
if err != nil {
return model2.GenericResponse{}, err
}
return updateWebsite, nil
}
func OnePanelDeleteWebsite(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
domain := json["domain"]
deleteSSL, err := strconv.ParseBool(json["deleteSSL"])
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
test := json["deleteSSL"]
fmt.Println(test)
var searchParam model2.SearchWebsiteRequest
searchParam.Name = domain
searchParam.Page = 1
@@ -353,7 +736,7 @@ func OnePanelDeleteWebsite(c *gin.Context) {
for key, value := range c.Request.Header {
headers[key] = value[0]
}
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, onePanelServer, headers)
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
@@ -367,7 +750,7 @@ func OnePanelDeleteWebsite(c *gin.Context) {
delete.DeleteApp = false
delete.DeleteBackup = false
delete.ForceDelete = false
response, err := service.MyService.OnePanel().DeleteWebsite(delete, onePanelServer, headers)
response, err := service.MyService.OnePanel().DeleteWebsite(delete, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
@@ -381,7 +764,45 @@ func OnePanelDeleteWebsite(c *gin.Context) {
Message: common_err.GetMsg(common_err.SUCCESS),
Data: response,
})
return
}
if deleteSSL {
var searchSSLParam model2.SearchSSLRequest
searchSSLParam.AcmeAccountID = ""
searchSSLParam.Page = 0
searchSSLParam.PageSize = 0
searchSSL, err := service.MyService.OnePanel().SearchWebsiteSSl(searchSSLParam, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
if len(searchSSL.Data) > 0 {
var deleleSSL model2.DeleteSSLRequest
for _, ssl := range searchSSL.Data {
if ssl.PrimaryDomain == domain {
deleleSSL.Ids = append(deleleSSL.Ids, ssl.ID)
}
}
if len(deleleSSL.Ids) > 0 {
deleteResult, err := service.MyService.OnePanel().DeleteWebsiteSSL(deleleSSL, config.NextWebInfo.Server, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
fmt.Println(deleteResult)
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
})
return
}
}
}
c.JSON(common_err.SUCCESS,
model.Result{
@@ -471,7 +892,7 @@ var oidcInit bool
func InitOIDC() {
const (
maxSleep = 60 * time.Second
minSleep = 10 * time.Second
minSleep = 3 * time.Second
maxRetryBackoff = 5 // Cap retry backoff to 5 attempts
)
@@ -498,10 +919,10 @@ func InitOIDC() {
successCount++
// TODO will enable in production
// Exponential backoff with a cap
// sleepTime = minSleep * time.Duration(successCount)
sleepTime = minSleep * time.Duration(successCount)
if sleepTime > maxSleep {
// TODO will enable in production
// sleepTime = maxSleep
sleepTime = maxSleep
}
} else {
@@ -512,7 +933,7 @@ func InitOIDC() {
sleepTime = minSleep * time.Duration(failCount)
if failCount > maxRetryBackoff {
// TODO will enable in production
// sleepTime = minSleep * time.Duration(maxRetryBackoff)
sleepTime = minSleep * time.Duration(maxRetryBackoff)
}
log.Printf("OIDC initialization failed: %v. Retrying in %v", err, sleepTime)
}
@@ -526,7 +947,7 @@ func CheckOIDCInit() gin.HandlerFunc {
return func(c *gin.Context) {
if !oidcInit {
log.Println("Provider is Offline")
c.JSON(http.StatusServiceUnavailable, model.Result{Success: common_err.OIDC_OFFLINE, Message: "Authentik Server is Offline"})
//c.JSON(http.StatusServiceUnavailable, model.Result{Success: common_err.OIDC_OFFLINE, Message: "Authentik Server is Offline"})
return
}
c.Next()
@@ -542,6 +963,12 @@ func OIDC() error {
authServer = authentik.Issuer
authURL = authentik.AuthUrl
callbackURL = authentik.CallbackUrl
} else {
clientID = config.OIDCInfo.ClientID
clientSecret = config.OIDCInfo.ClientSecret
authServer = config.OIDCInfo.AuthServer
authURL = config.OIDCInfo.AuthURL
callbackURL = config.OIDCInfo.CallbackURL
}
ctx := context.Background()
provider, err := oidc.NewProvider(ctx, authURL)
@@ -554,7 +981,6 @@ func OIDC() error {
RedirectURL: callbackURL,
Endpoint: provider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID, "profile", "email", "offline_access", "goauthentik.io/api"},
//add offline access for refresh token
}
return nil
}
@@ -681,28 +1107,27 @@ func OIDCValidateToken(c *gin.Context) {
var validateToken model2.AuthentikToken
validateToken, err = service.MyService.Authentik().ValidateToken(clientID, clientSecret, accessToken, authServer)
if err != nil {
c.JSON(http.StatusUnauthorized, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
return
}
if !validateToken.Active {
c.JSON(http.StatusUnauthorized, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
return
}
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN)})
}
func OIDCLogout(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
flow := "/if/flow/default-authentication-flow/"
next := "/application/o/authorize/"
client := "client_id=" + clientID
redirect_uri := "&redirect_uri=" + url.QueryEscape(callbackURL)
response_type := "&response_type=code"
scope := "&scope=openid+profile+email+" + url.QueryEscape("goauthentik.io/api")
state := "&state=" + url.QueryEscape("/#/profile")
fullURL := authServer + flow + "?" + "next=" + url.QueryEscape(next+"?"+client+redirect_uri+response_type+scope+state)
// json := make(map[string]string)
// c.ShouldBind(&json)
// flow := "/if/flow/default-authentication-flow/"
// next := "/application/o/authorize/"
// client := "client_id=" + clientID
// redirect_uri := "&redirect_uri=" + url.QueryEscape(callbackURL)
// response_type := "&response_type=code"
// scope := "&scope=openid+profile+email+" + url.QueryEscape("goauthentik.io/api")
// state := "&state=" + url.QueryEscape("/#/profile")
//fullURL := authServer + flow + "?" + "next=" + url.QueryEscape(next+"?"+client+redirect_uri+response_type+scope+state)
fullURL := "https://home.nextzenvn.com/outpost.goauthentik.io/sign_out"
c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_AUTH_TOKEN, Message: common_err.GetMsg(common_err.ERROR_AUTH_TOKEN), Data: fullURL})
}
func OIDCProfile(c *gin.Context) {
@@ -773,7 +1198,7 @@ func determineUserRole(isSuperuser bool) string {
return "user"
}
func OnePanelHealthCheck(c *gin.Context) {
status, err := service.MyService.OnePanel().HealthCheck(onePanelServer)
status, err := service.MyService.OnePanel().HealthCheck(config.NextWebInfo.Server)
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
@@ -1225,7 +1650,6 @@ func GetUserCustomConf(c *gin.Context) {
return
}
id := c.GetHeader("user_id")
user := service.MyService.User().GetUserInfoById(id)
// user := service.MyService.User().GetUserInfoByUsername(Username)
if user.Id == 0 {
@@ -1233,14 +1657,23 @@ func GetUserCustomConf(c *gin.Context) {
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json"
data := file.ReadFullFile(filePath)
if !gjson.ValidBytes(data) {
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)})
return
if name == "default-app" {
filePath := config.AppInfo.UserDataPath + "/default/link.json"
data := file.ReadFullFile(filePath)
if !gjson.ValidBytes(data) {
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)})
return
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
} else {
filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json"
data := file.ReadFullFile(filePath)
if !gjson.ValidBytes(data) {
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)})
return
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
}
/**
@@ -1262,21 +1695,52 @@ func PostUserCustomConf(c *gin.Context) {
model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)})
return
}
data, _ := io.ReadAll(c.Request.Body)
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id)
if err := file.IsNotExistMkDir(filePath); err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
data, err := io.ReadAll(c.Request.Body)
if err != nil {
logger.Error("Failed to read request body", zap.Error(err))
c.JSON(common_err.SERVICE_ERROR, model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
return
}
if name == "default-app" {
var appInfos []model.AppInfo
err := json.Unmarshal([]byte(data), &appInfos)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
}
go func() {
configData := formatAppInfosToMap(appInfos)
cfg.WriteMapToConfig(configData, name)
}()
filePath := config.AppInfo.UserDataPath + "/default"
if err := file.IsNotExistMkDir(filePath); err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
}
if err := file.WriteToPath(data, filePath, "link.json"); err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
}
} else {
filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id)
if err := file.IsNotExistMkDir(filePath); err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
}
if err := file.WriteToPath(data, filePath, name+".json"); err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
if err := file.WriteToPath(data, filePath, name+".json"); err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)})
return
}
}
if name == "system" {
dataMap := make(map[string]string, 1)
dataMap["system"] = string(data)
@@ -1288,11 +1752,19 @@ func PostUserCustomConf(c *gin.Context) {
if response.StatusCode() != http.StatusOK {
logger.Error("failed to publish event to message bus", zap.String("status", response.Status()), zap.Any("response", response))
}
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))})
}
func formatAppInfosToMap(appInfos []model.AppInfo) map[string]string {
formattedMap := make(map[string]string)
for _, appInfo := range appInfos {
formattedString := fmt.Sprintf("%s-%s-%s-%s-%s",
appInfo.Name, appInfo.Hostname, appInfo.Icon, appInfo.AppType, appInfo.Status)
formattedMap[appInfo.Name] = formattedString
}
return formattedMap
}
/**
* @description: delete user custom config
@@ -1585,7 +2057,7 @@ func DeleteUserAll(c *gin.Context) {
// })
// }
func GetUserStatus(c *gin.Context) {
func InitializedUser(c *gin.Context) {
data := make(map[string]interface{}, 2)
key := uuid.NewV4().String()
service.UserRegisterHash[key] = key
+181 -6
View File
@@ -2,6 +2,7 @@ package service
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"log"
@@ -11,20 +12,24 @@ import (
)
type OnePanelService interface {
Login(m model2.OnePanelCredentials, baseURL string) (model2.LoginResponse, []*http.Cookie, error)
Login(m model2.OnePanelCredentials, baseURL string, entranceCode string) (model2.LoginResponse, []*http.Cookie, error)
Logout(m model2.OnePanelCredentials, baseURL string) (model2.LogoutResponse, error)
HealthCheck(baseURL string) (string, error)
SearchInstalledApp(p model2.InstalledAppRequest, baseURL string) (model2.InstalledAppResponse, error)
// InstallApp()
SearchWebsite(m model2.SearchWebsiteRequest, baseUrl string, headers map[string]string) (model2.SearchWebsiteResponse, error)
CreateWebsite(m model2.CreateWebsiteRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error)
DeleteWebsite(m model2.DeleteWebsiteRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error)
GetProxyWebsite(m model2.ProxyWebsiteRequest, baseUrl string, headers map[string]string) (model2.ProxyWebsiteResponse, error)
UpdateProxyWebsite(m model2.ProxyDetail, baseUrl string, headers map[string]string) (model2.GenericResponse, error)
AcmeAccountSearch(m model2.AcmeSearchRequest, baseUrl string, headers map[string]string) (model2.AcmeSearchResponse, error)
SelfSignedCertSearch(m model2.SelfSignedCertSearchRequest, baseUrl string, headers map[string]string) (model2.SelfSignedCertSearchResponse, error)
IssueSelfSignedCert(m model2.SelfSignedIssueRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error)
CreateSelfSignedCert(m model2.CreateSelfSignedCertRequest, baseUrl string, headers map[string]string) (model2.CreateSelfSignedCertResponse, error)
ApplyWebsiteSSl(m model2.CreateSSLRequest, baseUrl string, headers map[string]string) (model2.CreateSSLResponse, error)
SearchWebsiteSSl(m model2.SearchSSLRequest, baseUrl string, headers map[string]string) (model2.SearchSSLResponse, error)
//UpdateWebsiteProtocol
UpdateWebsiteProtocol(m model2.WebsiteHttpsConfigRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error)
DeleteWebsiteSSL(m model2.DeleteSSLRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error)
GetSSLDetail(sslId int, baseUrl string, headers map[string]string) (model2.SSLDetail, error)
}
var (
@@ -34,7 +39,177 @@ var (
type onePanelService struct {
}
// TODO A lot of redundant code need refactor
func (o *onePanelService) GetSSLDetail(sslId int, baseUrl string, headers map[string]string) (model2.SSLDetail, error) {
path := baseUrl + fmt.Sprintf("/api/v1/websites/ssl/%d", sslId)
req, err := http.NewRequest("GET", path, nil)
if err != nil {
return model2.SSLDetail{}, fmt.Errorf("error creating request: %v", err)
}
// Add headers to the request
for key, value := range headers {
req.Header.Set(key, value)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return model2.SSLDetail{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.SSLDetail{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.SSLDetail
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.SSLDetail{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) DeleteWebsiteSSL(m model2.DeleteSSLRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error) {
path := baseUrl + "/api/v1/websites/ssl/del"
reqBody, err := json.Marshal(m)
if err != nil {
return model2.GenericResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.GenericResponse{}, fmt.Errorf("error creating request: %v", err)
}
// Add headers to the request
for key, value := range headers {
req.Header.Set(key, value)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return model2.GenericResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.GenericResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.GenericResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.GenericResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) UpdateWebsiteProtocol(m model2.WebsiteHttpsConfigRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error) {
path := baseUrl + fmt.Sprintf("/api/v1/websites/%d/https", m.WebsiteID)
reqBody, err := json.Marshal(m)
if err != nil {
return model2.GenericResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.GenericResponse{}, fmt.Errorf("error creating request: %v", err)
}
// Add headers to the request
for key, value := range headers {
req.Header.Set(key, value)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return model2.GenericResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.GenericResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.GenericResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.GenericResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) SelfSignedCertSearch(m model2.SelfSignedCertSearchRequest, baseUrl string, headers map[string]string) (model2.SelfSignedCertSearchResponse, error) {
path := baseUrl + "/api/v1/websites/ca/search"
reqBody, err := json.Marshal(m)
if err != nil {
return model2.SelfSignedCertSearchResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.SelfSignedCertSearchResponse{}, fmt.Errorf("error creating request: %v", err)
}
// Add headers to the request
for key, value := range headers {
req.Header.Set(key, value)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return model2.SelfSignedCertSearchResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.SelfSignedCertSearchResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.SelfSignedCertSearchResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.SelfSignedCertSearchResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) CreateSelfSignedCert(m model2.CreateSelfSignedCertRequest, baseUrl string, headers map[string]string) (model2.CreateSelfSignedCertResponse, error) {
path := baseUrl + "/api/v1/websites/ca"
reqBody, err := json.Marshal(m)
if err != nil {
return model2.CreateSelfSignedCertResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.CreateSelfSignedCertResponse{}, fmt.Errorf("error creating request: %v", err)
}
// Add headers to the request
for key, value := range headers {
req.Header.Set(key, value)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return model2.CreateSelfSignedCertResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.CreateSelfSignedCertResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.CreateSelfSignedCertResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.CreateSelfSignedCertResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) IssueSelfSignedCert(m model2.SelfSignedIssueRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error) {
path := baseUrl + "/api/v1/websites/ca/obtain"
reqBody, err := json.Marshal(m)
if err != nil {
return model2.GenericResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.GenericResponse{}, fmt.Errorf("error creating request: %v", err)
}
// Add headers to the request
for key, value := range headers {
req.Header.Set(key, value)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return model2.GenericResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.GenericResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.GenericResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.GenericResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) SearchWebsiteSSl(m model2.SearchSSLRequest, baseUrl string, headers map[string]string) (model2.SearchSSLResponse, error) {
path := baseUrl + "/api/v1/websites/ssl/search"
reqBody, err := json.Marshal(m)
@@ -298,7 +473,7 @@ func (o *onePanelService) SearchInstalledApp(m model2.InstalledAppRequest, baseU
return result, nil
}
func (o *onePanelService) Login(m model2.OnePanelCredentials, baseURL string) (model2.LoginResponse, []*http.Cookie, error) {
func (o *onePanelService) Login(m model2.OnePanelCredentials, baseURL string, entranceCode string) (model2.LoginResponse, []*http.Cookie, error) {
path := baseURL + prefixV1 + "/auth/login"
// Create the request body by marshaling the credentials into JSON
@@ -313,7 +488,7 @@ func (o *onePanelService) Login(m model2.OnePanelCredentials, baseURL string) (m
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
req.Header.Set("Entrancecode", base64.StdEncoding.EncodeToString([]byte(entranceCode)))
// Reuse the HTTP client (consider making it a field in onePanelService)
client := &http.Client{}
resp, err := client.Do(req)
+4
View File
@@ -40,6 +40,10 @@ func (a *authentikService) UpdateSettings(m model2.AuthentikCredentialsDBModel)
var existing model2.AuthentikCredentialsDBModel
result := a.db.First(&existing)
if result.Error != nil {
if result.Error.Error() == "record not found" {
a.db.Create(&m)
return existing, nil
}
return existing, result.Error
}
+254 -41
View File
@@ -46,58 +46,127 @@ type CreateSSLResponse struct {
Shell string `json:"shell"`
} `json:"data"`
}
type CreateSelfSignedCertRequest struct {
Name string `json:"name"`
KeyType string `json:"keyType"`
CommonName string `json:"commonName"`
Country string `json:"country"`
Organization string `json:"organization"`
OrganizationUint string `json:"organizationUint"`
Province string `json:"province"`
City string `json:"city"`
}
type CreateSelfSignedCertResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
CommonName string `json:"commonName"`
Country string `json:"country"`
Organization string `json:"organization"`
OrganizationUint string `json:"organizationUint"`
Name string `json:"name"`
KeyType string `json:"keyType"`
Province string `json:"province"`
City string `json:"city"`
} `json:"data"`
}
type SelfSignedIssueRequest struct {
KeyType string `json:"keyType"`
Domains string `json:"domains"`
ID int `json:"id"`
Time int `json:"time"`
Unit string `json:"unit"`
PushDir bool `json:"pushDir"`
Dir string `json:"dir"`
AutoRenew bool `json:"autoRenew"`
Description string `json:"description"`
ExecShell bool `json:"execShell"`
Shell string `json:"shell"`
}
type AcmeSearchRequest struct {
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
type SearchSSLRequest struct {
type SelfSignedCertSearchRequest struct {
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
type SearchSSLRequest struct {
AcmeAccountID string `json:"acmeAccountID"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
type SearchSSLResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Total int `json:"total"`
Items []struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
PrimaryDomain string `json:"primaryDomain"`
PrivateKey string `json:"privateKey"`
Pem string `json:"pem"`
Domains string `json:"domains"`
CertURL string `json:"certURL"`
Type string `json:"type"`
Provider string `json:"provider"`
Organization string `json:"organization"`
DNSAccountID int `json:"dnsAccountId"`
AcmeAccountID int `json:"acmeAccountId"`
CaID int `json:"caId"`
AutoRenew bool `json:"autoRenew"`
ExpireDate time.Time `json:"expireDate"`
StartDate time.Time `json:"startDate"`
Status string `json:"status"`
Message string `json:"message"`
KeyType string `json:"keyType"`
PushDir bool `json:"pushDir"`
Dir string `json:"dir"`
Description string `json:"description"`
SkipDNS bool `json:"skipDNS"`
Nameserver1 string `json:"nameserver1"`
Nameserver2 string `json:"nameserver2"`
DisableCNAME bool `json:"disableCNAME"`
ExecShell bool `json:"execShell"`
Shell string `json:"shell"`
AcmeAccount AcmeAccount `json:"acmeAccount"`
DNSAccount DNSAccount `json:"dnsAccount"`
Websites []interface{} `json:"websites"`
LogPath string `json:"logPath"`
} `json:"items"`
Data []struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
PrimaryDomain string `json:"primaryDomain"`
PrivateKey string `json:"privateKey"`
Pem string `json:"pem"`
Domains string `json:"domains"`
CertURL string `json:"certURL"`
Type string `json:"type"`
Provider string `json:"provider"`
Organization string `json:"organization"`
DNSAccountID int `json:"dnsAccountId"`
AcmeAccountID int `json:"acmeAccountId"`
CaID int `json:"caId"`
AutoRenew bool `json:"autoRenew"`
ExpireDate time.Time `json:"expireDate"`
StartDate time.Time `json:"startDate"`
Status string `json:"status"`
Message string `json:"message"`
KeyType string `json:"keyType"`
PushDir bool `json:"pushDir"`
Dir string `json:"dir"`
Description string `json:"description"`
SkipDNS bool `json:"skipDNS"`
Nameserver1 string `json:"nameserver1"`
Nameserver2 string `json:"nameserver2"`
DisableCNAME bool `json:"disableCNAME"`
ExecShell bool `json:"execShell"`
Shell string `json:"shell"`
AcmeAccount struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Email string `json:"email"`
URL string `json:"url"`
Type string `json:"type"`
EabKid string `json:"eabKid"`
EabHmacKey string `json:"eabHmacKey"`
KeyType string `json:"keyType"`
} `json:"acmeAccount"`
DNSAccount struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Name string `json:"name"`
Type string `json:"type"`
} `json:"dnsAccount"`
Websites interface{} `json:"websites"`
LogPath string `json:"logPath"`
} `json:"data"`
}
type WebsiteHttpsConfigRequest struct {
AcmeAccountID int `json:"acmeAccountID"`
Enable bool `json:"enable"`
WebsiteID int `json:"websiteId"`
WebsiteSSLID int `json:"websiteSSLId"`
Type string `json:"type"`
ImportType string `json:"importType"`
PrivateKey string `json:"privateKey"`
Certificate string `json:"certificate"`
PrivateKeyPath string `json:"privateKeyPath"`
CertificatePath string `json:"certificatePath"`
HTTPConfig string `json:"httpConfig"`
Hsts bool `json:"hsts"`
Algorithm string `json:"algorithm"`
SSLProtocol []string `json:"SSLProtocol"`
}
type AcmeSearchResponse struct {
Code int `json:"code"`
Message string `json:"message"`
@@ -106,7 +175,95 @@ type AcmeSearchResponse struct {
Items []AcmeAccount `json:"items"`
} `json:"data"`
}
type SelfSignedCertSearchResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Total int `json:"total"`
Items []struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Csr string `json:"csr"`
Name string `json:"name"`
PrivateKey string `json:"privateKey"`
KeyType string `json:"keyType"`
CommonName string `json:"commonName"`
Country string `json:"country"`
Organization string `json:"organization"`
OrganizationUint string `json:"organizationUint"`
Province string `json:"province"`
City string `json:"city"`
} `json:"items"`
} `json:"data"`
}
type DeleteSSLRequest struct {
Ids []int `json:"ids"`
}
type WebsiteDetail struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Protocol string `json:"protocol"`
PrimaryDomain string `json:"primaryDomain"`
Type string `json:"type"`
Alias string `json:"alias"`
Remark string `json:"remark"`
Status string `json:"status"`
HTTPConfig string `json:"httpConfig"`
ExpireDate time.Time `json:"expireDate"`
Proxy string `json:"proxy"`
ProxyType string `json:"proxyType"`
SiteDir string `json:"siteDir"`
ErrorLog bool `json:"errorLog"`
AccessLog bool `json:"accessLog"`
DefaultServer bool `json:"defaultServer"`
IPV6 bool `json:"IPV6"`
Rewrite string `json:"rewrite"`
WebSiteGroupID int `json:"webSiteGroupId"`
WebSiteSSLID int `json:"webSiteSSLId"`
RuntimeID int `json:"runtimeID"`
AppInstallID int `json:"appInstallId"`
FtpID int `json:"ftpId"`
User string `json:"user"`
Group string `json:"group"`
Domains interface{} `json:"domains"`
WebSiteSSL WebsiteSSL `json:"webSiteSSL"`
}
type WebsiteSSL struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
PrimaryDomain string `json:"primaryDomain"`
PrivateKey string `json:"privateKey"`
Pem string `json:"pem"`
Domains string `json:"domains"`
CertURL string `json:"certURL"`
Type string `json:"type"`
Provider string `json:"provider"`
Organization string `json:"organization"`
DNSAccountID int `json:"dnsAccountId"`
AcmeAccountID int `json:"acmeAccountId"`
CaID int `json:"caId"`
AutoRenew bool `json:"autoRenew"`
ExpireDate time.Time `json:"expireDate"`
StartDate time.Time `json:"startDate"`
Status string `json:"status"`
Message string `json:"message"`
KeyType string `json:"keyType"`
PushDir bool `json:"pushDir"`
Dir string `json:"dir"`
Description string `json:"description"`
SkipDNS bool `json:"skipDNS"`
Nameserver1 string `json:"nameserver1"`
Nameserver2 string `json:"nameserver2"`
DisableCNAME bool `json:"disableCNAME"`
ExecShell bool `json:"execShell"`
Shell string `json:"shell"`
AcmeAccount AcmeAccount `json:"acmeAccount"`
DNSAccount DNSAccount `json:"dnsAccount"`
Websites interface{} `json:"websites"`
}
type AcmeAccount struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
@@ -125,3 +282,59 @@ type DNSAccount struct {
Name string `json:"name"`
Type string `json:"type"`
}
type SSLDetail struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
PrimaryDomain string `json:"primaryDomain"`
PrivateKey string `json:"privateKey"`
Pem string `json:"pem"`
Domains string `json:"domains"`
CertURL string `json:"certURL"`
Type string `json:"type"`
Provider string `json:"provider"`
Organization string `json:"organization"`
DNSAccountID int `json:"dnsAccountId"`
AcmeAccountID int `json:"acmeAccountId"`
CaID int `json:"caId"`
AutoRenew bool `json:"autoRenew"`
ExpireDate time.Time `json:"expireDate"`
StartDate time.Time `json:"startDate"`
Status string `json:"status"`
Message string `json:"message"`
KeyType string `json:"keyType"`
PushDir bool `json:"pushDir"`
Dir string `json:"dir"`
Description string `json:"description"`
SkipDNS bool `json:"skipDNS"`
Nameserver1 string `json:"nameserver1"`
Nameserver2 string `json:"nameserver2"`
DisableCNAME bool `json:"disableCNAME"`
ExecShell bool `json:"execShell"`
Shell string `json:"shell"`
AcmeAccount struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Email string `json:"email"`
URL string `json:"url"`
Type string `json:"type"`
EabKid string `json:"eabKid"`
EabHmacKey string `json:"eabHmacKey"`
KeyType string `json:"keyType"`
} `json:"acmeAccount"`
DNSAccount struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Name string `json:"name"`
Type string `json:"type"`
} `json:"dnsAccount"`
Websites interface{} `json:"websites"`
LogPath string `json:"logPath"`
} `json:"data"`
}
+7 -5
View File
@@ -9,7 +9,6 @@ import (
"net/http"
"os"
"github.com/KaySar12/NextZen-UserService/pkg/config"
"github.com/KaySar12/NextZen-UserService/service/model"
)
@@ -36,7 +35,8 @@ func (o *omvService) LoginSession(username string, password string) (string, []*
},
})
responseBody := bytes.NewBuffer(postBody)
response, err := http.Post(config.AppInfo.OMVServer, "application/json", responseBody)
// response, err := http.Post(config.AppInfo.OMVServer, "application/json", responseBody)
response, err := http.Post("", "application/json", responseBody)
cookies := response.Cookies()
if err != nil {
fmt.Print(err.Error())
@@ -55,7 +55,8 @@ func (o *omvService) Logout(sessionID string) (string, error) {
"params": nil,
})
responseBody := bytes.NewBuffer(postBody)
req, err := http.NewRequest("POST", config.AppInfo.OMVServer, responseBody)
//req, err := http.NewRequest("POST", config.AppInfo.OMVServer, responseBody)
req, err := http.NewRequest("POST", "", responseBody)
if err != nil {
return "", fmt.Errorf("error creating request: %v", err)
}
@@ -89,7 +90,7 @@ func (o *omvService) AuthUser(username string, password string, sessionID string
},
})
responseBody := bytes.NewBuffer(postBody)
req, err := http.NewRequest("POST", config.AppInfo.OMVServer, responseBody)
req, err := http.NewRequest("POST", "", responseBody)
if err != nil {
return "", fmt.Errorf("error creating request: %v", err)
}
@@ -125,7 +126,8 @@ func (o *omvService) GetUser(username string, sessionID string) (string, error)
responseBody := bytes.NewBuffer(postBody)
// Create HTTP request and set session ID header
req, err := http.NewRequest("POST", config.AppInfo.OMVServer, responseBody)
// req, err := http.NewRequest("POST", config.AppInfo.OMVServer, responseBody)
req, err := http.NewRequest("POST", "", responseBody)
if err != nil {
return "", fmt.Errorf("error creating request: %v", err)
}