6 Commits

13 changed files with 950 additions and 34 deletions
+1 -1
View File
@@ -41,6 +41,6 @@ linux-amd64-nextzenos-user-service-v1.2.4.tar.gz
dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service
dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service
dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service
.env
.vscode/launch.json
dist/metadata.json
+1 -1
View File
@@ -6,7 +6,7 @@
"type": "go",
"debugAdapter": "dlv-dap",
"request": "launch",
"port": 34933,
"port": 39117,
"host": "127.0.0.1",
"mode": "exec",
"program": "${workspaceFolder}/dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service"
-1
View File
@@ -37,7 +37,6 @@ remove_tag:
@${GIT} tag -d ${CUR_TAG}
@${GIT} push ${GIT_REMOTE} -d ${CUR_TAG}
check_tag:
@echo "Previous tag: $(PREV_TAG)";
@echo "Current tag: $(CUR_TAG)";
push_release_all:
${GORELEASER} release --clean -f .goreleaser.yaml
+4
View File
@@ -11,6 +11,7 @@ require (
github.com/deepmap/oapi-codegen v1.12.4
github.com/getkin/kin-openapi v0.117.0
github.com/gin-contrib/gzip v0.0.6
github.com/gin-contrib/sessions v1.0.1
github.com/gin-gonic/gin v1.10.0
github.com/glebarez/sqlite v1.8.0
github.com/labstack/echo/v4 v4.12.0
@@ -48,7 +49,10 @@ require (
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/sessions v1.2.2 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
+10
View File
@@ -34,6 +34,8 @@ github.com/getkin/kin-openapi v0.117.0 h1:QT2DyGujAL09F4NrKDHJGsUoIprlIcFVHWDVDc
github.com/getkin/kin-openapi v0.117.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
github.com/gin-contrib/sessions v1.0.1 h1:3hsJyNs7v7N8OtelFmYXFrulAf6zSR7nW/putcPEHxI=
github.com/gin-contrib/sessions v1.0.1/go.mod h1:ouxSFM24/OgIud5MJYQJLpy6AwxQ5EYO9yLhbtObGkM=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
@@ -80,12 +82,20 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
+1
View File
@@ -125,6 +125,7 @@ func main() {
apiPaths := []string{
"/v1/users",
"/v1/1panel",
route.V2APIPath,
route.V2DocPath,
"/" + jwt.JWKSPath,
+22 -2
View File
@@ -9,6 +9,8 @@ import (
v1 "github.com/KaySar12/NextZen-UserService/route/v1"
"github.com/KaySar12/NextZen-UserService/service"
"github.com/gin-contrib/gzip"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
@@ -18,12 +20,16 @@ func InitRouter() *gin.Engine {
r.Use(v1.CheckOIDCInit())
r.Use(gzip.Gzip(gzip.DefaultCompression))
store := cookie.NewStore([]byte("secret"))
sessionMiddleware := sessions.Sessions("1Panel", store)
r.Use(sessionMiddleware)
// check if environment variable is set
if ginMode, success := os.LookupEnv("GIN_MODE"); success {
gin.SetMode(ginMode)
} else {
gin.SetMode(gin.ReleaseMode)
}
go v1.InitOIDC()
r.POST("/v1/users/register", v1.PostUserRegister)
r.POST("/v1/users/login", v1.PostUserLogin)
@@ -43,8 +49,13 @@ 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)
r.GET("/v1/1panel/health", v1.OnePanelHealthCheck)
// r.POST("/v1/1panel/login", v1.OnePanelLogin)
// r.POST("/v1/1panel/app/search", v1.ExternalAPIMiddleware, v1.OnePanelLogin)
// r.POST("/v1/1panel/website/search", v1.ExternalAPIMiddleware, v1.OnePanelLogin)
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)
v1Group := r.Group("/v1")
v1Group.Use(jwt.JWT(
@@ -54,6 +65,15 @@ func InitRouter() *gin.Engine {
},
))
{
// v1OnePanel := v1Group.Group("/1panel")
// v1OnePanel.Use()
// {
// r.GET("/health", v1.OnePanelHealthCheck)
// r.POST("/login", v1.OnePanelLogin)
// r.POST("/app/search", v1.ExternalAPIMiddleware, v1.OnePanelLogin)
// r.POST("/website/search", v1.ExternalAPIMiddleware, v1.OnePanelLogin)
// r.POST("/website/create", v1.ExternalAPIMiddleware, v1.OnePanelCreateWebsite)
// }
v1UsersGroup := v1Group.Group("/users")
v1UsersGroup.Use()
{
+267 -28
View File
@@ -36,6 +36,7 @@ import (
"github.com/KaySar12/NextZen-UserService/service"
model2 "github.com/KaySar12/NextZen-UserService/service/model"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
"github.com/tidwall/gjson"
@@ -45,17 +46,15 @@ import (
)
var (
//authServer = "http://10.0.0.26:9000"
authServer = "http://accessmanager.local"
clientID = "6KwKSxLCtaQ4r6HoAn3gdNMbNOAf75j3SejLIAx7"
clientSecret = "PE05fcDP4qESUmyZ1TNYpZNBxRPq70VpFI81vehsoJ6WhGz5yPXMljrFrOdMRdRhrYmF03fHWTZHgO9ZdNENrLN13BzL8CAgtEkTsyjXfgx9GvISheIjYfpSfvo219fL"
authURL = "http://accessmanager.local/application/o/nextzenos-oidc/"
//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@*"
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"
)
type OIDCSetting struct {
@@ -117,16 +116,35 @@ func PostUserRegister(c *gin.Context) {
var limiter = rate.NewLimiter(rate.Every(time.Minute), 5)
// @Summary login
// @Produce application/json
// @Accept application/json
// @Tags user
// @Param user_name query string true "User name"
// @Param pwd query string true "password"
// @Success 200 {string} string "ok"
// @Router /user/login [post]
func OnePanelLogin(c *gin.Context) {
var cred = model2.OnePanelCredentials{
// TODO Cant call login every request(using for testing only)
func ExternalAPIMiddleware(c *gin.Context) {
session := sessions.Default(c)
if err := OnePanelLogin(c); err != nil {
c.JSON(http.StatusUnauthorized, model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
c.Abort()
return
}
sessionId := session.Get("psession")
if sessionId == nil {
c.JSON(http.StatusInternalServerError, model.Result{
Success: common_err.SERVICE_ERROR,
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
c.Abort()
return
}
// Add sessionId to the request's Cookie header
c.Request.Header.Set("Cookie", "psession="+sessionId.(string))
c.Next()
}
func OnePanelLogin(c *gin.Context) error {
cred := model2.OnePanelCredentials{
Name: onePanelName,
Password: onePanelPassword,
IgnoreCaptcha: true,
@@ -135,7 +153,81 @@ func OnePanelLogin(c *gin.Context) {
AuthMethod: "session",
Language: "en",
}
response, cookies, err := service.MyService.OnePanel().Login(cred, "http://172.20.60.244:13000")
response, cookies, err := service.MyService.OnePanel().Login(cred, onePanelServer)
fmt.Println(response)
if err != nil {
logger.Error("OnePanel login failed", zap.Error(err))
return err
}
session := sessions.Default(c)
for _, cookie := range cookies {
session.Set(cookie.Name, cookie.Value)
session.Options(sessions.Options{
MaxAge: 3600, // 12hrs
})
}
if err := session.Save(); err != nil {
logger.Error("Failed to save session", zap.Error(err))
return err
}
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)
domain := json["domain"]
port := json["port"]
hostname := json["hostname"]
protocol := json["protocol"]
var searchParam model2.SearchWebsiteRequest
searchParam.Name = domain
searchParam.Page = 1
searchParam.PageSize = 1
searchParam.OrderBy = "created_at"
searchParam.Order = "null"
searchParam.WebsiteGroupID = 0
headers := make(map[string]string)
for key, value := range c.Request.Header {
headers[key] = value[0]
}
var search model2.SearchWebsiteResponse
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, onePanelServer, headers)
if err != nil {
c.JSON(common_err.SERVICE_ERROR,
model.Result{
@@ -143,14 +235,158 @@ func OnePanelLogin(c *gin.Context) {
Message: common_err.GetMsg(common_err.SERVICE_ERROR),
})
}
for _, cookie := range cookies {
c.SetCookie(cookie.Name, cookie.Value, 3600, "/", "", false, true)
if search.Data.Total > 0 {
var proxy model2.ProxyWebsiteRequest
proxy.ID = search.Data.Items[0].ID
var proxyResult model2.ProxyWebsiteResponse
proxyResult, err := service.MyService.OnePanel().GetProxyWebsite(proxy, onePanelServer, 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),
})
}
var updateProxy model2.ProxyDetail
updateProxy = proxyResult.Data[0]
updateProxy.Operate = "edit"
updateProxy.ProxyPass = protocol + "://" + hostname + ":" + port
updateProxyResult, err := service.MyService.OnePanel().UpdateProxyWebsite(updateProxy, onePanelServer, 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),
})
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: updateProxyResult,
})
return
}
c.JSON(common_err.SUCCESS,
model.Result{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
})
}
func OnePanelCreateWebsite(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
domain := json["domain"]
port := json["port"]
protocol := json["protocol"]
hostname := json["hostname"]
var website model2.CreateWebsiteRequest
website.PrimaryDomain = domain
website.Type = "proxy"
website.Alias = domain
website.AppType = "installed"
website.WebSiteGroupID = 2
website.Proxy = protocol + "://" + 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.ProxyAddress = hostname + ":" + port
website.RuntimeType = "php"
headers := make(map[string]string)
for key, value := range c.Request.Header {
headers[key] = value[0]
}
var searchParam model2.SearchWebsiteRequest
searchParam.Name = website.PrimaryDomain
searchParam.Page = 1
searchParam.PageSize = 1
searchParam.OrderBy = "created_at"
searchParam.Order = "null"
searchParam.WebsiteGroupID = 0
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, onePanelServer, 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 {
response, err := service.MyService.OnePanel().CreateWebsite(website, onePanelServer, 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),
})
}
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{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
})
}
func OnePanelDeleteWebsite(c *gin.Context) {
json := make(map[string]string)
c.ShouldBind(&json)
domain := json["domain"]
var searchParam model2.SearchWebsiteRequest
searchParam.Name = domain
searchParam.Page = 1
searchParam.PageSize = 1
searchParam.OrderBy = "created_at"
searchParam.Order = "null"
searchParam.WebsiteGroupID = 0
headers := make(map[string]string)
for key, value := range c.Request.Header {
headers[key] = value[0]
}
search, err := service.MyService.OnePanel().SearchWebsite(searchParam, onePanelServer, 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 {
var delete model2.DeleteWebsiteRequest
delete.ID = search.Data.Items[0].ID
delete.DeleteApp = false
delete.DeleteBackup = false
delete.ForceDelete = false
response, err := service.MyService.OnePanel().DeleteWebsite(delete, onePanelServer, 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),
})
}
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{
Success: common_err.SUCCESS,
Message: common_err.GetMsg(common_err.SUCCESS),
Data: response,
})
}
func PostUserLogin(c *gin.Context) {
@@ -260,10 +496,12 @@ func InitOIDC() {
oidcInit = true
failCount = 0
successCount++
// TODO will enable in production
// Exponential backoff with a cap
sleepTime = minSleep * time.Duration(successCount)
// sleepTime = minSleep * time.Duration(successCount)
if sleepTime > maxSleep {
sleepTime = maxSleep
// TODO will enable in production
// sleepTime = maxSleep
}
} else {
@@ -273,7 +511,8 @@ func InitOIDC() {
// Exponential backoff with a cap
sleepTime = minSleep * time.Duration(failCount)
if failCount > maxRetryBackoff {
sleepTime = minSleep * time.Duration(maxRetryBackoff)
// TODO will enable in production
// sleepTime = minSleep * time.Duration(maxRetryBackoff)
}
log.Printf("OIDC initialization failed: %v. Retrying in %v", err, sleepTime)
}
+275
View File
@@ -14,6 +14,17 @@ 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)
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)
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
}
var (
@@ -23,6 +34,270 @@ var (
type onePanelService struct {
}
// TODO A lot of redundant code need refactor
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)
if err != nil {
return model2.SearchSSLResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.SearchSSLResponse{}, 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.SearchSSLResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.SearchSSLResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.SearchSSLResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.SearchSSLResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) ApplyWebsiteSSl(m model2.CreateSSLRequest, baseUrl string, headers map[string]string) (model2.CreateSSLResponse, error) {
path := baseUrl + "/api/v1/websites/ssl"
reqBody, err := json.Marshal(m)
if err != nil {
return model2.CreateSSLResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.CreateSSLResponse{}, 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.CreateSSLResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.CreateSSLResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.CreateSSLResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.CreateSSLResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) AcmeAccountSearch(m model2.AcmeSearchRequest, baseUrl string, headers map[string]string) (model2.AcmeSearchResponse, error) {
path := baseUrl + "/api/v1/websites/acme/search"
reqBody, err := json.Marshal(m)
if err != nil {
return model2.AcmeSearchResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.AcmeSearchResponse{}, 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.AcmeSearchResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.AcmeSearchResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.AcmeSearchResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.AcmeSearchResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) UpdateProxyWebsite(m model2.ProxyDetail, baseUrl string, headers map[string]string) (model2.GenericResponse, error) {
path := baseUrl + "/api/v1/websites/proxies/update"
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) GetProxyWebsite(m model2.ProxyWebsiteRequest, baseUrl string, headers map[string]string) (model2.ProxyWebsiteResponse, error) {
path := baseUrl + "/api/v1/websites/proxies"
reqBody, err := json.Marshal(m)
if err != nil {
return model2.ProxyWebsiteResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.ProxyWebsiteResponse{}, 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.ProxyWebsiteResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.ProxyWebsiteResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.ProxyWebsiteResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.ProxyWebsiteResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) SearchWebsite(m model2.SearchWebsiteRequest, baseUrl string, headers map[string]string) (model2.SearchWebsiteResponse, error) {
path := baseUrl + "/api/v1/websites/search"
reqBody, err := json.Marshal(m)
if err != nil {
return model2.SearchWebsiteResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
if err != nil {
return model2.SearchWebsiteResponse{}, 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.SearchWebsiteResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.SearchWebsiteResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.SearchWebsiteResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.SearchWebsiteResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) CreateWebsite(m model2.CreateWebsiteRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error) {
path := baseUrl + "/api/v1/websites"
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) DeleteWebsite(m model2.DeleteWebsiteRequest, baseUrl string, headers map[string]string) (model2.GenericResponse, error) {
path := baseUrl + "/api/v1/websites/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) SearchInstalledApp(m model2.InstalledAppRequest, baseUrl string) (model2.InstalledAppResponse, error) {
path := baseUrl + "/api/v1/websites/search"
reqBody, err := json.Marshal(m)
if err != nil {
return model2.InstalledAppResponse{}, fmt.Errorf("error marshaling request body: %v", err)
}
req, err := http.NewRequest("POST", path, bytes.NewReader(reqBody))
// req.AddCookie()
if err != nil {
return model2.InstalledAppResponse{}, fmt.Errorf("error creating request: %v", err)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return model2.InstalledAppResponse{}, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return model2.InstalledAppResponse{}, fmt.Errorf("HTTP error: %s", resp.Status)
}
var result model2.InstalledAppResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return model2.InstalledAppResponse{}, fmt.Errorf("error decoding response: %v", err)
}
return result, nil
}
func (o *onePanelService) Login(m model2.OnePanelCredentials, baseURL string) (model2.LoginResponse, []*http.Cookie, error) {
path := baseURL + prefixV1 + "/auth/login"
+47
View File
@@ -0,0 +1,47 @@
package model
import "time"
type InstalledAppRequest struct {
Page int `json:"page"`
PageSize int `json:"pageSize"`
Name string `json:"name"`
Tags []interface{} `json:"tags"`
Update bool `json:"update"`
Sync bool `json:"sync"`
}
type InstalledAppResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Total int `json:"total"`
Items []struct {
ID int `json:"id"`
Name string `json:"name"`
AppID int `json:"appID"`
AppDetailID int `json:"appDetailID"`
Version string `json:"version"`
Status string `json:"status"`
Message string `json:"message"`
HTTPPort int `json:"httpPort"`
HTTPSPort int `json:"httpsPort"`
Path string `json:"path"`
CanUpdate bool `json:"canUpdate"`
Icon string `json:"icon"`
AppName string `json:"appName"`
Ready int `json:"ready"`
Total int `json:"total"`
AppKey string `json:"appKey"`
AppType string `json:"appType"`
AppStatus string `json:"appStatus"`
DockerCompose string `json:"dockerCompose"`
CreatedAt time.Time `json:"createdAt"`
App struct {
Website string `json:"website"`
Document string `json:"document"`
Github string `json:"github"`
} `json:"app"`
} `json:"items"`
} `json:"data"`
}
+127
View File
@@ -0,0 +1,127 @@
package model
import "time"
type CreateSSLRequest struct {
ID int `json:"id"`
PrimaryDomain string `json:"primaryDomain"`
OtherDomains string `json:"otherDomains"`
Provider string `json:"provider"`
WebsiteID int `json:"websiteId"`
AcmeAccountID int `json:"acmeAccountId"`
AutoRenew bool `json:"autoRenew"`
KeyType string `json:"keyType"`
PushDir bool `json:"pushDir"`
Dir string `json:"dir"`
Description string `json:"description"`
DisableCNAME bool `json:"disableCNAME"`
SkipDNS bool `json:"skipDNS"`
Nameserver1 string `json:"nameserver1"`
Nameserver2 string `json:"nameserver2"`
ExecShell bool `json:"execShell"`
Shell string `json:"shell"`
}
type CreateSSLResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
PrimaryDomain string `json:"primaryDomain"`
OtherDomains string `json:"otherDomains"`
Provider string `json:"provider"`
AcmeAccountID int `json:"acmeAccountId"`
DNSAccountID int `json:"dnsAccountId"`
AutoRenew bool `json:"autoRenew"`
KeyType string `json:"keyType"`
Apply bool `json:"apply"`
PushDir bool `json:"pushDir"`
Dir string `json:"dir"`
ID int `json:"id"`
Description string `json:"description"`
DisableCNAME bool `json:"disableCNAME"`
SkipDNS bool `json:"skipDNS"`
Nameserver1 string `json:"nameserver1"`
Nameserver2 string `json:"nameserver2"`
ExecShell bool `json:"execShell"`
Shell string `json:"shell"`
} `json:"data"`
}
type AcmeSearchRequest struct {
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
type SearchSSLRequest struct {
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"`
} `json:"data"`
}
type AcmeSearchResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Total int `json:"total"`
Items []AcmeAccount `json:"items"`
} `json:"data"`
}
type 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"`
}
type DNSAccount struct {
ID int `json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Name string `json:"name"`
Type string `json:"type"`
}
+195
View File
@@ -0,0 +1,195 @@
package model
import "time"
type SearchWebsiteRequest struct {
Name string `json:"name"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
OrderBy string `json:"orderBy"`
Order string `json:"order"`
WebsiteGroupID int `json:"websiteGroupId"`
}
type SearchWebsiteResponse 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"`
Protocol string `json:"protocol"`
PrimaryDomain string `json:"primaryDomain"`
Type string `json:"type"`
Alias string `json:"alias"`
Remark string `json:"remark"`
Status string `json:"status"`
ExpireDate time.Time `json:"expireDate"`
SitePath string `json:"sitePath"`
AppName string `json:"appName"`
RuntimeName string `json:"runtimeName"`
SslExpireDate time.Time `json:"sslExpireDate"`
SslStatus string `json:"sslStatus"`
AppInstallID int `json:"appInstallId"`
RuntimeType string `json:"runtimeType"`
} `json:"items"`
} `json:"data"`
}
type CreateWebsiteRequest struct {
PrimaryDomain string `json:"primaryDomain"`
Type string `json:"type,omitempty"`
Alias string `json:"alias,omitempty"`
Remark string `json:"remark,omitempty"`
AppType string `json:"appType,omitempty"`
WebSiteGroupID int64 `json:"webSiteGroupId,omitempty"`
OtherDomains string `json:"otherDomains,omitempty"`
Proxy string `json:"proxy,omitempty"`
Appinstall struct {
AppID int64 `json:"appId,omitempty"`
Name string `json:"name,omitempty"`
AppDetailID int64 `json:"appDetailId,omitempty"`
Params struct{} `json:"params,omitempty"`
Version string `json:"version,omitempty"`
Appkey string `json:"appkey,omitempty"`
Advanced bool `json:"advanced,omitempty"`
CPUQuota int64 `json:"cpuQuota,omitempty"`
MemoryLimit int64 `json:"memoryLimit,omitempty"`
MemoryUnit string `json:"memoryUnit,omitempty"`
ContainerName string `json:"containerName,omitempty"`
AllowPort bool `json:"allowPort,omitempty"`
} `json:"appinstall,omitempty"`
IPV6 bool `json:"IPV6,omitempty"`
EnableFtp bool `json:"enableFtp,omitempty"`
FtpUser string `json:"ftpUser,omitempty"`
FtpPassword string `json:"ftpPassword,omitempty"`
ProxyType string `json:"proxyType,omitempty"`
Port int64 `json:"port,omitempty"`
ProxyProtocol string `json:"proxyProtocol,omitempty"`
ProxyAddress string `json:"proxyAddress,omitempty"`
RuntimeType string `json:"runtimeType,omitempty"`
}
type DeleteWebsiteRequest struct {
ID int `json:"id"`
DeleteApp bool `json:"deleteApp"`
DeleteBackup bool `json:"deleteBackup"`
ForceDelete bool `json:"forceDelete"`
}
type GenericResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
} `json:"data"`
}
type ProxyWebsiteRequest struct {
ID int `json:"id"`
}
type ProxyWebsiteResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data []ProxyDetail `json:"data"`
}
type ProxyDetail struct {
ID int `json:"id"`
Operate string `json:"operate"`
Enable bool `json:"enable"`
Cache bool `json:"cache"`
CacheTime int `json:"cacheTime"`
CacheUnit string `json:"cacheUnit"`
Name string `json:"name"`
Modifier string `json:"modifier"`
Match string `json:"match"`
ProxyPass string `json:"proxyPass"`
ProxyHost string `json:"proxyHost"`
Content string `json:"content"`
FilePath string `json:"filePath"`
Replaces struct {
} `json:"replaces"`
Sni bool `json:"sni"`
ProxyProtocol string `json:"proxyProtocol"`
ProxyAddress string `json:"proxyAddress"`
}
type WebsiteHttpsRequest 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 WebsiteHttpsResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Enable bool `json:"enable"`
HTTPConfig string `json:"httpConfig"`
SSL 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"`
} `json:"SSL"`
SSLProtocol []string `json:"SSLProtocol"`
Algorithm string `json:"algorithm"`
Hsts bool `json:"hsts"`
} `json:"data"`
}
-1
View File
@@ -35,7 +35,6 @@ type UserService interface {
DeleteAllUser()
GetUserInfoByUserName(userName string) (m model.UserDBModel)
GetAllUserName() (list []model.UserDBModel)
GetKeyPair() (*ecdsa.PrivateKey, *ecdsa.PublicKey)
}