mirror of
https://github.com/veops/oneterm.git
synced 2025-10-03 22:46:24 +08:00
141 lines
4.5 KiB
Go
141 lines
4.5 KiB
Go
package controller
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"golang.org/x/crypto/ssh"
|
|
|
|
"github.com/veops/oneterm/pkg/server/auth/acl"
|
|
"github.com/veops/oneterm/pkg/server/model"
|
|
"github.com/veops/oneterm/pkg/server/storage/db/mysql"
|
|
"github.com/veops/oneterm/pkg/util"
|
|
)
|
|
|
|
var (
|
|
publicKeyPreHooks = []preHook[*model.PublicKey]{
|
|
func(ctx *gin.Context, data *model.PublicKey) {
|
|
if _, comment, _, _, err := ssh.ParseAuthorizedKey([]byte(data.Pk)); err != nil {
|
|
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrWrongPk, Data: nil})
|
|
} else {
|
|
data.Pk = strings.TrimSpace(strings.TrimSuffix(data.Pk, comment))
|
|
}
|
|
if _, err := net.ParseMAC(data.Mac); err != nil {
|
|
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrWrongMac, Data: nil})
|
|
}
|
|
},
|
|
func(ctx *gin.Context, data *model.PublicKey) {
|
|
data.Pk = util.EncryptAES(data.Pk)
|
|
},
|
|
func(ctx *gin.Context, data *model.PublicKey) {
|
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
|
data.Uid = currentUser.GetUid()
|
|
data.UserName = currentUser.GetUserName()
|
|
},
|
|
}
|
|
publicKeyPostHooks = []postHook[*model.PublicKey]{
|
|
func(ctx *gin.Context, data []*model.PublicKey) {
|
|
for _, d := range data {
|
|
d.Pk = util.DecryptAES(d.Pk)
|
|
}
|
|
},
|
|
}
|
|
)
|
|
|
|
// CreatePublicKey godoc
|
|
//
|
|
// @Tags public_key
|
|
// @Param publicKey body model.PublicKey true "publicKey"
|
|
// @Success 200 {object} HttpResponse
|
|
// @Router /public_key [post]
|
|
func (c *Controller) CreatePublicKey(ctx *gin.Context) {
|
|
doCreate(ctx, false, &model.PublicKey{}, "", publicKeyPreHooks...)
|
|
}
|
|
|
|
// DeletePublicKey godoc
|
|
//
|
|
// @Tags public_key
|
|
// @Param id path int true "publicKey id"
|
|
// @Success 200 {object} HttpResponse
|
|
// @Router /public_key/:id [delete]
|
|
func (c *Controller) DeletePublicKey(ctx *gin.Context) {
|
|
doDelete(ctx, false, &model.PublicKey{})
|
|
}
|
|
|
|
// UpdatePublicKey godoc
|
|
//
|
|
// @Tags public_key
|
|
// @Param id path int true "publicKey id"
|
|
// @Param publicKey body model.PublicKey true "publicKey"
|
|
// @Success 200 {object} HttpResponse
|
|
// @Router /public_key/:id [put]
|
|
func (c *Controller) UpdatePublicKey(ctx *gin.Context) {
|
|
doUpdate(ctx, false, &model.PublicKey{}, publicKeyPreHooks...)
|
|
}
|
|
|
|
// GetPublicKeys godoc
|
|
//
|
|
// @Tags public_key
|
|
// @Param page_index query int true "publicKey id"
|
|
// @Param page_size query int true "publicKey id"
|
|
// @Param search query string false "name or mac"
|
|
// @Param id query int false "publicKey id"
|
|
// @Param name query string false "publicKey name"
|
|
// @Success 200 {object} HttpResponse{data=ListData{list=[]model.PublicKey}}
|
|
// @Router /public_key [get]
|
|
func (c *Controller) GetPublicKeys(ctx *gin.Context) {
|
|
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
|
|
|
db := mysql.DB.Model(&model.PublicKey{})
|
|
db = filterSearch(ctx, db, "name", "mac")
|
|
db = filterEqual(ctx, db, "id")
|
|
db = filterLike(ctx, db, "name")
|
|
|
|
db = db.Where("uid = ?", currentUser.Uid)
|
|
|
|
doGet[*model.PublicKey](ctx, false, db, "", publicKeyPostHooks...)
|
|
}
|
|
|
|
// Auth godoc
|
|
//
|
|
// @Tags public_key
|
|
// @Param req body model.ReqAuth false "method 1password 2publickey"
|
|
// @Success 200 {object} HttpResponse{}
|
|
// @Router /public_key/auth [post]
|
|
func (c *Controller) Auth(ctx *gin.Context) {
|
|
data := &model.ReqAuth{}
|
|
if err := ctx.BindJSON(data); err != nil {
|
|
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
|
return
|
|
}
|
|
|
|
switch data.Method {
|
|
case model.AUTHMETHOD_PASSWORD:
|
|
cookie, err := acl.LoginByPassword(ctx, data.UserName, data.Password)
|
|
if err != nil {
|
|
ctx.AbortWithError(http.StatusUnauthorized, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
|
return
|
|
}
|
|
ctx.JSON(http.StatusOK, NewHttpResponseWithData(map[string]any{"cookie": cookie}))
|
|
case model.AUTHMETHOD_PUBLICKEY:
|
|
pk := &model.PublicKey{}
|
|
if err := mysql.DB.
|
|
Where("username = ? AND pk = ?", data.UserName, util.EncryptAES(data.Pk)).
|
|
First(pk).Error; err != nil {
|
|
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
|
return
|
|
}
|
|
cookie, err := acl.LoginByPublicKey(ctx, data.UserName)
|
|
if err != nil {
|
|
ctx.AbortWithError(http.StatusUnauthorized, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
|
return
|
|
}
|
|
ctx.JSON(http.StatusOK, NewHttpResponseWithData(map[string]any{"cookie": cookie}))
|
|
default:
|
|
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": "invalid auth method"}})
|
|
return
|
|
}
|
|
}
|