package group
import (
"Yearning-go/src/handler/common"
"Yearning-go/src/lib"
"Yearning-go/src/model"
"encoding/json"
"fmt"
"github.com/cookieY/yee"
"github.com/google/uuid"
"net/http"
"net/url"
"strings"
)
func SuperGetRuseSource(c yee.Context) (err error) {
var source []model.CoreDataSource
var query []model.CoreDataSource
model.DB().Select("source,source_id").Scopes(common.AccordingToGroupSourceIsQuery(0, 2)).Find(&source)
model.DB().Select("source,source_id").Scopes(common.AccordingToGroupSourceIsQuery(1, 2)).Find(&query)
return c.JSON(http.StatusOK, common.SuccessPayload(map[string]interface{}{"source": source, "query": query}))
}
func SuperGroup(c yee.Context) (err error) {
u := new(common.PageList[[]model.CoreRoleGroup])
if err = c.Bind(u); err != nil {
return err
}
return c.JSON(http.StatusOK, u.Paging().Query(common.AccordingToOrderName(u.Expr.Text)).ToMessage())
}
type wsMsg struct {
Type string `json:"type"`
Cmd string `json:"cmd"`
Cols int `json:"cols"`
Rows int `json:"rows"`
}
type LogicSshWsSession struct {
stdinPipe io.WriteCloser
comboOutput *safeBuffer //ssh 终端混合输出
inputFilterBuff *safeBuffer //用来过滤输入的命令和ssh_filter配置对比的
session *ssh.Session
wsConn *websocket.Conn
isAdmin bool
IsFlagged bool `comment:"当前session是否包含禁止命令"`
sshFilters JsonArraySshFilter
Tlog JsonArrayString
HasEditor bool
}
func NewLogicSshWsSession(cols, rows int, isAdmin bool, sshClient *ssh.Client, wsConn *websocket.Conn, sfg *SshFilterGroup) (*LogicSshWsSession, error) {
sshSession, err := sshClient.NewSession()
if err != nil {
return nil, err
}
stdinP, err := sshSession.StdinPipe()
if err != nil {
return nil, err
}
comboWriter := new(safeBuffer)
inputBuf := new(safeBuffer)
//ssh.stdout and stderr will write output into comboWriter
sshSession.Stdout = comboWriter
sshSession.Stderr = comboWriter
modes := ssh.TerminalModes{
ssh.ECHO: 1, // disable echo
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
}
// Request pseudo terminal
if err := sshSession.RequestPty("xterm", rows, cols, modes); err != nil {
return nil, err
}
// Start remote shell
if err := sshSession.Shell(); err != nil {
return nil, err
}
sfs := JsonArraySshFilter{}
if sfg != nil {
sfs = sfg.Filters
}
return &LogicSshWsSession{
stdinPipe: stdinP,
comboOutput: comboWriter,
inputFilterBuff: inputBuf,
session: sshSession,
wsConn: wsConn,
isAdmin: isAdmin,
IsFlagged: false,
sshFilters: sfs,
Tlog: JsonArrayString{},
}, nil
}
func SuperGroupUpdate(c yee.Context) (err error) {
user := new(lib.Token).JwtParse(c)
if user.Username == "admin" {
u := new(policy)
if err = c.Bind(u); err != nil {
c.Logger().Error(err.Error())
return c.JSON(http.StatusOK, common.ERR_REQ_BIND)
}
g, err := json.Marshal(u.PermissionList)
if err != nil {
c.Logger().Error(err.Error())
return c.JSON(http.StatusOK, common.ERR_COMMON_MESSAGE(err))
}
if u.ID == 0 {
model.DB().Create(&model.CoreRoleGroup{
Name: u.Name,
Permissions: g,
GroupId: uuid.New().String(),
})
} else {
model.DB().Model(model.CoreRoleGroup{}).Scopes(common.AccordingToIDEqual(u.ID)).Updates(&model.CoreRoleGroup{Permissions: g, Name: u.Name})
}
return c.JSON(http.StatusOK, common.SuccessPayLoadToMessage(fmt.Sprintf(GROUP_CREATE_SUCCESS, u.Name)))
}
return c.JSON(http.StatusOK, common.ERR_REQ_FAKE)
}
func SuperClearUserRule(c yee.Context) (err error) {
args := c.QueryParam("group_id")
scape, _ := url.QueryUnescape(args)
var j []model.CoreGrained
model.DB().Scopes(common.AccordingToGroupNameIsLike(scape)).Find(&j)
for _, i := range j {
b, err := lib.ArrayRemove(i.Group, scape)
if err != nil {
return c.JSON(http.StatusOK, common.ERR_COMMON_MESSAGE(err))
}
go model.DB().Model(model.CoreGrained{}).Scopes(common.AccordingToUsernameEqual(i.Username)).Updates(&model.CoreGrained{Group: b})
}
model.DB().Model(model.CoreRoleGroup{}).Where("group_id = ?", scape).Delete(&model.CoreRoleGroup{})
return c.JSON(http.StatusOK, common.SuccessPayLoadToMessage(fmt.Sprintf(GROUP_DELETE_SUCCESS, scape)))
}
func SuperUserRuleMarge(c yee.Context) (err error) {
u := new(marge)
if err = c.Bind(u); err != nil {
return c.JSON(http.StatusOK, common.ERR_REQ_BIND)
}
m3 := lib.NewMultiUserRuleSet(strings.Split(u.Group, ","))
return c.JSON(http.StatusOK, common.SuccessPayload(m3))
}
原子性文件写入
package file
import (
"os"
"path/filepath"
)
type atomicFileWriter struct {
f *os.File
path string
perm os.FileMode
}
func (a *atomicFileWriter) close() (err error) {
if err = a.f.Sync(); err != nil {
err := a.f.Close()
if err != nil {
return err
}
return err
}
if err := a.f.Close(); err != nil {
return err
}
if err := os.Chmod(a.f.Name(), a.perm); err != nil {
return err
}
return os.Rename(a.f.Name(), a.path)
}
func newAtomicFileWriter(path string, perm os.FileMode) (*atomicFileWriter, error) {
tmpFile, err := MkTmpFile(filepath.Dir(path))
if err != nil {
return nil, err
}
return &atomicFileWriter{f: tmpFile, path: path, perm: perm}, nil
}
func AtomicWriteFile(filepath string, data []byte, perm os.FileMode) (err error) {
afw, err := newAtomicFileWriter(filepath, perm)
if err != nil {
return err
}
defer func() {
if err != nil {
CleanFile(afw.f)
}
}()
if _, err = afw.f.Write(data); err != nil {
return
}
err = afw.close()
return
}