add setting support
Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
parent
16e23b50de
commit
b0781a2c0e
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/github"
|
||||
|
|
@ -21,11 +22,10 @@ func NewGithubOauth2(name string, clientID string, clientSecret string, db *gorm
|
|||
oa.Config = &oauth2.Config{
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"https://www.googleapis.com/auth/userinfo.email"},
|
||||
Scopes: strings.Split(GithubScopes, ","),
|
||||
Endpoint: github.Endpoint,
|
||||
}
|
||||
oa.UserInfoURL = "https://api.github.com/user"
|
||||
oa.UserInfoURL = GithubUserInfoURL
|
||||
|
||||
redirectURL, err := oa.GetRediectURL(db)
|
||||
if err != nil {
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package oauth
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/google"
|
||||
"gorm.io/gorm"
|
||||
|
|
@ -17,11 +19,10 @@ func NewGoogleOauth2(name string, clientID string, clientSecret string, db *gorm
|
|||
oa.Config = &oauth2.Config{
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Scopes: []string{"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"https://www.googleapis.com/auth/userinfo.email"},
|
||||
Scopes: strings.Split(GoogleScopes, ","),
|
||||
Endpoint: google.Endpoint,
|
||||
}
|
||||
oa.UserInfoURL = "https://www.googleapis.com/oauth2/v2/userinfo"
|
||||
oa.UserInfoURL = GithubUserInfoURL
|
||||
|
||||
redirectURL, err := oa.GetRediectURL(db)
|
||||
if err != nil {
|
||||
|
|
@ -16,6 +16,14 @@ import (
|
|||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const (
|
||||
GoogleScopes = "https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/userinfo.profile"
|
||||
GoogleUserInfoURL = "https://www.googleapis.com/oauth2/v2/userinfo"
|
||||
|
||||
GithubScopes = "user,public_repo"
|
||||
GithubUserInfoURL = "https://api.github.com/user"
|
||||
)
|
||||
|
||||
type baseOauth2 struct {
|
||||
Name string
|
||||
UserInfoURL string
|
||||
|
|
@ -193,33 +193,17 @@ func (h *Handlers) GetOauth(ctx *gin.Context) {
|
|||
// @Tags Oauth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param page query int true "current page" default(0)
|
||||
// @Param per_page query int true "return max item count, default 10, max 50" default(10) minimum(2) maximum(50)
|
||||
// @Success 200 {object} []model.Oauth
|
||||
// @Failure 400 {object} HTTPError
|
||||
// @Failure 404 {object} HTTPError
|
||||
// @Failure 500 {object} HTTPError
|
||||
// @Router /oauths [get]
|
||||
func (h *Handlers) GetOauths(ctx *gin.Context) {
|
||||
var query types.GetOauthsQuery
|
||||
if err := ctx.ShouldBindQuery(&query); err != nil {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.setPaginationDefault(&query.Page, &query.PerPage)
|
||||
oauths, err := h.Service.GetOauths(query)
|
||||
oauths, err := h.Service.GetOauths()
|
||||
if err != nil {
|
||||
ctx.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
totalCount, err := h.Service.OauthTotalCount(query)
|
||||
if err != nil {
|
||||
ctx.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
h.setPaginationLinkHeader(ctx, query.Page, query.PerPage, int(totalCount))
|
||||
ctx.JSON(http.StatusOK, oauths)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,132 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"d7y.io/dragonfly/v2/manager/types"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Summary Create Setting
|
||||
// @Description create by json config
|
||||
// @Tags Setting
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param Setting body types.CreateSettingRequest true "Setting"
|
||||
// @Success 200 {object} model.Setting
|
||||
// @Failure 400 {object} HTTPError
|
||||
// @Failure 404 {object} HTTPError
|
||||
// @Failure 500 {object} HTTPError
|
||||
// @Router /settings [post]
|
||||
func (h *Handlers) CreateSetting(ctx *gin.Context) {
|
||||
var json types.CreateSettingRequest
|
||||
if err := ctx.ShouldBindJSON(&json); err != nil {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
setting, err := h.Service.CreateSetting(json)
|
||||
if err != nil {
|
||||
ctx.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, setting)
|
||||
}
|
||||
|
||||
// @Summary Destroy Setting
|
||||
// @Description Destroy by key
|
||||
// @Tags Setting
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "key"
|
||||
// @Success 200
|
||||
// @Failure 400 {object} HTTPError
|
||||
// @Failure 404 {object} HTTPError
|
||||
// @Failure 500 {object} HTTPError
|
||||
// @Router /settings/{id} [delete]
|
||||
func (h *Handlers) DestroySetting(ctx *gin.Context) {
|
||||
var params types.SettingParams
|
||||
if err := ctx.ShouldBindUri(¶ms); err != nil {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
err := h.Service.DestroySetting(params.Key)
|
||||
if err != nil {
|
||||
ctx.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
// @Summary Update Setting
|
||||
// @Description Update by json config
|
||||
// @Tags Setting
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param key path string true "key"
|
||||
// @Param Setting body types.UpdateSettingRequest true "Setting"
|
||||
// @Success 200 {object} model.Setting
|
||||
// @Failure 400 {object} HTTPError
|
||||
// @Failure 404 {object} HTTPError
|
||||
// @Failure 500 {object} HTTPError
|
||||
// @Router /settings/{id} [patch]
|
||||
func (h *Handlers) UpdateSetting(ctx *gin.Context) {
|
||||
|
||||
var params types.SettingParams
|
||||
if err := ctx.ShouldBindUri(¶ms); err != nil {
|
||||
ctx.Error(err)
|
||||
return
|
||||
}
|
||||
var json types.UpdateSettingRequest
|
||||
if err := ctx.ShouldBindJSON(&json); err != nil {
|
||||
ctx.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
setting, err := h.Service.UpdateSetting(params.Key, json)
|
||||
if err != nil {
|
||||
ctx.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, setting)
|
||||
}
|
||||
|
||||
// @Summary Get Settings
|
||||
// @Description Get Settings
|
||||
// @Tags Setting
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param page query int true "current page" default(0)
|
||||
// @Param per_page query int true "return max item count, default 10, max 50" default(10) minimum(2) maximum(50)
|
||||
// @Success 200 {object} []model.Setting
|
||||
// @Failure 400 {object} HTTPError
|
||||
// @Failure 404 {object} HTTPError
|
||||
// @Failure 500 {object} HTTPError
|
||||
// @Router /settings [get]
|
||||
func (h *Handlers) GetSettings(ctx *gin.Context) {
|
||||
var query types.GetSettingsQuery
|
||||
if err := ctx.ShouldBindQuery(&query); err != nil {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.setPaginationDefault(&query.Page, &query.PerPage)
|
||||
settings, err := h.Service.GetSettings(query)
|
||||
if err != nil {
|
||||
ctx.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
totalCount, err := h.Service.SettingTotalCount()
|
||||
if err != nil {
|
||||
ctx.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
h.setPaginationLinkHeader(ctx, query.Page, query.PerPage, int(totalCount))
|
||||
ctx.JSON(http.StatusOK, settings)
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package model
|
||||
|
||||
type Settings struct {
|
||||
Model
|
||||
Key string `gorm:"column:key;type:varchar(256);index:unique;not null;comment: setting key" json:"key"`
|
||||
ID uint `gorm:"primarykey;comment:id" json:"id"`
|
||||
Key string `gorm:"column:key;type:varchar(256);index:uk_settings_key,unique;not null;comment:setting key" json:"key"`
|
||||
Value string `gorm:"column:value;type:varchar(256);not null;comment:setting value" json:"value"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,13 @@ func Init(console bool, verbose bool, publicPath string, service service.REST, e
|
|||
s.GET(":id", h.GetScheduler)
|
||||
s.GET("", h.GetSchedulers)
|
||||
|
||||
// Settings
|
||||
st := apiv1.Group("/settings")
|
||||
st.POST("", h.CreateSetting)
|
||||
st.DELETE(":id", h.DestroySetting)
|
||||
st.PATCH("", h.UpdateSetting)
|
||||
st.GET("", h.GetSettings)
|
||||
|
||||
// CDN Cluster
|
||||
cc := apiv1.Group("/cdn-clusters")
|
||||
cc.POST("", h.CreateCDNCluster)
|
||||
|
|
|
|||
|
|
@ -1,25 +1,47 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"d7y.io/dragonfly/v2/manager/auth/oauth"
|
||||
"d7y.io/dragonfly/v2/manager/model"
|
||||
"d7y.io/dragonfly/v2/manager/oauth"
|
||||
"d7y.io/dragonfly/v2/manager/types"
|
||||
"golang.org/x/oauth2/github"
|
||||
"golang.org/x/oauth2/google"
|
||||
)
|
||||
|
||||
func (s *rest) CreateOauth(json types.CreateOauthRequest) (*model.Oauth, error) {
|
||||
oauth := model.Oauth{
|
||||
o := model.Oauth{}
|
||||
o.ClientID = json.ClientID
|
||||
o.ClientSecret = json.ClientSecret
|
||||
o.Name = json.Name
|
||||
switch json.Name {
|
||||
case "google":
|
||||
o.AuthURL = google.Endpoint.AuthURL
|
||||
o.TokenURL = google.Endpoint.TokenURL
|
||||
o.Scopes = oauth.GoogleScopes
|
||||
o.UserInfoURL = oauth.GoogleUserInfoURL
|
||||
|
||||
case "github":
|
||||
o.AuthURL = github.Endpoint.AuthURL
|
||||
o.TokenURL = github.Endpoint.TokenURL
|
||||
o.Scopes = oauth.GithubScopes
|
||||
o.UserInfoURL = oauth.GithubUserInfoURL
|
||||
default:
|
||||
o = model.Oauth{
|
||||
ClientID: json.ClientID,
|
||||
ClientSecret: json.ClientSecret,
|
||||
Name: json.Name,
|
||||
Scopes: json.Scopes,
|
||||
AuthURL: json.AuthURL,
|
||||
TokenURL: json.TokenURL,
|
||||
UserInfoURL: json.UserInfoURL,
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.db.Create(&oauth).Error; err != nil {
|
||||
if err := s.db.Create(&o).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &oauth, nil
|
||||
return &o, nil
|
||||
}
|
||||
|
||||
func (s *rest) DestroyOauth(id uint) error {
|
||||
|
|
@ -53,52 +75,40 @@ func (s *rest) GetOauth(id uint) (*model.Oauth, error) {
|
|||
return &oauth, nil
|
||||
}
|
||||
|
||||
func (s *rest) GetOauths(q types.GetOauthsQuery) (*[]model.Oauth, error) {
|
||||
func (s *rest) GetOauths() (*[]model.Oauth, error) {
|
||||
oauths := []model.Oauth{}
|
||||
if q.Name != "" {
|
||||
if err := s.db.Scopes(model.Paginate(q.Page, q.PerPage)).Where(&model.Oauth{
|
||||
Name: q.Name,
|
||||
}).Find(&oauths).Error; err != nil {
|
||||
if err := s.db.Find(&oauths).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
if err := s.db.Scopes(model.Paginate(q.Page, q.PerPage)).Find(&oauths).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &oauths, nil
|
||||
}
|
||||
|
||||
func (s *rest) OauthTotalCount(q types.GetOauthsQuery) (int64, error) {
|
||||
var count int64
|
||||
if q.Name != "" {
|
||||
if err := s.db.Model(&model.Oauth{}).Where(&model.Oauth{
|
||||
Name: q.Name,
|
||||
}).Count(&count).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
} else {
|
||||
if err := s.db.Model(&model.Oauth{}).Where(&model.Oauth{}).Count(&count).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (s *rest) OauthSignin(name string) (string, error) {
|
||||
oauthModel := model.Oauth{}
|
||||
if err := s.db.First(&oauthModel, name).Error; err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
o, err := oauth.NewBaseOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, oauthModel.Scopes, oauthModel.AuthURL, oauthModel.TokenURL, s.db)
|
||||
var o oauth.Oauther
|
||||
var err error
|
||||
switch name {
|
||||
case "google":
|
||||
o, err = oauth.NewGoogleOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, s.db)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
case "github":
|
||||
o, err = oauth.NewGithubOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, s.db)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
default:
|
||||
o, err = oauth.NewBaseOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, oauthModel.Scopes, oauthModel.AuthURL, oauthModel.TokenURL, s.db)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return o.AuthCodeURL(), nil
|
||||
}
|
||||
|
||||
|
|
@ -107,11 +117,26 @@ func (s *rest) OauthCallback(name, code string) (*model.User, error) {
|
|||
if err := s.db.First(&oauthModel, name).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o, err := oauth.NewBaseOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, oauthModel.Scopes, oauthModel.AuthURL, oauthModel.TokenURL, s.db)
|
||||
var o oauth.Oauther
|
||||
var err error
|
||||
switch name {
|
||||
case "google":
|
||||
o, err = oauth.NewGoogleOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, s.db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "github":
|
||||
o, err = oauth.NewGithubOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, s.db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
o, err = oauth.NewBaseOauth2(name, oauthModel.ClientID, oauthModel.ClientSecret, oauthModel.Scopes, oauthModel.AuthURL, oauthModel.TokenURL, s.db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
user, err := o.ExchangeUserByCode(code, s.db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -81,6 +81,12 @@ type REST interface {
|
|||
GetSchedulers(types.GetSchedulersQuery) (*[]model.Scheduler, error)
|
||||
SchedulerTotalCount(types.GetSchedulersQuery) (int64, error)
|
||||
|
||||
CreateSetting(types.CreateSettingRequest) (*model.Settings, error)
|
||||
DestroySetting(string) error
|
||||
UpdateSetting(string, types.UpdateSettingRequest) (*model.Settings, error)
|
||||
GetSettings(types.GetSettingsQuery) (*[]model.Settings, error)
|
||||
SettingTotalCount() (int64, error)
|
||||
|
||||
CreateSecurityGroup(types.CreateSecurityGroupRequest) (*model.SecurityGroup, error)
|
||||
DestroySecurityGroup(uint) error
|
||||
UpdateSecurityGroup(uint, types.UpdateSecurityGroupRequest) (*model.SecurityGroup, error)
|
||||
|
|
@ -97,8 +103,7 @@ type REST interface {
|
|||
DestroyOauth(uint) error
|
||||
UpdateOauth(uint, types.UpdateOauthRequest) (*model.Oauth, error)
|
||||
GetOauth(uint) (*model.Oauth, error)
|
||||
GetOauths(types.GetOauthsQuery) (*[]model.Oauth, error)
|
||||
OauthTotalCount(types.GetOauthsQuery) (int64, error)
|
||||
GetOauths() (*[]model.Oauth, error)
|
||||
OauthSignin(name string) (string, error)
|
||||
OauthCallback(name, code string) (*model.User, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"d7y.io/dragonfly/v2/manager/model"
|
||||
"d7y.io/dragonfly/v2/manager/types"
|
||||
)
|
||||
|
||||
func (s *rest) CreateSetting(json types.CreateSettingRequest) (*model.Settings, error) {
|
||||
setting := model.Settings{
|
||||
Key: json.Key,
|
||||
Value: json.Value,
|
||||
}
|
||||
|
||||
if err := s.db.Create(&setting).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &setting, nil
|
||||
}
|
||||
|
||||
func (s *rest) DestroySetting(key string) error {
|
||||
if err := s.db.Unscoped().Delete(&model.Settings{}, model.Settings{Key: key}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *rest) UpdateSetting(key string, json types.UpdateSettingRequest) (*model.Settings, error) {
|
||||
setting := model.Settings{}
|
||||
if err := s.db.First(&setting, model.Settings{Key: key}).Updates(model.Settings{
|
||||
Key: json.Key,
|
||||
Value: json.Value,
|
||||
}).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &setting, nil
|
||||
}
|
||||
|
||||
func (s *rest) GetSettings(q types.GetSettingsQuery) (*[]model.Settings, error) {
|
||||
settings := []model.Settings{}
|
||||
if err := s.db.Scopes(model.Paginate(q.Page, q.PerPage)).Find(&settings).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &settings, nil
|
||||
}
|
||||
|
||||
func (s *rest) SettingTotalCount() (int64, error) {
|
||||
var count int64
|
||||
if err := s.db.Model(&model.Settings{}).Count(&count).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ type OauthBaseRquest struct {
|
|||
Scopes string `json:"scopes" binding:"omitempty"`
|
||||
AuthURL string `json:"auth_url" binding:"omitempty"`
|
||||
TokenURL string `json:"token_url" binding:"omitempty"`
|
||||
UserInfoURL string `json:"user_info_url" binding:"omitempty"`
|
||||
}
|
||||
|
||||
type CreateOauthRequest struct {
|
||||
|
|
@ -25,9 +26,3 @@ type CreateOauthRequest struct {
|
|||
type UpdateOauthRequest struct {
|
||||
OauthBaseRquest
|
||||
}
|
||||
|
||||
type GetOauthsQuery struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
Page int `form:"page" binding:"omitempty,gte=1"`
|
||||
PerPage int `form:"per_page" binding:"omitempty,gte=1,lte=50"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
package types
|
||||
|
||||
type SettingParams struct {
|
||||
Key string `uri:"key" binding:"required"`
|
||||
}
|
||||
type CreateSettingRequest struct {
|
||||
Key string `json:"key" binding:"required"`
|
||||
Value string `json:"value" binding:"required"`
|
||||
}
|
||||
|
||||
type UpdateSettingRequest struct {
|
||||
Key string `json:"key" binding:"required"`
|
||||
Value string `json:"value" binding:"required"`
|
||||
}
|
||||
|
||||
type GetSettingsQuery struct {
|
||||
Page int `form:"page" binding:"omitempty,gte=1"`
|
||||
PerPage int `form:"per_page" binding:"omitempty,gte=1,lte=50"`
|
||||
}
|
||||
Loading…
Reference in New Issue