├── LICENSE ├── README.md ├── build ├── build.sh ├── build_windows.go ├── git_push.bat ├── go.mod └── go.sum ├── console ├── .gitignore ├── README.md ├── biz │ ├── client │ │ ├── model │ │ │ └── db.go │ │ ├── service │ │ │ ├── login.go │ │ │ ├── ras_hash.go │ │ │ ├── ras_tool.go │ │ │ ├── req.go │ │ │ └── rsa.go │ │ └── view │ │ │ ├── errors.go │ │ │ ├── login.go │ │ │ └── router.go │ ├── dash │ │ ├── service │ │ │ ├── chart.go │ │ │ ├── dash.go │ │ │ ├── model.go │ │ │ └── top5.go │ │ └── view │ │ │ ├── dash.go │ │ │ ├── errors.go │ │ │ └── router.go │ ├── gm │ │ ├── model │ │ │ ├── db.go │ │ │ ├── gold.go │ │ │ ├── roles.go │ │ │ ├── table.go │ │ │ └── task.go │ │ ├── service │ │ │ ├── accounts.go │ │ │ ├── auction.go │ │ │ ├── email.go │ │ │ ├── gold_init.go │ │ │ ├── model_account.go │ │ │ ├── model_task.go │ │ │ ├── roles.go │ │ │ ├── task.go │ │ │ └── util.go │ │ └── view │ │ │ ├── account.go │ │ │ ├── auction.go │ │ │ ├── email.go │ │ │ ├── errors.go │ │ │ ├── roles.go │ │ │ ├── router.go │ │ │ └── task.go │ ├── log │ │ ├── model │ │ │ ├── table.go │ │ │ └── util.go │ │ ├── service │ │ │ ├── model.go │ │ │ ├── operate_log.go │ │ │ └── recharge_log.go │ │ └── view │ │ │ ├── errors.go │ │ │ ├── recharge_log.go │ │ │ └── router.go │ ├── middleware │ │ ├── casbin_rbac.go │ │ ├── error.go │ │ └── operate.go │ ├── static │ │ └── view.go │ ├── user │ │ ├── auth │ │ │ ├── model │ │ │ │ └── config.go │ │ │ ├── service │ │ │ │ ├── auth.go │ │ │ │ └── op_info.go │ │ │ └── view │ │ │ │ └── auth.go │ │ ├── role │ │ │ ├── model │ │ │ │ └── role_map.go │ │ │ ├── service │ │ │ │ └── role.go │ │ │ └── view │ │ │ │ ├── errors.go │ │ │ │ ├── role.go │ │ │ │ └── router.go │ │ ├── router.go │ │ └── users │ │ │ ├── model │ │ │ ├── table.go │ │ │ └── user_map.go │ │ │ ├── service │ │ │ ├── user.go │ │ │ └── user_init.go │ │ │ └── view │ │ │ ├── errors.go │ │ │ ├── op_info.go │ │ │ ├── router.go │ │ │ └── user.go │ └── view │ │ ├── config.go │ │ ├── cors.go │ │ └── views.go ├── cmds │ ├── args.go │ ├── config.go │ ├── server.go │ ├── service.go │ ├── service_daemon.go │ └── service_main.go ├── config │ ├── rbac_model.conf │ └── server.json ├── go.mod ├── go.sum ├── main.go ├── mods │ ├── casbinx │ │ ├── casbin.go │ │ ├── config.go │ │ └── table.go │ ├── game_db │ │ ├── config.go │ │ ├── db.go │ │ ├── db_mysql.go │ │ ├── db_sqlite.go │ │ ├── migrate.go │ │ └── model.go │ ├── ginx │ │ ├── router.go │ │ └── table.go │ ├── pathx │ │ └── path.go │ └── readme.md └── source │ ├── gold.txt │ ├── private.pem │ └── publickey.pem ├── dist ├── .gitignore ├── config │ ├── rbac_model.conf │ └── server.json ├── main.exe ├── source │ ├── gold.txt │ ├── private.pem │ └── publickey.pem └── web │ └── static │ ├── favicon.ico │ ├── index.html │ └── lib │ ├── css │ ├── 141.95778f3a.css │ ├── 190.8bdff399.css │ ├── 200.fb6b2964.css │ ├── 220.95778f3a.css │ ├── 228.bd54ec38.css │ ├── 23.c722803a.css │ ├── 387.58c3a4c7.css │ ├── 504.95778f3a.css │ ├── 582.8bdff399.css │ ├── 693.8bdff399.css │ ├── 902.2ad5574d.css │ ├── 929.8bdff399.css │ ├── 953.8bdff399.css │ ├── app.76c5944a.css │ └── chunk-vendors.b6fbac7d.css │ ├── img │ ├── 401.1800ba9e.gif │ ├── 404.458c248a.png │ └── logo2.7bca92d9.png │ └── js │ ├── 134.d50f8eb4.js │ ├── 141.0831c36a.js │ ├── 190.3fe911a3.js │ ├── 200.8e316701.js │ ├── 220.76a17955.js │ ├── 228.5c599d35.js │ ├── 23.5cedb868.js │ ├── 387.08b35757.js │ ├── 390.a3a879bf.js │ ├── 504.6e8b787b.js │ ├── 567.a133d293.js │ ├── 582.59ea8022.js │ ├── 693.89e0d7a3.js │ ├── 902.255c5b24.js │ ├── 929.5b9f21b5.js │ ├── 953.5a64bcf3.js │ ├── app.a00b3824.js │ └── chunk-vendors.86afa7e2.js ├── web ├── .browserslistrc ├── .env.development ├── .env.production ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── api │ │ ├── client │ │ │ └── login.ts │ │ ├── dash │ │ │ └── index.ts │ │ ├── gm │ │ │ ├── accounts.ts │ │ │ ├── auction.ts │ │ │ ├── email.ts │ │ │ ├── role.ts │ │ │ └── task.ts │ │ ├── log │ │ │ └── index.ts │ │ └── user │ │ │ ├── auth.ts │ │ │ └── users.ts │ ├── assets │ │ ├── 401_images │ │ │ └── 401.gif │ │ ├── 404_images │ │ │ ├── 404.png │ │ │ └── 404_cloud.png │ │ ├── cms-icons.png │ │ ├── logo.png │ │ ├── logo2.png │ │ └── toinstlist.png │ ├── components │ │ ├── BreadCrumb │ │ │ ├── index.ts │ │ │ └── src │ │ │ │ └── BreadCrumb.vue │ │ ├── HamBurger │ │ │ ├── index.ts │ │ │ └── src │ │ │ │ └── HamBurger.vue │ │ ├── HeaderSearch │ │ │ └── index.vue │ │ ├── Layout │ │ │ ├── components │ │ │ │ ├── AppMain.vue │ │ │ │ ├── Navbar.vue │ │ │ │ ├── TagsView │ │ │ │ │ ├── ScrollPane.vue │ │ │ │ │ └── TagsView.vue │ │ │ │ ├── index.ts │ │ │ │ └── sidebar │ │ │ │ │ ├── Link.vue │ │ │ │ │ ├── SidebarItem.vue │ │ │ │ │ └── index.vue │ │ │ └── index.vue │ │ ├── PanelStep │ │ │ ├── index.ts │ │ │ └── src │ │ │ │ └── PanelStep.vue │ │ ├── PanelTitle │ │ │ ├── index.ts │ │ │ └── src │ │ │ │ └── PanelTitle.vue │ │ ├── Screenfull │ │ │ └── index.vue │ │ └── SvgIcon │ │ │ └── index.vue │ ├── icons │ │ ├── index.ts │ │ └── svg │ │ │ ├── bell.svg │ │ │ ├── bug.svg │ │ │ ├── close-eye.svg │ │ │ ├── cloud-download.svg │ │ │ ├── cog.svg │ │ │ ├── dashboard.svg │ │ │ ├── dollar.svg │ │ │ ├── envelope-closed.svg │ │ │ ├── envelope-open.svg │ │ │ ├── exit-fullscreen.svg │ │ │ ├── expand-down.svg │ │ │ ├── eye.svg │ │ │ ├── file.svg │ │ │ ├── fork.svg │ │ │ ├── fullscreen.svg │ │ │ ├── grid-four-up.svg │ │ │ ├── headphones.svg │ │ │ ├── home.svg │ │ │ ├── international.svg │ │ │ ├── key.svg │ │ │ ├── language.svg │ │ │ ├── layers.svg │ │ │ ├── link.svg │ │ │ ├── list-rich.svg │ │ │ ├── list.svg │ │ │ ├── lock.svg │ │ │ ├── menu.svg │ │ │ ├── nested.svg │ │ │ ├── open-eye.svg │ │ │ ├── password.svg │ │ │ ├── people.svg │ │ │ ├── person.svg │ │ │ ├── print.svg │ │ │ ├── pulse.svg │ │ │ ├── search.svg │ │ │ ├── shield.svg │ │ │ ├── timer.svg │ │ │ ├── transfer.svg │ │ │ └── yen.svg │ ├── main.ts │ ├── models │ │ ├── page.ts │ │ └── user │ │ │ ├── auth.ts │ │ │ └── user.ts │ ├── permission.ts │ ├── router │ │ ├── constant.ts │ │ ├── index.ts │ │ ├── modules │ │ │ ├── client.ts │ │ │ ├── gm.ts │ │ │ └── system.ts │ │ └── types.ts │ ├── settings.ts │ ├── store │ │ ├── index.ts │ │ └── modules │ │ │ ├── app.ts │ │ │ ├── permission.ts │ │ │ ├── tagsView.ts │ │ │ └── user.ts │ ├── styles │ │ ├── color.scss │ │ ├── elem.scss │ │ ├── index.scss │ │ ├── mixin.scss │ │ ├── sidebar.scss │ │ └── transition.scss │ ├── types │ │ ├── global.d.ts │ │ └── shims-vue.d.ts │ ├── utils │ │ ├── download │ │ │ └── index.ts │ │ ├── echarts │ │ │ ├── echarts.ts │ │ │ └── useEcharts.ts │ │ ├── element │ │ │ ├── form.ts │ │ │ ├── message.ts │ │ │ └── messageBox.ts │ │ ├── event │ │ │ ├── breakpointEnum.ts │ │ │ ├── useBreakpoint.ts │ │ │ └── useEventListener.ts │ │ ├── filters.ts │ │ ├── fn.ts │ │ ├── get-page-title.ts │ │ ├── http │ │ │ ├── config.ts │ │ │ ├── const.ts │ │ │ ├── core.ts │ │ │ ├── download.ts │ │ │ ├── index.ts │ │ │ ├── upload.ts │ │ │ └── utils.ts │ │ ├── index.ts │ │ ├── progress │ │ │ └── index.ts │ │ ├── propTypes.ts │ │ ├── storage │ │ │ └── index.ts │ │ ├── utils.ts │ │ └── vue │ │ │ ├── index.ts │ │ │ └── install.ts │ └── views │ │ ├── client │ │ └── login │ │ │ ├── index.vue │ │ │ └── models │ │ │ └── login.ts │ │ ├── dashboard │ │ ├── components │ │ │ ├── BarChart.vue │ │ │ ├── DashBody.vue │ │ │ ├── DashFoot.vue │ │ │ └── DashHeader.vue │ │ ├── dash.scss │ │ ├── index.vue │ │ └── model │ │ │ └── dash.ts │ │ ├── errorPage │ │ ├── 401.vue │ │ └── 404.vue │ │ ├── gm │ │ ├── account │ │ │ ├── components │ │ │ │ ├── ChangePassword.vue │ │ │ │ ├── CreateAccountDialog.vue │ │ │ │ ├── EditAccountDialog.vue │ │ │ │ └── RechargeDialog.vue │ │ │ ├── filter.vue │ │ │ ├── index.vue │ │ │ ├── model │ │ │ │ ├── info.ts │ │ │ │ └── model.ts │ │ │ └── table.vue │ │ ├── auction │ │ │ ├── index.vue │ │ │ └── model.ts │ │ ├── email │ │ │ ├── EmailForm.vue │ │ │ ├── index.vue │ │ │ └── model.ts │ │ ├── roles │ │ │ ├── RolesTable.vue │ │ │ ├── components │ │ │ │ ├── RolePvpDialog.vue │ │ │ │ └── RoleQPDialog.vue │ │ │ ├── index.vue │ │ │ ├── model.ts │ │ │ └── model │ │ │ │ ├── pvp.ts │ │ │ │ └── qp.ts │ │ └── tasks │ │ │ ├── RoleTable.vue │ │ │ ├── SelectAccount.vue │ │ │ ├── TaskDetail.vue │ │ │ ├── index.vue │ │ │ └── model.ts │ │ ├── login │ │ ├── index.vue │ │ └── login.scss │ │ ├── redirect │ │ └── index.vue │ │ ├── test.vue │ │ └── user │ │ ├── info │ │ └── index.vue │ │ ├── list │ │ ├── EditCreateUserdialog.vue │ │ └── index.vue │ │ └── test │ │ └── index.vue ├── tsconfig.json └── vue.config.js └── wxp.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 jason 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ../web 4 | 5 | npm install 6 | npm run build 7 | 8 | rm -rf ../dist/web/static/* 9 | cp -r dist/* ../dist/web/static 10 | 11 | cd ../console 12 | 13 | go build main.go 14 | yes | cp main ../dist 15 | 16 | cd ../build -------------------------------------------------------------------------------- /build/build_windows.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "errors" 7 | log "github.com/sirupsen/logrus" 8 | "golang.org/x/text/encoding/simplifiedchinese" 9 | "golang.org/x/text/transform" 10 | "io" 11 | "os/exec" 12 | "time" 13 | ) 14 | 15 | func main() { 16 | cmds := []string{ 17 | "cd ..\\web && npm i", 18 | "cd ..\\web && npm run build", 19 | "cd ..\\dist\\web && rmdir /s /q static", 20 | "cd ..\\dist\\web && mkdir static", 21 | "cd ..\\web && xcopy /s /e /i dist ..\\dist\\web\\static /Y", 22 | 23 | "cd ..\\console && go build main.go", 24 | "cd ..\\console && copy main.exe ..\\dist\\main.exe /Y && del main.exe", 25 | } 26 | 27 | for _, cmd := range cmds { 28 | out, err := WindowsExecByShell(cmd) 29 | if err != nil { 30 | log.Error(out) 31 | } 32 | log.Info("OUT:", out) 33 | } 34 | } 35 | 36 | func WindowsExecByShell(cmd string) (string, error) { 37 | ctx, cancel := context.WithTimeout(context.Background(), 500*time.Second) 38 | defer cancel() 39 | 40 | command := exec.CommandContext(ctx, "cmd", "/C", cmd) 41 | stdOut := bytes.Buffer{} 42 | stderr := bytes.Buffer{} 43 | command.Stdout = &stdOut 44 | command.Stderr = &stderr 45 | err := command.Run() 46 | if err != nil { 47 | s, _ := GbkToUtf8(stderr.Bytes()) 48 | return string(s), errors.New(stderr.String()) 49 | } 50 | return stdOut.String(), nil 51 | } 52 | 53 | func GbkToUtf8(s []byte) ([]byte, error) { 54 | reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewDecoder()) 55 | d, e := io.ReadAll(reader) 56 | if e != nil { 57 | return nil, e 58 | } 59 | return d, nil 60 | } 61 | -------------------------------------------------------------------------------- /build/git_push.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem git push 3 | 4 | git add . 5 | git commit -m "push" 6 | git push 7 | 8 | echo done 9 | pause -------------------------------------------------------------------------------- /build/go.mod: -------------------------------------------------------------------------------- 1 | module build 2 | 3 | go 1.21.5 4 | 5 | require ( 6 | github.com/sirupsen/logrus v1.9.3 7 | golang.org/x/text v0.14.0 8 | ) 9 | 10 | require golang.org/x/sys v0.5.0 // indirect 11 | -------------------------------------------------------------------------------- /build/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 5 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 6 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 7 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 8 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 9 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 10 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 11 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 12 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 13 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 14 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 15 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 16 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 17 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 18 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 19 | -------------------------------------------------------------------------------- /console/.gitignore: -------------------------------------------------------------------------------- 1 | /org 2 | /.vscode 3 | 4 | 5 | .vscode/* 6 | !.vscode/settings.json 7 | !.vscode/tasks.json 8 | !.vscode/launch.json 9 | !.vscode/extensions.json 10 | !.vscode/*.code-snippets 11 | 12 | # Local History for Visual Studio Code 13 | .history/ 14 | 15 | # Built Visual Studio Code Extensions 16 | *.vsix 17 | .idea 18 | 19 | 20 | data 21 | /log/ 22 | -------------------------------------------------------------------------------- /console/README.md: -------------------------------------------------------------------------------- 1 | # webconsole 2 | -------------------------------------------------------------------------------- /console/biz/client/model/db.go: -------------------------------------------------------------------------------- 1 | package model 2 | -------------------------------------------------------------------------------- /console/biz/client/service/login.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | gmModel "console/biz/gm/model" 5 | "console/mods/game_db" 6 | "crypto/md5" 7 | "encoding/hex" 8 | "errors" 9 | "fmt" 10 | "gorm.io/gorm" 11 | "os" 12 | ) 13 | 14 | func ToMd5(str string) string { 15 | h := md5.New() 16 | h.Write([]byte(str)) 17 | return hex.EncodeToString(h.Sum(nil)) 18 | } 19 | 20 | func Hex2bin(raw string) string { 21 | result, _ := hex.DecodeString(raw) 22 | return string(result) 23 | } 24 | 25 | // 10转16进制,不够补0 26 | func uidTo16(uid int) string { 27 | return fmt.Sprintf("%08x", uid) 28 | } 29 | 30 | func Login(data *LoginReq) (string, error) { 31 | dbx := game_db.DBPools.Get(gmModel.DTaiwan) 32 | 33 | var account gmModel.Accounts 34 | 35 | var err error 36 | if data.LoginType == "uid" { 37 | err = dbx.Where("UID = ?", data.Uid).First(&account).Error 38 | } else { 39 | err = dbx.Where("accountname = ? AND password = ?", data.Username, ToMd5(data.Password)).First(&account).Error 40 | } 41 | 42 | if errors.Is(err, gorm.ErrRecordNotFound) { 43 | return "", errors.New("账号未找到!") 44 | } 45 | 46 | uid16 := uidTo16(account.Uid) 47 | fmt.Println("data", data.LoginType, account.Uid, uid16) 48 | 49 | rsa := NewRsa() 50 | key := fmt.Sprintf("%s010101010101010101010101010101010101010101010101010101010101010155914510010403030101", uid16) 51 | d := Hex2bin(key) 52 | 53 | privateKey, _ := os.ReadFile(rsa.PrivateFile) 54 | token, err := applyPriEPubD(d, string(privateKey)) 55 | fmt.Println("err", err) 56 | if err != nil { 57 | return "", err 58 | } 59 | fmt.Println("key:", d) 60 | //token := base64.StdEncoding.EncodeToString(hashToken) 61 | fmt.Println("token:", token) 62 | return token, nil 63 | } 64 | -------------------------------------------------------------------------------- /console/biz/client/service/ras_hash.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "crypto/rand" 5 | "crypto/rsa" 6 | "crypto/x509" 7 | "encoding/pem" 8 | "os" 9 | ) 10 | 11 | // RasEncrypt RSA加密 12 | // plainText 要加密的数据 13 | // path 公钥匙文件地址 14 | func RasEncrypt(plainText []byte, path string) ([]byte, error) { 15 | //打开文件 16 | file, err := os.Open(path) 17 | if err != nil { 18 | panic(err) 19 | } 20 | defer file.Close() 21 | //读取文件的内容 22 | info, _ := file.Stat() 23 | buf := make([]byte, info.Size()) 24 | file.Read(buf) 25 | //pem解码 26 | block, _ := pem.Decode(buf) 27 | //x509解码 28 | 29 | publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes) 30 | if err != nil { 31 | return nil, err 32 | } 33 | //类型断言 34 | publicKey := publicKeyInterface.(*rsa.PublicKey) 35 | //对明文进行加密 36 | cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText) 37 | if err != nil { 38 | return nil, err 39 | } 40 | //返回密文 41 | return cipherText, nil 42 | } 43 | 44 | // RsaDecrypt RSA解密 45 | // cipherText 需要解密的byte数据 46 | // path 私钥文件路径 47 | func RsaDecrypt(cipherText []byte, path string) []byte { 48 | //打开文件 49 | file, err := os.Open(path) 50 | if err != nil { 51 | panic(err) 52 | } 53 | defer file.Close() 54 | //获取文件内容 55 | info, _ := file.Stat() 56 | buf := make([]byte, info.Size()) 57 | file.Read(buf) 58 | //pem解码 59 | block, _ := pem.Decode(buf) 60 | //X509解码 61 | privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) 62 | if err != nil { 63 | panic(err) 64 | } 65 | //对密文进行解密 66 | plainText, _ := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText) 67 | //返回明文 68 | return plainText 69 | } 70 | -------------------------------------------------------------------------------- /console/biz/client/service/ras_tool.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | gorsa "github.com/Lyafei/go-rsa" 5 | ) 6 | 7 | func applyPriEPubD(data, pirvatekey string) (string, error) { 8 | prienctypt, err := gorsa.PriKeyEncrypt(data, pirvatekey) 9 | if err != nil { 10 | return "", err 11 | } 12 | 13 | return prienctypt, nil 14 | } 15 | -------------------------------------------------------------------------------- /console/biz/client/service/req.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | type LoginReq struct { 4 | LoginType string `json:"login_type"` 5 | Uid int `json:"uid"` 6 | Username string `json:"username"` 7 | Password string `json:"password"` 8 | } 9 | -------------------------------------------------------------------------------- /console/biz/client/service/rsa.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "console/mods/pathx" 5 | "crypto/rand" 6 | "crypto/rsa" 7 | "crypto/x509" 8 | "encoding/pem" 9 | "os" 10 | "path/filepath" 11 | ) 12 | 13 | type Rsa struct { 14 | PrivateFile string 15 | PublicFile string 16 | } 17 | 18 | func NewRsa() *Rsa { 19 | exeDir, _ := pathx.GetExeDir() 20 | publickeyFile := filepath.Join(exeDir, "source", "publickey.pem") 21 | privateFile := filepath.Join(exeDir, "source", "private.pem") 22 | return &Rsa{ 23 | PublicFile: publickeyFile, 24 | PrivateFile: privateFile, 25 | } 26 | } 27 | 28 | // GenRsaKey RSA公钥私钥产生 29 | func (r *Rsa) GenRsaKey(bits int) error { 30 | // 生成私钥文件 31 | privateKey, err := rsa.GenerateKey(rand.Reader, bits) 32 | if err != nil { 33 | return err 34 | } 35 | derStream := x509.MarshalPKCS1PrivateKey(privateKey) 36 | block := &pem.Block{ 37 | Type: "RSA PRIVATE KEY", 38 | Bytes: derStream, 39 | } 40 | file, err := os.Create(r.PrivateFile) 41 | if err != nil { 42 | return err 43 | } 44 | err = pem.Encode(file, block) 45 | if err != nil { 46 | return err 47 | } 48 | // 生成公钥文件 49 | publicKey := &privateKey.PublicKey 50 | derPkix, err := x509.MarshalPKIXPublicKey(publicKey) 51 | if err != nil { 52 | return err 53 | } 54 | block = &pem.Block{ 55 | Type: "PUBLIC KEY", 56 | Bytes: derPkix, 57 | } 58 | file, err = os.Create(r.PublicFile) 59 | if err != nil { 60 | return err 61 | } 62 | err = pem.Encode(file, block) 63 | if err != nil { 64 | return err 65 | } 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /console/biz/client/view/errors.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | const ( 4 | E_CLIENT_LOGIN = "E_CLIENT_LOGIN" 5 | ) 6 | -------------------------------------------------------------------------------- /console/biz/client/view/login.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/client/service" 5 | "github.com/gin-gonic/gin" 6 | "github.com/localhostjason/webserver/server/util/uv" 7 | ) 8 | 9 | func login(c *gin.Context) { 10 | data := &service.LoginReq{} 11 | uv.PB(c, data) 12 | 13 | token, err := service.Login(data) 14 | uv.PEIf(E_CLIENT_LOGIN, err) 15 | c.JSON(200, map[string]string{"token": token}) 16 | } 17 | -------------------------------------------------------------------------------- /console/biz/client/view/router.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import "console/mods/ginx" 4 | 5 | func InitClientRouter(r *ginx.RouterGroup) { 6 | client := r.Group("客户端登录", "") 7 | { 8 | client.POST("登录", "login", login) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /console/biz/dash/service/chart.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | logModel "console/biz/log/model" 5 | "fmt" 6 | "github.com/localhostjason/webserver/db" 7 | "time" 8 | ) 9 | 10 | func GetDashChart() ChartResult { 11 | return ChartResult{ 12 | Cera: getChartByType("cera"), 13 | CeraPoint: getChartByType("cera_point"), 14 | } 15 | } 16 | 17 | func getChartByType(typ string) ChartTranInfo { 18 | var data []ChartInfo 19 | 20 | now := time.Now() 21 | nowYear := now.Format("2006") 22 | 23 | tx := db.DB.Debug().Model(&logModel.RechargeLog{}). 24 | Select("sum(number) as total,strftime('%Y',time) as year, strftime('%m',time) AS month"). 25 | Group("year, month"). 26 | Having("year = ?", nowYear) 27 | 28 | if typ == "cera" { 29 | tx = tx.Where("action = ?", logModel.RechargeCera) 30 | } else { 31 | tx = tx.Where("action = ?", logModel.RechargeCeraPoint) 32 | } 33 | tx.Find(&data) 34 | 35 | date := make([]string, 0) 36 | for i := 1; i <= 12; i++ { 37 | date = append(date, fmt.Sprintf("%d月", i)) 38 | } 39 | 40 | number := make([]int, 0) 41 | for i := 1; i <= 12; i++ { 42 | isAppend := false 43 | for _, info := range data { 44 | if info.Month == i { 45 | number = append(number, info.Total) 46 | isAppend = true 47 | break 48 | } 49 | } 50 | 51 | if !isAppend { 52 | number = append(number, 0) 53 | } 54 | 55 | } 56 | 57 | return ChartTranInfo{ 58 | Date: date, 59 | Total: number, 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /console/biz/dash/service/dash.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "console/biz/gm/model" 5 | logModel "console/biz/log/model" 6 | "console/mods/game_db" 7 | "github.com/localhostjason/webserver/db" 8 | ) 9 | 10 | func GetDashStatTotal() StatCountResult { 11 | return StatCountResult{ 12 | CeraTotal: GetRechargeTotal("cera"), 13 | CeraPointTotal: GetRechargeTotal("cera_point"), 14 | UserTotal: getAccountTotal(), 15 | CharacTotal: getCharacTotal(), 16 | } 17 | } 18 | 19 | func GetRechargeTotal(typ string) int { 20 | type _R struct { 21 | Total int `json:"total"` 22 | } 23 | var data _R 24 | tx := db.DB.Model(&logModel.RechargeLog{}).Select("sum(number) as total").Group("action") 25 | if typ == "cera" { 26 | tx.Having("action = 1").First(&data) 27 | } else { 28 | tx.Having("action = 2").First(&data) 29 | } 30 | 31 | return data.Total 32 | } 33 | 34 | func getAccountTotal() int { 35 | dbx := game_db.DBPools.Get(model.DTaiwan) 36 | 37 | var total int64 38 | dbx.Model(&model.Accounts{}).Count(&total) 39 | return int(total) 40 | } 41 | 42 | func getCharacTotal() int { 43 | dbx := game_db.DBPools.Get(model.DTaiwan) 44 | var accounts []model.Accounts 45 | dbx.Find(&accounts) 46 | 47 | uids := make([]int, 0) 48 | for _, info := range accounts { 49 | uids = append(uids, info.Uid) 50 | } 51 | 52 | db2 := game_db.DBPools.Get(model.TaiwanCain) 53 | 54 | var total int64 55 | db2.Table("charac_info").Where("m_id IN ? AND delete_flag = ?", uids, 0).Count(&total) 56 | return int(total) 57 | } 58 | -------------------------------------------------------------------------------- /console/biz/dash/service/model.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | type StatCountResult struct { 4 | UserTotal int `json:"user_total"` 5 | CharacTotal int `json:"charac_total"` 6 | CeraTotal int `json:"cera_total"` 7 | CeraPointTotal int `json:"cera_point_total"` 8 | } 9 | 10 | type TopInfo struct { 11 | Uid int `json:"uid"` 12 | AccountName string `json:"account_name"` 13 | Total int `json:"total"` 14 | } 15 | 16 | type StatTop5Result struct { 17 | Cera []TopInfo `json:"cera"` 18 | CeraPoint []TopInfo `json:"cera_point"` 19 | CeraTotal int `json:"cera_total"` 20 | CeraPointTotal int `json:"cera_point_total"` 21 | } 22 | 23 | type ChartInfo struct { 24 | Year int `json:"year"` 25 | Month int `json:"month"` 26 | Total int `json:"total"` 27 | } 28 | 29 | type ChartTranInfo struct { 30 | Date []string `json:"date"` 31 | Total []int `json:"total"` 32 | } 33 | 34 | type ChartResult struct { 35 | Cera ChartTranInfo `json:"cera"` 36 | CeraPoint ChartTranInfo `json:"cera_point"` 37 | } 38 | -------------------------------------------------------------------------------- /console/biz/dash/service/top5.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "console/biz/gm/model" 5 | logModel "console/biz/log/model" 6 | "console/mods/game_db" 7 | "github.com/localhostjason/webserver/db" 8 | ) 9 | 10 | func GetRechargeTop5() StatTop5Result { 11 | return StatTop5Result{ 12 | Cera: getRechargeTop5ByType("cera"), 13 | CeraPoint: getRechargeTop5ByType("cera_point"), 14 | CeraTotal: GetRechargeTotal("cera"), 15 | CeraPointTotal: GetRechargeTotal("cera_point"), 16 | } 17 | } 18 | 19 | func getRechargeTop5ByType(typ string) []TopInfo { 20 | var data []TopInfo 21 | tx := db.DB.Model(&logModel.RechargeLog{}).Select("sum(number) as total, uid").Group("action, uid").Order("total desc").Limit(5) 22 | 23 | if typ == "cera" { 24 | tx.Having("action = 1") 25 | } else { 26 | tx.Having("action = 2") 27 | } 28 | tx.Find(&data) 29 | 30 | result := make([]TopInfo, 0) 31 | for _, info := range data { 32 | info.AccountName = getAccountNameByUid(info.Uid) 33 | result = append(result, info) 34 | } 35 | return result 36 | } 37 | 38 | func getAccountNameByUid(uid int) string { 39 | dbx := game_db.DBPools.Get(model.DTaiwan) 40 | var data model.Accounts 41 | dbx.Where("UID = ?", uid).First(&data) 42 | return data.AccountName 43 | } 44 | -------------------------------------------------------------------------------- /console/biz/dash/view/dash.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/dash/service" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | func getDashStatCount(c *gin.Context) { 9 | data := service.GetDashStatTotal() 10 | c.JSON(200, data) 11 | } 12 | 13 | func getDashTop5(c *gin.Context) { 14 | data := service.GetRechargeTop5() 15 | c.JSON(200, data) 16 | } 17 | 18 | func getDashChart(c *gin.Context) { 19 | data := service.GetDashChart() 20 | c.JSON(200, data) 21 | } 22 | -------------------------------------------------------------------------------- /console/biz/dash/view/errors.go: -------------------------------------------------------------------------------- 1 | package view 2 | -------------------------------------------------------------------------------- /console/biz/dash/view/router.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import "console/mods/ginx" 4 | 5 | func InitDashRouter(r *ginx.RouterGroup) { 6 | r.GET("获取首页统计", "stat/count", getDashStatCount) 7 | r.GET("获取首页Top5", "stat/top5", getDashTop5) 8 | r.GET("获取首页图表", "stat/chart", getDashChart) 9 | //r.GET("操作日志", "operate", getOperateLog) 10 | } 11 | -------------------------------------------------------------------------------- /console/biz/gm/model/db.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | const DTaiwan = "d_taiwan" 4 | const TaiwanCain = "taiwan_cain" 5 | 6 | const TaiwanCain2nd = "taiwan_cain_2nd" 7 | 8 | const TaiwanBilling = "taiwan_billing" 9 | 10 | const TaiwanLogin = "taiwan_login" 11 | 12 | const TaiwanCainAuctionGold = "taiwan_cain_auction_gold" 13 | const TaiwanCainAuctionCera = "taiwan_cain_auction_cera" 14 | -------------------------------------------------------------------------------- /console/biz/gm/model/gold.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "console/mods/game_db" 5 | ) 6 | 7 | type Gold struct { 8 | Id int `json:"id" gorm:"primaryKey"` 9 | Code int `json:"code"` 10 | Name string `json:"name" gorm:"type:string;size:128"` 11 | } 12 | 13 | func init() { 14 | game_db.RegTables(TaiwanCain2nd, &Gold{}) 15 | } 16 | -------------------------------------------------------------------------------- /console/biz/gm/model/roles.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type CharacInfo struct { 6 | MId int `json:"m_id"` 7 | CharacNo int `json:"charac_no"` 8 | CharacName string `json:"charac_name"` 9 | Lev int `json:"lev"` 10 | CreateTime time.Time `json:"create_time"` 11 | } 12 | 13 | type CharacInfoV2 struct { 14 | MId int `json:"m_id"` 15 | CharacNo int `json:"charac_no"` 16 | ConvertedCharacName string `json:"converted_charac_name"` 17 | Lev int `json:"lev"` 18 | CreateTime time.Time `json:"create_time"` 19 | } 20 | -------------------------------------------------------------------------------- /console/biz/gm/model/table.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "console/mods/game_db" 4 | 5 | type Accounts struct { 6 | Uid int `json:"uid" gorm:"column:UID;primaryKey"` 7 | AccountName string `json:"account_name" gorm:"column:accountname;type:string;size:128;unique;not null"` 8 | Password string `json:"-" gorm:"type:string;size:128;not null"` 9 | QQ string `json:"qq" gorm:"type:string;size:128;"` 10 | } 11 | 12 | func init() { 13 | game_db.RegTables(DTaiwan, &Accounts{}) 14 | } 15 | -------------------------------------------------------------------------------- /console/biz/gm/model/task.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type Task struct { 4 | CharacNo int `json:"charac_no"` 5 | Play1 int `json:"play_1" gorm:"column:play_1;"` 6 | Play1Trigger int `json:"play_1_trigger" gorm:"column:play_1_trigger;"` 7 | } 8 | -------------------------------------------------------------------------------- /console/biz/gm/service/email.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "console/biz/gm/model" 5 | "console/mods/game_db" 6 | "github.com/localhostjason/webserver/server/util/uv" 7 | "time" 8 | ) 9 | 10 | // SendEmail 插入 2条记录 letter postal 11 | func SendEmail(characNo int, email *Email) error { 12 | dbx := game_db.DBPools.Get(model.TaiwanCain2nd) 13 | 14 | err := dbx.Table("letter").Create(map[string]interface{}{ 15 | "charac_no": characNo, 16 | "send_charac_no": 0, 17 | "send_charac_name": "GM", 18 | "letter_text": "Thanks!", 19 | "stat": 1, 20 | }).Error 21 | 22 | if err != nil { 23 | return err 24 | } 25 | 26 | type _R struct { 27 | LetterId int `json:"letter_id"` 28 | } 29 | var data _R 30 | dbx.Table("letter").Where("charac_no = ?", characNo).Order("letter_id desc").Take(&data) 31 | 32 | //fmt.Println(123, data.LetterId) 33 | amplifyOption := 0 34 | amplifyValue := 0 35 | if email.IsAmplify { 36 | amplifyOption = email.AmplifyOption 37 | amplifyValue = email.AmplifyValue 38 | } 39 | 40 | now := time.Now() 41 | return dbx.Debug().Table("postal").Create(map[string]interface{}{ 42 | "occ_time": now.Format("2006-01-02 15:04:05"), 43 | "send_charac_no": 0, 44 | "send_charac_name": "GAME MASTER", 45 | "receive_charac_no": characNo, 46 | "item_id": email.Code, 47 | "add_info": email.Number, 48 | "letter_id": data.LetterId, 49 | "seperate_upgrade": email.SeperateUpgrade, 50 | "upgrade": email.Upgrade, 51 | "amplify_option": amplifyOption, 52 | "amplify_value": amplifyValue, 53 | "gold": email.Gold, 54 | "seal_flag": email.SealFlag, 55 | }).Error 56 | 57 | } 58 | 59 | func GetGoldList(q *GoldQ, pi *uv.PagingIn, order *uv.Order) ([]model.Gold, *uv.PagingOut, error) { 60 | dbx := game_db.DBPools.Get(model.TaiwanCain2nd) 61 | tx := q.FilterQuery(dbx) 62 | 63 | var lst = make([]model.Gold, 0) 64 | po, err := uv.PagingFind(tx, &lst, pi, order) 65 | 66 | return lst, po, err 67 | } 68 | -------------------------------------------------------------------------------- /console/biz/gm/service/gold_init.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "bufio" 5 | "console/biz/gm/model" 6 | "console/mods/game_db" 7 | "console/mods/pathx" 8 | "fmt" 9 | "github.com/localhostjason/webserver/util" 10 | "io" 11 | "os" 12 | "path/filepath" 13 | "regexp" 14 | "strconv" 15 | "strings" 16 | ) 17 | 18 | type GoldFile struct { 19 | File string 20 | } 21 | 22 | func NewGoldFile() *GoldFile { 23 | return &GoldFile{ 24 | File: getGoldFile(), 25 | } 26 | } 27 | 28 | func getGoldFile() string { 29 | exeDir, _ := pathx.GetExeDir() 30 | goldFile := filepath.Join(exeDir, "source", "gold.txt") 31 | if !util.PathExists(goldFile) { 32 | return "" 33 | } 34 | return goldFile 35 | } 36 | 37 | func (gf *GoldFile) Read() []model.Gold { 38 | fs, err := os.Open(gf.File) 39 | if err != nil { 40 | return nil 41 | } 42 | 43 | goldList := make([]model.Gold, 0) 44 | line := bufio.NewReader(fs) 45 | for { 46 | content, _, err := line.ReadLine() 47 | if err == io.EOF { 48 | fs.Close() //关闭 49 | break 50 | } 51 | 52 | data := string(content) 53 | reg, _ := regexp.Compile("\\[(.*?)]") 54 | ver := reg.FindAllStringSubmatch(data, 1) 55 | if len(ver) == 0 { 56 | continue 57 | } 58 | code, err := strconv.Atoi(strings.TrimSpace(ver[0][1])) 59 | if err != nil { 60 | continue 61 | } 62 | 63 | reg2, _ := regexp.Compile(".*name:(.*)") 64 | d := reg2.FindAllStringSubmatch(data, 1) 65 | name := strings.TrimSpace(d[0][1]) 66 | 67 | goldList = append(goldList, model.Gold{ 68 | Code: code, 69 | Name: name, 70 | }) 71 | } 72 | 73 | return goldList 74 | } 75 | 76 | func (gf *GoldFile) WriteDB() error { 77 | data := gf.Read() 78 | dbx := game_db.DBPools.Get(model.TaiwanCain2nd) 79 | 80 | var gs []model.Gold 81 | dbx.Find(&gs) 82 | if len(gs) > 0 { 83 | return nil 84 | } 85 | 86 | fmt.Println("start") 87 | dbx.Where("1=1").Delete(&model.Gold{}) 88 | dbx.CreateInBatches(&data, 10000) 89 | fmt.Println("stop") 90 | return nil 91 | } 92 | 93 | func init() { 94 | gf := NewGoldFile() 95 | // 数据太多,直接执行sql 导入? 96 | game_db.AddInitHook(gf.WriteDB) 97 | } 98 | -------------------------------------------------------------------------------- /console/biz/gm/service/model_task.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "console/biz/gm/model" 5 | "github.com/localhostjason/webserver/db" 6 | "gorm.io/gorm" 7 | ) 8 | 9 | type TaskId struct { 10 | Ids []int `json:"ids"` 11 | } 12 | 13 | type Email struct { 14 | Code int `json:"code" binding:"gte=0"` 15 | Number int `json:"number" binding:"required"` 16 | SeperateUpgrade int `json:"seperate_upgrade"` // 武将锻造等级 17 | Upgrade int `json:"upgrade"` // 装备等级 18 | IsAmplify bool `json:"is_amplify"` // 具有异界属性 19 | AmplifyOption int `json:"amplify_option"` 20 | AmplifyValue int `json:"amplify_value"` 21 | Gold int `json:"gold"` // 金币 22 | SealFlag bool `json:"seal_flag"` // 是否封装 23 | } 24 | 25 | type GoldQ struct { 26 | Name string `form:"name"` 27 | } 28 | 29 | func (q GoldQ) FilterQuery(dbx *gorm.DB) (tx *gorm.DB) { 30 | tx = dbx.Model(&model.Gold{}) 31 | 32 | if q.Name != "" { 33 | tx = tx.Where("name like ?", db.Like(q.Name)) 34 | } 35 | return 36 | } 37 | -------------------------------------------------------------------------------- /console/biz/gm/service/task.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "console/biz/gm/model" 5 | "console/mods/game_db" 6 | "errors" 7 | "fmt" 8 | "gorm.io/gorm" 9 | ) 10 | 11 | func GetTaskByRole(characNo int) ([]model.Task, error) { 12 | dbx := game_db.DBPools.Get(model.TaiwanCain) 13 | 14 | var characInfo model.CharacInfo 15 | err := dbx.Table("charac_info").Where("charac_no = ?", characNo).First(&characInfo).Error 16 | if errors.Is(err, gorm.ErrRecordNotFound) { 17 | return nil, errors.New("角色不存在!") 18 | } 19 | 20 | var data = make([]model.Task, 0) 21 | dbx.Table("new_charac_quest").Where("charac_no = ?", characNo).Find(&data) 22 | return data, nil 23 | } 24 | 25 | func UpdateTaskByRole(characNo int, ids []int) error { 26 | dbx := game_db.DBPools.Get(model.TaiwanCain) 27 | 28 | var characInfo model.CharacInfo 29 | err := dbx.Table("charac_info").Where("charac_no = ?", characNo).First(&characInfo).Error 30 | if errors.Is(err, gorm.ErrRecordNotFound) { 31 | return errors.New("角色不存在!") 32 | } 33 | 34 | var updateMap = make(map[string]interface{}, 0) 35 | for i := 1; i <= 20; i++ { 36 | key := fmt.Sprintf("play_%d_trigger", i) 37 | updateMap[key] = 0 38 | } 39 | 40 | fmt.Println(111, characNo, ids, updateMap) 41 | 42 | if len(ids) == 0 { 43 | return errors.New("请选择任务!") 44 | } 45 | 46 | for _, id := range ids { 47 | err = dbx.Debug().Table("new_charac_quest").Where("charac_no = ? AND play_1 = ?", characNo, id).Updates(updateMap).Error 48 | if err != nil { 49 | return err 50 | } 51 | } 52 | return nil 53 | } 54 | -------------------------------------------------------------------------------- /console/biz/gm/service/util.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | ) 7 | 8 | func ToMd5(str string) string { 9 | h := md5.New() 10 | h.Write([]byte(str)) 11 | return hex.EncodeToString(h.Sum(nil)) 12 | } 13 | -------------------------------------------------------------------------------- /console/biz/gm/view/account.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/gm/service" 5 | "github.com/gin-gonic/gin" 6 | "github.com/localhostjason/webserver/server/util/uv" 7 | ) 8 | 9 | func getAccounts(c *gin.Context) { 10 | var pi, order, q = &uv.PagingIn{}, &uv.Order{}, &service.AccountFilter{} 11 | uv.PQ(c, pi, order, q) 12 | lst, po, err := service.GetAccounts(q, pi, order) 13 | uv.PEIf(E_ACCOUNT_GET, err) 14 | 15 | c.JSON(200, uv.PagedOut(lst, po)) 16 | } 17 | 18 | func rechargeAccount(c *gin.Context) { 19 | uid := uv.PPID(c, "id") 20 | 21 | data := &service.RechargeReq{} 22 | uv.PB(c, data) 23 | 24 | err := service.RechargeAccount(uid, data, c) 25 | uv.PEIf(E_RECHARGE_POST, err) 26 | c.Status(201) 27 | } 28 | 29 | func resetCreateCharac(c *gin.Context) { 30 | uid := uv.PPID(c, "id") 31 | err := service.ResetCreateCharac(uid) 32 | uv.PEIf(E_RESET_CREATE_CHARAC, err) 33 | c.Status(201) 34 | } 35 | 36 | func deleteAccount(c *gin.Context) { 37 | uid := uv.PPID(c, "id") 38 | err := service.DeleteAccount(uid) 39 | uv.PEIf(E_ACCOUNT_DELETE, err) 40 | c.Status(201) 41 | } 42 | 43 | func changePassword(c *gin.Context) { 44 | args := &service.PasswordReq{} 45 | uv.PB(c, args) 46 | 47 | uid := uv.PPID(c, "id") 48 | err := service.ChangeAccountPassword(uid, args) 49 | uv.PEIf(E_ACCOUNT_CHANGE_PASSWORD, err) 50 | c.Status(201) 51 | } 52 | 53 | func createAccount(c *gin.Context) { 54 | args := &service.CreateAccountReq{} 55 | uv.PB(c, args) 56 | 57 | err := service.CreateAccount(args) 58 | uv.PEIf(E_ACCOUNT_CREARE, err) 59 | c.Status(201) 60 | } 61 | 62 | func updateAccount(c *gin.Context) { 63 | args := &service.UpdateAccountReq{} 64 | uv.PB(c, args) 65 | 66 | uid := uv.PPID(c, "id") 67 | err := service.UpdateAccountInfo(uid, args) 68 | uv.PEIf(E_ACCOUNT_UPDATE, err) 69 | c.Status(201) 70 | } 71 | -------------------------------------------------------------------------------- /console/biz/gm/view/auction.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/gm/service" 5 | "github.com/gin-gonic/gin" 6 | "github.com/localhostjason/webserver/server/util/uv" 7 | ) 8 | 9 | func getAuctionSate(c *gin.Context) { 10 | data := service.GetAuctionState() 11 | c.JSON(200, data) 12 | } 13 | 14 | func openAuctionSate(c *gin.Context) { 15 | name := c.Param("name") 16 | err := service.OpenAuction(name) 17 | uv.PEIf(E_OPEN_AUCTION, err) 18 | c.Status(201) 19 | } 20 | 21 | func closeAuction(c *gin.Context) { 22 | c.JSON(200, "未实现") 23 | } 24 | -------------------------------------------------------------------------------- /console/biz/gm/view/email.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/gm/service" 5 | "github.com/gin-gonic/gin" 6 | "github.com/localhostjason/webserver/server/util/uv" 7 | ) 8 | 9 | func sendEmail(c *gin.Context) { 10 | characNo := uv.PPID(c, "id") 11 | 12 | email := &service.Email{} 13 | uv.PB(c, email) 14 | err := service.SendEmail(characNo, email) 15 | uv.PEIf(E_EMAIL_POST, err) 16 | c.Status(201) 17 | } 18 | 19 | func getGolds(c *gin.Context) { 20 | var pi, order, q = &uv.PagingIn{}, &uv.Order{}, &service.GoldQ{} 21 | uv.PQ(c, pi, order, q) 22 | 23 | lst, po, err := service.GetGoldList(q, pi, order) 24 | uv.PEIf(E_GOLD_GET, err) 25 | c.JSON(200, uv.PagedOut(lst, po)) 26 | } 27 | -------------------------------------------------------------------------------- /console/biz/gm/view/roles.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/gm/service" 5 | "github.com/gin-gonic/gin" 6 | "github.com/localhostjason/webserver/server/util/uv" 7 | ) 8 | 9 | func getRoles(c *gin.Context) { 10 | mid := uv.PPID(c, "id") 11 | roles, err := service.GetRoles(mid) 12 | uv.PEIf(E_ROLES_GET, err) 13 | c.JSON(200, roles) 14 | } 15 | 16 | func changeQp(c *gin.Context) { 17 | args := &service.UpdateQpReq{} 18 | uv.PB(c, args) 19 | 20 | characNo := uv.PPID(c, "id") 21 | err := service.UpdateQp(characNo, args) 22 | uv.PEIf(E_ROLES_UPDATE_QP, err) 23 | c.Status(201) 24 | } 25 | 26 | func changePvp(c *gin.Context) { 27 | args := &service.UpdatePvpReq{} 28 | uv.PB(c, args) 29 | 30 | characNo := uv.PPID(c, "id") 31 | err := service.UpdatePvp(characNo, args) 32 | uv.PEIf(E_ROLES_UPDATE_PVP, err) 33 | c.Status(201) 34 | } 35 | -------------------------------------------------------------------------------- /console/biz/gm/view/router.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import "console/mods/ginx" 4 | 5 | func InitGmRouter(r *ginx.RouterGroup) { 6 | 7 | accounts := r.Group("账号相关", "account") 8 | { 9 | accounts.GET("获取账号列表", "list", getAccounts) 10 | accounts.GET("获取角色信息", ":id/roles", getRoles) 11 | 12 | accounts.DELETE("删除账号", ":id", deleteAccount) 13 | accounts.POST("修改账号密码", ":id/change_password", changePassword) 14 | accounts.POST("创建账号", "", createAccount) 15 | accounts.PUT("修改账号信息", ":id", updateAccount) 16 | 17 | accounts.POST("充值", ":id/recharge", rechargeAccount) 18 | accounts.POST("重置创建角色", ":id/reset_create_charac", resetCreateCharac) 19 | } 20 | 21 | roles := r.Group("角色管理", "roles") 22 | { 23 | roles.PUT("修改QP", ":id/qp", changeQp) 24 | roles.PUT("修改pk段位", ":id/pvp", changePvp) 25 | 26 | roles.GET("获取任务列表", ":id/tasks", getRoleTasks) 27 | roles.PUT("更新任务列表", ":id/tasks", updateRoleTasks) 28 | 29 | roles.POST("发送邮件", ":id/email", sendEmail) // id === charac no 30 | } 31 | 32 | gold := r.Group("物品", "gold") 33 | { 34 | gold.GET("获取物品代码", "list", getGolds) 35 | } 36 | 37 | auction := r.Group("拍卖行", "auction") 38 | { 39 | auction.GET("状态", "state", getAuctionSate) 40 | auction.POST("开启", ":name/open", openAuctionSate) 41 | auction.POST("关闭", ":name/close", closeAuction) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /console/biz/gm/view/task.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/gm/service" 5 | "github.com/gin-gonic/gin" 6 | "github.com/localhostjason/webserver/server/util/uv" 7 | ) 8 | 9 | func getRoleTasks(c *gin.Context) { 10 | characNo := uv.PPID(c, "id") 11 | data, err := service.GetTaskByRole(characNo) 12 | uv.PEIf(E_TASKS_GET, err) 13 | c.JSON(200, data) 14 | } 15 | 16 | func updateRoleTasks(c *gin.Context) { 17 | characNo := uv.PPID(c, "id") 18 | 19 | args := &service.TaskId{} 20 | uv.PB(c, args) 21 | 22 | err := service.UpdateTaskByRole(characNo, args.Ids) 23 | uv.PEIf(E_TASKS_UPDATE, err) 24 | c.Status(201) 25 | } 26 | -------------------------------------------------------------------------------- /console/biz/log/model/table.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "github.com/localhostjason/webserver/db" 5 | "time" 6 | ) 7 | 8 | const ( 9 | RechargeCera = 1 // action 充值D币 10 | RechargeCeraPoint = 2 // action 充值D点 11 | ) 12 | 13 | // RechargeLog 充值記錄 14 | type RechargeLog struct { 15 | Id int `json:"id" gorm:"primaryKey"` 16 | Uid int `json:"uid" gorm:"uid" gorm:"not null"` 17 | Ip string `json:"ip" gorm:"type=string;size=64"` 18 | Time time.Time `json:"time" gorm:"not null"` 19 | Action int `json:"action"` 20 | Number int `json:"number"` 21 | } 22 | 23 | // 操作日志 24 | 25 | type OperateLog struct { 26 | Id int `json:"id" gorm:"primaryKey"` 27 | Username string `json:"username"` 28 | Time time.Time `json:"time" gorm:"not null"` 29 | Ip string `json:"ip" gorm:"type=string;size=64"` 30 | Action string `json:"action"` 31 | Result string `json:"result"` 32 | } 33 | 34 | func init() { 35 | db.RegTables(&RechargeLog{}, &OperateLog{}) 36 | } 37 | -------------------------------------------------------------------------------- /console/biz/log/model/util.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "console/biz/user/auth/service" 5 | "github.com/gin-gonic/gin" 6 | "github.com/localhostjason/webserver/db" 7 | "time" 8 | ) 9 | 10 | func CreateRechargeLog(uid int, action int, number int, c *gin.Context) { 11 | log := &RechargeLog{ 12 | Uid: uid, 13 | Time: time.Now(), 14 | Action: action, 15 | Number: number, 16 | Ip: c.RemoteIP(), 17 | } 18 | 19 | db.DB.Create(log) 20 | return 21 | } 22 | 23 | func CreateOperateLog(action string, msg string, c *gin.Context) { 24 | currentUser := service.CurrentUser(c) 25 | log := &OperateLog{ 26 | Username: currentUser.Username, 27 | Time: time.Now(), 28 | Action: action, 29 | Result: msg, 30 | Ip: c.RemoteIP(), 31 | } 32 | db.DB.Create(&log) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /console/biz/log/service/model.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "console/biz/log/model" 5 | "github.com/localhostjason/webserver/db" 6 | "gorm.io/gorm" 7 | ) 8 | 9 | type RechargeQ struct { 10 | Uid string `form:"uid"` 11 | } 12 | 13 | func (q RechargeQ) FilterQuery(dbx *gorm.DB) (tx *gorm.DB) { 14 | tx = dbx.Model(&model.RechargeLog{}) 15 | 16 | if q.Uid != "" { 17 | tx = tx.Where("uid like ?", db.Like(q.Uid)) 18 | } 19 | return 20 | } 21 | 22 | type OperateQ struct { 23 | Action string `form:"action"` 24 | } 25 | 26 | func (q OperateQ) FilterQuery(dbx *gorm.DB) (tx *gorm.DB) { 27 | tx = dbx.Model(&model.OperateLog{}) 28 | 29 | if q.Action != "" { 30 | tx = tx.Where("action like ?", db.Like(q.Action)) 31 | } 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /console/biz/log/service/operate_log.go: -------------------------------------------------------------------------------- 1 | package service 2 | -------------------------------------------------------------------------------- /console/biz/log/service/recharge_log.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "console/biz/log/model" 5 | "github.com/localhostjason/webserver/db" 6 | "github.com/localhostjason/webserver/server/util/uv" 7 | ) 8 | 9 | func GetReChargeLogList(q *RechargeQ, pi *uv.PagingIn, order *uv.Order) ([]model.RechargeLog, *uv.PagingOut, error) { 10 | tx := q.FilterQuery(db.DB) 11 | var lst = make([]model.RechargeLog, 0) 12 | 13 | po, err := uv.PagingFind(tx, &lst, pi, order) 14 | return lst, po, err 15 | } 16 | 17 | func GetOperateLogList(q *OperateQ, pi *uv.PagingIn, order *uv.Order) ([]model.OperateLog, *uv.PagingOut, error) { 18 | tx := q.FilterQuery(db.DB) 19 | var lst = make([]model.OperateLog, 0) 20 | 21 | po, err := uv.PagingFind(tx, &lst, pi, order) 22 | return lst, po, err 23 | } 24 | -------------------------------------------------------------------------------- /console/biz/log/view/errors.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import "github.com/localhostjason/webserver/server/util/ue" 4 | 5 | const ( 6 | E_LOG_RECHARGE = "E_LOG_RECHARGE" 7 | E_LOG_OPERATE = "E_LOG_OPERATE" 8 | ) 9 | 10 | var eMap = map[string]ue.Error{ 11 | E_LOG_RECHARGE: {Code: E_LOG_RECHARGE, Desc: "获取充值记录错误", Msg: "%v"}, 12 | E_LOG_OPERATE: {Code: E_LOG_OPERATE, Desc: "获取充值记录错误", Msg: "%v"}, 13 | } 14 | 15 | func init() { 16 | ue.RegErrors(eMap) 17 | } 18 | -------------------------------------------------------------------------------- /console/biz/log/view/recharge_log.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/log/service" 5 | "github.com/gin-gonic/gin" 6 | "github.com/localhostjason/webserver/server/util/uv" 7 | ) 8 | 9 | func getRechargeLog(c *gin.Context) { 10 | var pi, order, q = &uv.PagingIn{}, &uv.Order{}, &service.RechargeQ{} 11 | uv.PQ(c, pi, order, q) 12 | lst, po, err := service.GetReChargeLogList(q, pi, order) 13 | uv.PEIf(E_LOG_RECHARGE, err) 14 | 15 | c.JSON(200, uv.PagedOut(lst, po)) 16 | } 17 | 18 | func getOperateLog(c *gin.Context) { 19 | var pi, order, q = &uv.PagingIn{}, &uv.Order{}, &service.OperateQ{} 20 | uv.PQ(c, pi, order, q) 21 | lst, po, err := service.GetOperateLogList(q, pi, order) 22 | uv.PEIf(E_LOG_RECHARGE, err) 23 | 24 | c.JSON(200, uv.PagedOut(lst, po)) 25 | } 26 | -------------------------------------------------------------------------------- /console/biz/log/view/router.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import "console/mods/ginx" 4 | 5 | func InitLogRouter(r *ginx.RouterGroup) { 6 | r.GET("充值日志", "recharge", getRechargeLog) 7 | r.GET("操作日志", "operate", getOperateLog) 8 | } 9 | -------------------------------------------------------------------------------- /console/biz/middleware/casbin_rbac.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | roleService "console/biz/user/role/service" 5 | "console/mods/casbinx" 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | func CasbinHandler(c *gin.Context) { 10 | // 获取请求的URI 11 | obj := c.Request.URL.RequestURI() 12 | // 获取请求方法 13 | act := c.Request.Method 14 | // 获取用户的角色 15 | user := roleService.GetCurrentUser(c) 16 | sub := user.Role 17 | 18 | // 判断策略中是否存在 19 | success, _ := casbinx.E.Enforce(sub, obj, act) 20 | 21 | if success { 22 | c.AbortWithStatus(403) 23 | } else { 24 | c.Next() 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /console/biz/middleware/error.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "github.com/localhostjason/webserver/server/util/ue" 6 | log "github.com/sirupsen/logrus" 7 | "net/http" 8 | "runtime/debug" 9 | "sync" 10 | ) 11 | 12 | var lock sync.Mutex 13 | 14 | // ErrorHandler remove 15 | func ErrorHandler(c *gin.Context) { 16 | defer func() { 17 | if r := recover(); r != nil { 18 | if err, ok := r.(*ue.Error); ok { 19 | c.AbortWithStatusJSON(http.StatusUnprocessableEntity, err) 20 | } else { 21 | log.Error(string(debug.Stack())) 22 | c.AbortWithStatus(http.StatusInternalServerError) 23 | } 24 | } 25 | 26 | }() 27 | lock.Lock() 28 | defer lock.Unlock() 29 | c.Next() 30 | } 31 | -------------------------------------------------------------------------------- /console/biz/middleware/operate.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "console/biz/log/model" 5 | "github.com/gin-gonic/gin" 6 | "github.com/localhostjason/webserver/server/util/ue" 7 | ) 8 | 9 | const OperateKey = "_OpLog" 10 | 11 | func OperateHandler(c *gin.Context) { 12 | c.Next() 13 | 14 | // 全局操作 入庫 15 | data, ok := c.Get(OperateKey) 16 | if ok { 17 | info, ok2 := data.(*ue.Info) 18 | if ok2 { 19 | model.CreateOperateLog(info.Action, info.Msg, c) 20 | } 21 | //fmt.Println(11111, data) 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /console/biz/static/view.go: -------------------------------------------------------------------------------- 1 | package static 2 | 3 | import ( 4 | "console/mods/pathx" 5 | "path/filepath" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func AddStaticToRouter(r *gin.Engine) { 11 | exeDir, _ := pathx.GetExeDir() 12 | 13 | r.GET("/", redirectRoot) 14 | r.Static("/static", filepath.Join(exeDir, "web", "static")) 15 | } 16 | 17 | func redirectRoot(c *gin.Context) { 18 | c.Redirect(302, "/static/index.html") 19 | } 20 | -------------------------------------------------------------------------------- /console/biz/user/auth/model/config.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "github.com/localhostjason/webserver/server/config" 4 | 5 | const _key = "auth" 6 | 7 | func regConfig() { 8 | c := ConfigAuth{ 9 | Realm: "test zone", 10 | Secret: "f450a7bdbde3416d22474b9fdc2a3636", 11 | IDKey: "username", 12 | Timeout: 12 * 3600, 13 | MaxRefresh: 3600, 14 | } 15 | _ = config.RegConfig(_key, c) 16 | } 17 | 18 | type ConfigAuth struct { 19 | Realm string `json:"realm"` 20 | Secret string `json:"secret"` 21 | IDKey string `json:"id_key"` 22 | Timeout int `json:"timeout"` 23 | MaxRefresh int `json:"max_refresh"` 24 | } 25 | 26 | func GetConfig() (ConfigAuth, error) { 27 | var c ConfigAuth 28 | err := config.GetConfig(_key, &c) 29 | return c, err 30 | } 31 | 32 | func init() { 33 | regConfig() 34 | } 35 | -------------------------------------------------------------------------------- /console/biz/user/auth/service/op_info.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/localhostjason/webserver/server/util/ue" 5 | ) 6 | 7 | const ( 8 | I_OP_LOGIN = "I_OP_LOGIN" 9 | I_OP_LOGOUT = "I_OP_LOGOUT" 10 | ) 11 | 12 | var iMap = map[string]ue.Info{ 13 | I_OP_LOGIN: {Code: I_OP_LOGIN, Action: "登录", Msg: "用户名: %v,登录系统"}, 14 | I_OP_LOGOUT: {Code: I_OP_LOGOUT, Action: "退出登录", Msg: "用户名: %v"}, 15 | } 16 | 17 | func init() { 18 | ue.RegInfos(iMap) 19 | } 20 | 21 | const operateKey = "_OpLog" 22 | -------------------------------------------------------------------------------- /console/biz/user/auth/view/auth.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/user/auth/model" 5 | "console/biz/user/auth/service" 6 | jwt "github.com/appleboy/gin-jwt/v2" 7 | "github.com/gin-gonic/gin" 8 | "time" 9 | ) 10 | 11 | func AddJwtAuth(authApi, authedApi *gin.RouterGroup) error { 12 | m, err := newAuthMiddleWare() 13 | if err != nil { 14 | return err 15 | } 16 | 17 | authApi.POST("login", m.LoginHandler) 18 | authedApi.Use(m.MiddlewareFunc()) 19 | 20 | authedApi.POST("auth/logout", m.LogoutHandler) 21 | return nil 22 | } 23 | 24 | func newAuthMiddleWare() (*jwt.GinJWTMiddleware, error) { 25 | conf, err := model.GetConfig() 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | c := authConfig(conf) 31 | return jwt.New(c) 32 | } 33 | 34 | func authConfig(conf model.ConfigAuth) *jwt.GinJWTMiddleware { 35 | c := jwt.GinJWTMiddleware{ 36 | Realm: conf.Realm, 37 | Key: []byte(conf.Secret), 38 | Timeout: time.Duration(conf.Timeout) * time.Second, 39 | MaxRefresh: time.Duration(conf.MaxRefresh) * time.Second, 40 | IdentityKey: conf.IDKey, 41 | PayloadFunc: service.PayloadFunc, 42 | IdentityHandler: service.IdHandler, 43 | Authenticator: service.Authenticator, 44 | Authorizator: service.Authorizator, 45 | Unauthorized: service.UnAuth, 46 | LoginResponse: service.LoginResponse, 47 | LogoutResponse: service.LogoutResponse, 48 | TokenLookup: "header: Authorization, query: token", 49 | TokenHeadName: "Bearer", 50 | TimeFunc: time.Now, 51 | } 52 | return &c 53 | } 54 | -------------------------------------------------------------------------------- /console/biz/user/role/model/role_map.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type RolePost struct { 4 | Role string `json:"role" binding:"required"` 5 | Path string `json:"path" binding:"required"` 6 | Method string `json:"method" binding:"required,oneof=PUT POST GET DELETE"` 7 | } 8 | -------------------------------------------------------------------------------- /console/biz/user/role/service/role.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | jwtService "console/biz/user/auth/service" 5 | "console/biz/user/users/model" 6 | "console/mods/casbinx" 7 | "errors" 8 | "github.com/gin-gonic/gin" 9 | "github.com/localhostjason/webserver/db" 10 | "gorm.io/gorm" 11 | ) 12 | 13 | func CreateRole(role, path, method string) error { 14 | if success, _ := casbinx.E.AddPolicy(role, path, method); !success { 15 | return errors.New("存在相同的策略,添加失败") 16 | } 17 | return nil 18 | } 19 | 20 | func UpdateRoleDesc(id int, desc string) error { 21 | policy, err := checkPolicyInDb(id) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | policy.Desc = desc 27 | return db.DB.Save(policy).Error 28 | } 29 | 30 | func UpdateRole(id int, role, path, method string) error { 31 | policy, err := checkPolicyInDb(id) 32 | if err != nil { 33 | return err 34 | } 35 | 36 | updated, err := casbinx.E.UpdatePolicy([]string{policy.Role, policy.Path, policy.Method}, []string{role, path, method}) 37 | if err != nil { 38 | return err 39 | } 40 | if !updated { 41 | return errors.New("更新策略失败") 42 | } 43 | return nil 44 | } 45 | 46 | func DeleteRole(id int) error { 47 | policy, err := checkPolicyInDb(id) 48 | if err != nil { 49 | return err 50 | } 51 | 52 | ok, err := casbinx.E.RemoveFilteredNamedPolicy(policy.PType, 0, policy.Role, policy.Path, policy.Method) 53 | if err != nil { 54 | return err 55 | } 56 | if !ok { 57 | return errors.New("已删除策略") 58 | } 59 | return nil 60 | } 61 | 62 | func checkPolicyInDb(id int) (*casbinx.CasbinRule, error) { 63 | var rule casbinx.CasbinRule 64 | err := db.DB.First(&rule, &casbinx.CasbinRule{ID: uint(id)}).Error 65 | if errors.Is(err, gorm.ErrRecordNotFound) { 66 | return &rule, errors.New("未找到策略") 67 | } 68 | return &rule, nil 69 | } 70 | 71 | func GetRolePolicy() [][]string { 72 | return casbinx.E.GetPolicy() 73 | } 74 | 75 | func GetCurrentUser(ctx *gin.Context) *model.User { 76 | currentUser := jwtService.CurrentUser(ctx) 77 | return currentUser 78 | } 79 | -------------------------------------------------------------------------------- /console/biz/user/role/view/errors.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import "github.com/localhostjason/webserver/server/util/ue" 4 | 5 | const ( 6 | E_USER_ROLE_GET = "E_USER_ROLE_GET" 7 | E_USER_ROLE_UPDATE = "E_USER_ROLE_UPDATE" 8 | E_USER_ROLE_DELETE = "E_USER_ROLE_DELETE" 9 | E_USER_ROLE_CREATE = "E_USER_ROLE_CREATE" 10 | ) 11 | 12 | var eMap = map[string]ue.Error{ 13 | E_USER_ROLE_GET: {Code: E_USER_ROLE_GET, Desc: "获取权限错误", Msg: "%v"}, 14 | E_USER_ROLE_UPDATE: {Code: E_USER_ROLE_UPDATE, Desc: "更新权限错误", Msg: "%v"}, 15 | E_USER_ROLE_DELETE: {Code: E_USER_ROLE_DELETE, Desc: "删除权限错误", Msg: "%v"}, 16 | E_USER_ROLE_CREATE: {Code: E_USER_ROLE_CREATE, Desc: "创建权限错误", Msg: "%v"}, 17 | } 18 | 19 | func init() { 20 | ue.RegErrors(eMap) 21 | } 22 | -------------------------------------------------------------------------------- /console/biz/user/role/view/role.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/user/role/model" 5 | "console/biz/user/role/service" 6 | "github.com/gin-gonic/gin" 7 | "github.com/localhostjason/webserver/server/util/uv" 8 | "strconv" 9 | ) 10 | 11 | func createRole(c *gin.Context) { 12 | rq := &model.RolePost{} 13 | uv.PB(c, rq) 14 | 15 | err := service.CreateRole(rq.Role, rq.Path, rq.Method) 16 | uv.PEIf(E_USER_ROLE_CREATE, err) 17 | c.Status(201) 18 | } 19 | 20 | func deleteRole(c *gin.Context) { 21 | id := c.Param("id") 22 | idInt, _ := strconv.Atoi(id) 23 | 24 | err := service.DeleteRole(idInt) 25 | uv.PEIf(E_USER_ROLE_DELETE, err) 26 | c.JSON(200, service.GetRolePolicy()) 27 | } 28 | 29 | func updateRole(c *gin.Context) { 30 | err := service.UpdateRole(1, "admin", "/api/user/password", "GET") 31 | uv.PEIf(E_USER_ROLE_UPDATE, err) 32 | c.JSON(200, service.GetRolePolicy()) 33 | } 34 | 35 | func getRole(c *gin.Context) { 36 | data := service.GetRolePolicy() 37 | c.JSON(200, data) 38 | } 39 | -------------------------------------------------------------------------------- /console/biz/user/role/view/router.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import "console/mods/ginx" 4 | 5 | func InitRoleRouter(r *ginx.RouterGroup) { 6 | r.GET("获取权限", "", getRole) 7 | r.DELETE("删除权限", ":id", deleteRole) 8 | r.PUT("更新权限", ":id", updateRole) 9 | r.POST("创建权限", "", createRole) 10 | } 11 | -------------------------------------------------------------------------------- /console/biz/user/router.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | role "console/biz/user/role/view" 5 | users "console/biz/user/users/view" 6 | "console/mods/ginx" 7 | ) 8 | 9 | func InitUserRouter(g *ginx.RouterGroup) { 10 | { 11 | role.InitRoleRouter(g.Group("用户权限", "role")) 12 | users.InitUsersRouter(g.Group("用户信息", "")) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /console/biz/user/users/model/table.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "github.com/localhostjason/webserver/db" 5 | uuid "github.com/satori/go.uuid" 6 | "golang.org/x/crypto/bcrypt" 7 | "time" 8 | ) 9 | 10 | type User struct { 11 | // 基本信息 12 | Id int64 `json:"id" gorm:"primaryKey"` 13 | Username string `json:"username" gorm:"type:string;size:64;unique;not null"` 14 | Password string `json:"-" gorm:"column:_password;type:string;size:128"` 15 | LastLoginTime *time.Time `json:"last_login_time"` 16 | Time time.Time `json:"time"` // 创建时间 17 | JwtKey uuid.UUID `json:"-" gorm:"type:string;size:128;"` // 为每个用户存一个唯一的jwt key (通用唯一识别码) 18 | 19 | Role string `json:"role"` 20 | Email string `json:"email" gorm:"type:string;size:64"` 21 | Desc string `json:"desc" gorm:"type:string;size:256"` 22 | 23 | IsSuperAdmin bool `json:"is_super_admin"` 24 | } 25 | 26 | func (u *User) SetPassword(password string) { 27 | b, err := bcrypt.GenerateFromPassword([]byte(password), 14) 28 | if err != nil { 29 | return 30 | } 31 | u.Password = string(b) 32 | } 33 | 34 | func (u *User) CheckPassword(password string) bool { 35 | err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password)) 36 | return err == nil 37 | } 38 | 39 | func (u *User) GetInfo() map[string]interface{} { 40 | return map[string]interface{}{ 41 | "username": u.Username, 42 | "role": u.Role, 43 | "email": u.Email, 44 | "desc": u.Desc, 45 | "last_login_time": u.LastLoginTime, 46 | } 47 | } 48 | 49 | func init() { 50 | db.RegTables(&User{}) 51 | } 52 | -------------------------------------------------------------------------------- /console/biz/user/users/model/user_map.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type UserInfoPut struct { 4 | Desc string `json:"desc"` 5 | } 6 | -------------------------------------------------------------------------------- /console/biz/user/users/service/user.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | roleService "console/biz/user/role/service" 5 | "console/biz/user/users/model" 6 | "github.com/gin-gonic/gin" 7 | "github.com/localhostjason/webserver/db" 8 | ) 9 | 10 | func GetUserInfo(c *gin.Context) *model.User { 11 | return roleService.GetCurrentUser(c) 12 | } 13 | 14 | func UpdateUserInfo(c *gin.Context, desc string) error { 15 | currentUser := roleService.GetCurrentUser(c) 16 | currentUser.Desc = desc 17 | 18 | return db.DB.Save(currentUser).Error 19 | } 20 | 21 | func GetUsers() []model.User { 22 | var users = make([]model.User, 0) 23 | db.DB.Find(&users) 24 | return users 25 | } 26 | -------------------------------------------------------------------------------- /console/biz/user/users/service/user_init.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "console/biz/user/users/model" 5 | "github.com/localhostjason/webserver/db" 6 | uuid "github.com/satori/go.uuid" 7 | "time" 8 | ) 9 | 10 | const ( 11 | Normal = 1 12 | Locked = -1 13 | ) 14 | 15 | const ( 16 | ADMIN = "admin" 17 | SECURITY = "security" 18 | AUDITOR = "auditor" 19 | ) 20 | 21 | const _defaultPassword = "123" 22 | 23 | func InitUser() error { 24 | now := time.Now() 25 | users := []model.User{ 26 | { 27 | Username: "admin", 28 | Role: ADMIN, 29 | Email: "", 30 | Desc: "超级管理员", 31 | Time: now, 32 | IsSuperAdmin: true, 33 | }, 34 | } 35 | 36 | for i := range users { 37 | u := &users[i] 38 | 39 | var userList []model.User 40 | if db.DB.Limit(1).Where("username = ? ", u.Username).Find(&userList); len(userList) == 0 { 41 | u.SetPassword(_defaultPassword) 42 | u.JwtKey = uuid.NewV4() 43 | db.DB.Create(u) 44 | } 45 | } 46 | return nil 47 | } 48 | 49 | func init() { 50 | db.AddInitHook(InitUser) 51 | } 52 | -------------------------------------------------------------------------------- /console/biz/user/users/view/errors.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import "github.com/localhostjason/webserver/server/util/ue" 4 | 5 | const ( 6 | E_USER_INFO_GET = "E_USER_INFO_GET" 7 | E_USER_INFO_UPDATE = "E_USER_INFO_UPDATE" 8 | E_USERS_GET = "E_USERS_GET" 9 | ) 10 | 11 | var eMap = map[string]ue.Error{ 12 | E_USER_INFO_GET: {Code: E_USER_INFO_GET, Desc: "获取个人用户错误", Msg: "%v"}, 13 | E_USER_INFO_UPDATE: {Code: E_USER_INFO_UPDATE, Desc: "更新个人用户错误", Msg: "%v"}, 14 | E_USERS_GET: {Code: E_USERS_GET, Desc: "获取用户列表错误", Msg: "%v"}, 15 | } 16 | 17 | func init() { 18 | ue.RegErrors(eMap) 19 | } 20 | -------------------------------------------------------------------------------- /console/biz/user/users/view/op_info.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/middleware" 5 | "github.com/localhostjason/webserver/server/util/ue" 6 | ) 7 | 8 | const ( 9 | I_OP = "I_OP" 10 | ) 11 | 12 | var iMap = map[string]ue.Info{ 13 | I_OP: {Code: I_OP, Action: "测试", Msg: "测试ID: %v, 测试名称:%v"}, 14 | } 15 | 16 | func init() { 17 | ue.RegInfos(iMap) 18 | } 19 | 20 | const operateKey = middleware.OperateKey 21 | -------------------------------------------------------------------------------- /console/biz/user/users/view/router.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/mods/ginx" 5 | "console/mods/pathx" 6 | "fmt" 7 | "github.com/gin-gonic/gin" 8 | "net/url" 9 | "path/filepath" 10 | ) 11 | 12 | func InitUsersRouter(r *ginx.RouterGroup) { 13 | userInfo := r.Group("用户个人信息", "info") 14 | { 15 | userInfo.GET("获取个人信息", "", getUserInfo) 16 | userInfo.PUT("更新个人信息", "", updateUserInfo) 17 | } 18 | 19 | users := r.Group("用户管理", "list") 20 | { 21 | users.GET("获取用户列表", "", getUsers) 22 | 23 | } 24 | 25 | r.GET("下载", "file", loadFile) 26 | } 27 | 28 | func loadFile(c *gin.Context) { 29 | //uv.PEIf(E_USER_INFO_UPDATE, errors.New("test error")) 30 | pwd, _ := pathx.GetExeDir() 31 | file := filepath.Join(pwd, "config", "rbac_model.conf") 32 | output := url.QueryEscape(filepath.Base(file)) 33 | c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", output)) 34 | c.Writer.Header().Add("Access-Control-Expose-Headers", "Content-Disposition") 35 | c.Writer.Header().Add("Content-Type", "application/octet-stream") 36 | c.File(file) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /console/biz/user/users/view/user.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "console/biz/user/users/model" 5 | "console/biz/user/users/service" 6 | "github.com/gin-gonic/gin" 7 | "github.com/localhostjason/webserver/server/util/uv" 8 | ) 9 | 10 | func getUserInfo(c *gin.Context) { 11 | //c.Set(operateKey, uv.OP(I_OP, "1", "hello")) 12 | 13 | data := service.GetUserInfo(c) 14 | c.JSON(200, data) 15 | } 16 | 17 | func updateUserInfo(c *gin.Context) { 18 | userQ := &model.UserInfoPut{} 19 | uv.PB(c, userQ) 20 | 21 | err := service.UpdateUserInfo(c, userQ.Desc) 22 | uv.PEIf(E_USER_INFO_UPDATE, err) 23 | c.Status(201) 24 | } 25 | 26 | func getUsers(c *gin.Context) { 27 | data := service.GetUsers() 28 | c.JSON(200, data) 29 | } 30 | -------------------------------------------------------------------------------- /console/biz/view/config.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import "github.com/localhostjason/webserver/server/config" 4 | 5 | const _key = "api" 6 | 7 | type ConfigView struct { 8 | CORS bool `json:"cors"` 9 | } 10 | 11 | func init() { 12 | c := ConfigView{CORS: true} 13 | _ = config.RegConfig(_key, c) 14 | } 15 | 16 | func GetConfig() (ConfigView, error) { 17 | var c ConfigView 18 | err := config.GetConfig(_key, &c) 19 | return c, err 20 | } 21 | -------------------------------------------------------------------------------- /console/biz/view/cors.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "github.com/gin-contrib/cors" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | func setCORS(r *gin.Engine) { 9 | config := cors.DefaultConfig() 10 | config.AddAllowHeaders("*") 11 | config.AllowOrigins = []string{"*"} 12 | config.AllowMethods = []string{"*"} 13 | r.Use(cors.New(config)) 14 | } 15 | -------------------------------------------------------------------------------- /console/biz/view/views.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | client "console/biz/client/view" 5 | dash "console/biz/dash/view" 6 | gm "console/biz/gm/view" 7 | log "console/biz/log/view" 8 | "console/biz/middleware" 9 | "console/biz/static" 10 | "console/biz/user" 11 | auth "console/biz/user/auth/view" 12 | "console/mods/ginx" 13 | "github.com/gin-gonic/gin" 14 | 15 | _ "console/biz/user/users/service" 16 | ) 17 | 18 | func SetView(r *gin.Engine) error { 19 | c, err := GetConfig() 20 | if err != nil { 21 | return err 22 | } 23 | if c.CORS { 24 | setCORS(r) 25 | } 26 | 27 | static.AddStaticToRouter(r) 28 | r.Use(middleware.OperateHandler) 29 | 30 | apiAuth := r.Group("api/auth") 31 | api := r.Group("api") 32 | 33 | err = auth.AddJwtAuth(apiAuth, api) 34 | if err != nil { 35 | return err 36 | } 37 | 38 | // load casbin 39 | api.Use(middleware.CasbinHandler, middleware.ErrorHandler) 40 | routeGroup := ginx.NewRouterGroup(api) 41 | { 42 | gm.InitGmRouter(routeGroup.Group("GM管理", "gm")) 43 | client.InitClientRouter(routeGroup.Group("客户端", "client")) 44 | 45 | user.InitUserRouter(routeGroup.Group("用户管理", "user")) 46 | log.InitLogRouter(routeGroup.Group("日志", "log")) 47 | dash.InitDashRouter(routeGroup.Group("统计", "dash")) 48 | } 49 | 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /console/cmds/args.go: -------------------------------------------------------------------------------- 1 | package cmds 2 | 3 | import ( 4 | "console/mods/game_db" 5 | "flag" 6 | "fmt" 7 | "github.com/gin-gonic/gin" 8 | "github.com/localhostjason/webserver/server" 9 | "github.com/localhostjason/webserver/server/config" 10 | ) 11 | 12 | type MainWorkFunc func(r *gin.Engine) error 13 | 14 | type MainServer struct { 15 | DefaultConfigPath string 16 | } 17 | 18 | func NewMainServer() *MainServer { 19 | return &MainServer{} 20 | } 21 | 22 | func (m *MainServer) SetServerConfigFile(file string) { 23 | m.DefaultConfigPath = file 24 | } 25 | 26 | // Run 可根据自己业务 替换扩展 27 | func (m *MainServer) Run() { 28 | setDefaultPathNoPath := server.InitDefaultServerConfigFile(m.DefaultConfigPath) 29 | 30 | configPath := flag.String("p", setDefaultPathNoPath, "path to config") 31 | initDB := flag.Bool("i", false, "int db") 32 | dumpConfig := flag.Bool("d", false, "dump default config") 33 | 34 | createPem := flag.Bool("pem", false, "create pem") 35 | 36 | // for service 37 | singleMode := flag.Bool("x", false, "start, no daemon/service mode") 38 | svcCMD := flag.String("k", "", "cmds:start|stop|status, windows: install|uninstall") 39 | 40 | flag.Parse() 41 | 42 | if err := config.SetConfigFile(*configPath); err != nil { 43 | fmt.Println("failed to set config path", *configPath, err) 44 | return 45 | } 46 | 47 | // commands 48 | 49 | if *dumpConfig { 50 | DumpDefaultConfig() 51 | return 52 | } 53 | 54 | if *createPem { 55 | if err := CreatePem(); err != nil { 56 | fmt.Println("error create pem", err) 57 | return 58 | } 59 | fmt.Println("success create publicKey.pem / private.pem") 60 | return 61 | } 62 | 63 | // DB 初始表结构和默认值 64 | if *initDB { 65 | if err := SyncDB(); err != nil { 66 | fmt.Println("error when sync db schema", err) 67 | return 68 | } 69 | if err := game_db.SyncDB(); err != nil { 70 | fmt.Println("error when sync game db schema", err) 71 | return 72 | } 73 | 74 | fmt.Println("success: sync db schema") 75 | return 76 | } 77 | 78 | RunService(*singleMode, *svcCMD) 79 | } 80 | -------------------------------------------------------------------------------- /console/cmds/config.go: -------------------------------------------------------------------------------- 1 | package cmds 2 | 3 | import ( 4 | "console/biz/client/service" 5 | "errors" 6 | "fmt" 7 | "github.com/localhostjason/webserver/db" 8 | "github.com/localhostjason/webserver/server/config" 9 | "github.com/sirupsen/logrus" 10 | ) 11 | 12 | func DumpDefaultConfig() { 13 | content, err := config.GeneDefaultConfig() 14 | if err != nil { 15 | fmt.Println("failed to generate default config") 16 | } else { 17 | fmt.Println(string(content)) 18 | } 19 | } 20 | 21 | func SyncDB() (err error) { 22 | if !db.DBEnable() { 23 | logrus.Info("no enable sql") 24 | return 25 | } 26 | err = db.Connect() 27 | if err != nil { 28 | return errors.New(fmt.Sprintf("failed to migrate:%v", err)) 29 | } 30 | err = db.Migrate() 31 | if err != nil { 32 | return 33 | } 34 | 35 | err = db.InitData() 36 | return 37 | } 38 | 39 | func AutoMigrate() (err error) { 40 | if !db.DBEnable() { 41 | return 42 | } 43 | err = db.Connect() 44 | if err != nil { 45 | return errors.New(fmt.Sprintf("failed to migrate:%v", err)) 46 | } 47 | return db.Migrate() 48 | } 49 | 50 | func CreatePem() error { 51 | rsa := service.NewRsa() 52 | return rsa.GenRsaKey(2048) 53 | } 54 | -------------------------------------------------------------------------------- /console/cmds/server.go: -------------------------------------------------------------------------------- 1 | package cmds 2 | 3 | func Run() { 4 | s := NewMainServer() 5 | s.Run() 6 | } 7 | -------------------------------------------------------------------------------- /console/cmds/service.go: -------------------------------------------------------------------------------- 1 | package cmds 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/localhostjason/webserver/svc" 7 | 8 | log "github.com/sirupsen/logrus" 9 | ) 10 | 11 | func createService(singleMode bool) (*svc.Svc, error) { 12 | prc := NewProc(singleMode) 13 | svcx, err := NewService(prc) 14 | if err != nil { 15 | return nil, errors.New(fmt.Sprintf("failed to create program:%v", err)) 16 | } 17 | return svcx, nil 18 | } 19 | 20 | func RunService(singleMode bool, cmd string) { 21 | defer func() { 22 | if r := recover(); r != nil { 23 | fmt.Println(r) 24 | } 25 | }() 26 | 27 | s, err := createService(true) 28 | if err != nil { 29 | log.Fatalln("failed to start", err) 30 | } 31 | 32 | s.RunMain(singleMode, cmd) 33 | } 34 | -------------------------------------------------------------------------------- /console/cmds/service_daemon.go: -------------------------------------------------------------------------------- 1 | package cmds 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/localhostjason/webserver/server" 7 | "github.com/localhostjason/webserver/server/config" 8 | "github.com/localhostjason/webserver/svc" 9 | "os" 10 | "path/filepath" 11 | "runtime" 12 | ) 13 | 14 | const _groupService = "service" 15 | 16 | type ServiceConfig struct { 17 | PidFile string `json:"pid_file"` 18 | DaemonLog string `json:"daemon_log"` 19 | } 20 | 21 | func getConf() (ServiceConfig, error) { 22 | var c ServiceConfig 23 | err := config.GetConfig(_groupService, &c) 24 | if err != nil { 25 | return c, err 26 | 27 | } 28 | confWebServer, err := server.GetConfig() 29 | if err != nil { 30 | return c, err 31 | } 32 | logPath := confWebServer.LogPath 33 | c.PidFile = filepath.Join(logPath, c.PidFile) 34 | c.DaemonLog = filepath.Join(logPath, c.DaemonLog) 35 | 36 | if err := os.MkdirAll(logPath, 0755); err != nil { 37 | return c, fmt.Errorf("failed to create log dir %s", logPath) 38 | } 39 | 40 | return c, nil 41 | } 42 | 43 | func init() { 44 | c := ServiceConfig{ 45 | PidFile: "console.pid", 46 | DaemonLog: "daemon.log", 47 | } 48 | _ = config.RegConfig(_groupService, c) 49 | } 50 | 51 | func NewService(prc *MainProc) (*svc.Svc, error) { 52 | if runtime.GOOS == "windows" { 53 | svcName := "center" 54 | svcDescription := "center 服务" 55 | return svc.NewSvc(svcName, svcDescription, prc), nil 56 | } else { 57 | c, err := getConf() 58 | if err != nil { 59 | return nil, errors.New(fmt.Sprintf("failed to get daemon config:%v", err)) 60 | } 61 | return svc.NewSvc(c.PidFile, c.DaemonLog, prc), nil 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /console/config/rbac_model.conf: -------------------------------------------------------------------------------- 1 | [request_definition] 2 | r = sub,obj,act 3 | 4 | [policy_definition] 5 | p = sub,obj,act 6 | 7 | [role_definition] 8 | g = _, _ 9 | 10 | [policy_effect] 11 | e = some(where (p.eft == allow)) 12 | 13 | [matchers] 14 | m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && r.act == p.act 15 | -------------------------------------------------------------------------------- /console/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "console/cmds" 5 | ) 6 | 7 | func main() { 8 | cmds.Run() 9 | } 10 | -------------------------------------------------------------------------------- /console/mods/casbinx/casbin.go: -------------------------------------------------------------------------------- 1 | package casbinx 2 | 3 | import ( 4 | "github.com/casbin/casbin/v2" 5 | gormadapter "github.com/casbin/gorm-adapter/v3" 6 | "github.com/localhostjason/webserver/db" 7 | "github.com/localhostjason/webserver/util" 8 | ) 9 | 10 | var E *casbin.Enforcer // 作为全局访问 11 | 12 | type CasBin struct { 13 | File string 14 | } 15 | 16 | func NewCasBin() *CasBin { 17 | cfg, _ := GetCasbinConfig() 18 | return &CasBin{File: cfg.File} 19 | } 20 | 21 | func (c *CasBin) Run() error { 22 | if !util.PathExists(c.File) { 23 | createCasbinConfigFile(c.File) 24 | } 25 | 26 | dbx := db.DB 27 | adapter, err := gormadapter.NewAdapterByDBWithCustomTable(dbx, &CasbinRule{}) 28 | 29 | var enforcer *casbin.Enforcer 30 | enforcer, err = casbin.NewEnforcer(c.File, adapter) 31 | 32 | err = enforcer.LoadPolicy() 33 | if err != nil { 34 | return err 35 | } 36 | E = enforcer 37 | return nil 38 | } 39 | 40 | func (c *CasBin) Clear(v int, p ...string) bool { 41 | ok, _ := E.RemoveFilteredPolicy(v, p...) 42 | return ok 43 | } 44 | 45 | func (c *CasBin) Get() [][]string { 46 | policy := E.GetPolicy() 47 | return policy 48 | } 49 | -------------------------------------------------------------------------------- /console/mods/casbinx/config.go: -------------------------------------------------------------------------------- 1 | package casbinx 2 | 3 | import ( 4 | "console/mods/pathx" 5 | "github.com/localhostjason/webserver/server/config" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | const _casbinKey = "casbin" 11 | const casbinText = `[request_definition] 12 | r = sub,obj,act 13 | 14 | [policy_definition] 15 | p = sub,obj,act 16 | 17 | [role_definition] 18 | g = _, _ 19 | 20 | [policy_effect] 21 | e = some(where (p.eft == allow)) 22 | 23 | [matchers] 24 | m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && r.act == p.act 25 | ` 26 | 27 | func regCasbinConfig() { 28 | extPath, _ := pathx.GetExeDir() 29 | file := filepath.Join(extPath, "config", "rbac_model.conf") 30 | 31 | c := CasbinConfig{ 32 | File: file, 33 | } 34 | _ = config.RegConfig(_casbinKey, c) 35 | } 36 | 37 | type CasbinConfig struct { 38 | File string `json:"file"` 39 | } 40 | 41 | func createCasbinConfigFile(file string) { 42 | _ = os.WriteFile(file, []byte(casbinText), os.ModePerm) 43 | } 44 | 45 | func GetCasbinConfig() (CasbinConfig, error) { 46 | var c CasbinConfig 47 | err := config.GetConfig(_casbinKey, &c) 48 | return c, err 49 | } 50 | 51 | func init() { 52 | regCasbinConfig() 53 | } 54 | -------------------------------------------------------------------------------- /console/mods/casbinx/table.go: -------------------------------------------------------------------------------- 1 | package casbinx 2 | 3 | type CasbinRule struct { 4 | ID uint `json:"id" gorm:"primaryKey;autoIncrement"` 5 | PType string `json:"p_type" gorm:"column:ptype" description:"策略类型"` 6 | Role string `json:"role" gorm:"column:v0" description:"角色"` 7 | Path string `json:"path" gorm:"column:v1" description:"api路径 obj"` 8 | Method string `json:"method" gorm:"column:v2" description:"访问方法 act"` 9 | V3 string `json:"-" gorm:"column:v3"` 10 | V4 string `json:"-" gorm:"column:v4"` 11 | V5 string `json:"-" gorm:"column:v5" ` 12 | V6 string `json:"-" gorm:"column:v6" ` 13 | V7 string `json:"-" gorm:"column:v7" ` 14 | ApiName string `json:"api_name" gorm:"-"` 15 | GroupName string `json:"group_name" gorm:"-"` 16 | Desc string `json:"desc" description:"策略描述"` 17 | } 18 | -------------------------------------------------------------------------------- /console/mods/game_db/config.go: -------------------------------------------------------------------------------- 1 | package game_db 2 | 3 | import "github.com/localhostjason/webserver/server/config" 4 | 5 | const _key = "game_db" 6 | 7 | type MysqlDBConfig struct { 8 | Key string `json:"key"` 9 | User string `json:"user"` 10 | Password string `json:"password"` 11 | Host string `json:"host"` 12 | Port int `json:"port"` 13 | DB string `json:"db"` 14 | Charset string `json:"charset"` 15 | Timeout int `json:"timeout"` 16 | MultiStatements bool `json:"multi_statements"` 17 | Debug bool `json:"debug"` 18 | } 19 | 20 | type SqliteDBConfig struct { 21 | Key string `json:"key"` 22 | DbFile string `json:"db_file"` 23 | Debug bool `json:"debug"` 24 | } 25 | 26 | type DbConfig struct { 27 | Enable bool `json:"enable"` 28 | Mysql []MysqlDBConfig `json:"mysql"` 29 | Sqlite []SqliteDBConfig `json:"sqlite"` 30 | } 31 | 32 | func init() { 33 | mc := MysqlDBConfig{ 34 | Key: "TestMysql1", 35 | User: "root", 36 | Password: "123456", 37 | Host: "127.0.0.1", 38 | Port: 3306, 39 | DB: "test", 40 | Charset: "utf8mb4", 41 | MultiStatements: false, 42 | Timeout: 5, 43 | Debug: false, 44 | } 45 | 46 | sc := SqliteDBConfig{ 47 | Key: "TestSqlite1", 48 | DbFile: "data/data.db", 49 | Debug: false, 50 | } 51 | 52 | c := DbConfig{ 53 | Enable: true, 54 | Mysql: []MysqlDBConfig{mc}, 55 | Sqlite: []SqliteDBConfig{sc}, 56 | } 57 | _ = config.RegConfig(_key, c) 58 | } 59 | 60 | func getDbConfig() DbConfig { 61 | var c DbConfig 62 | _ = config.GetConfig(_key, &c) 63 | return c 64 | } 65 | -------------------------------------------------------------------------------- /console/mods/game_db/db.go: -------------------------------------------------------------------------------- 1 | package game_db 2 | 3 | import ( 4 | log "github.com/sirupsen/logrus" 5 | "gorm.io/gorm" 6 | ) 7 | 8 | var DBPools = new(DBPool) 9 | 10 | func Connect() error { 11 | c := getDbConfig() 12 | if !c.Enable { 13 | return nil 14 | } 15 | 16 | if err := ConnectWithMysqlConfig(c.Mysql); err != nil { 17 | return err 18 | } 19 | 20 | if err := ConnectWithSqliteConfig(c.Sqlite); err != nil { 21 | return err 22 | } 23 | return nil 24 | } 25 | 26 | func DBEnable() bool { 27 | c := getDbConfig() 28 | return c.Enable 29 | } 30 | 31 | var tableModels = make(map[any][]interface{}) 32 | 33 | // Migrate 初始化或升级表结构 34 | func Migrate() error { 35 | DBPools.Range(func(k, db any) bool { 36 | if err := db.(*gorm.DB).AutoMigrate(tableModels[k]...); err != nil { 37 | log.Fatalln("failed to migrate database:", k, ",err:", err) 38 | return false 39 | } 40 | return true 41 | }) 42 | 43 | return nil 44 | } 45 | 46 | // RegTables 其他模块注册需要访问的表, 会被自动创建 47 | func RegTables(k any, tables ...interface{}) { 48 | tableModels[k] = append(tableModels[k], tables...) 49 | } 50 | 51 | type InitGameDataHandler func() error 52 | 53 | var _initGameHooks []InitGameDataHandler 54 | 55 | // AddInitHook db连接后执行的函数, 可用于初始化数据等 56 | func AddInitHook(h InitGameDataHandler) { 57 | _initGameHooks = append(_initGameHooks, h) 58 | } 59 | 60 | func InitData() error { 61 | for _, h := range _initGameHooks { 62 | if err := h(); err != nil { 63 | return err 64 | } 65 | } 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /console/mods/game_db/db_mysql.go: -------------------------------------------------------------------------------- 1 | // Package game_db Package db 处理数据库连接信息,实现Model对象的存储读取 2 | package game_db 3 | 4 | import ( 5 | "errors" 6 | "fmt" 7 | log "github.com/sirupsen/logrus" 8 | "sync" 9 | 10 | "gorm.io/driver/mysql" 11 | "gorm.io/gorm" 12 | "gorm.io/gorm/schema" 13 | ) 14 | 15 | // ConnectWithMysqlConfig 连接,检验配置是否正确 16 | func ConnectWithMysqlConfig(cfgs []MysqlDBConfig) error { 17 | if len(cfgs) == 0 { 18 | return nil 19 | } 20 | 21 | var wg = &sync.WaitGroup{} 22 | for _, c := range cfgs { 23 | wg.Add(1) 24 | 25 | go func(c MysqlDBConfig) { 26 | defer wg.Done() 27 | 28 | err := connectMysqlOne(c) 29 | if err != nil { 30 | log.Fatal(err) 31 | } 32 | }(c) 33 | 34 | } 35 | wg.Wait() 36 | return nil 37 | } 38 | 39 | func connectMysqlOne(c MysqlDBConfig) error { 40 | multiStatements := "false" 41 | if c.MultiStatements { 42 | multiStatements = "true" 43 | } 44 | dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?multiStatements=%s&charset=%s&parseTime=True&loc=Local&timeout=%ds&allowAllFiles=true", 45 | c.User, c.Password, c.Host, c.Port, c.DB, multiStatements, c.Charset, c.Timeout) 46 | db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ 47 | FullSaveAssociations: true, 48 | SkipDefaultTransaction: true, 49 | NamingStrategy: schema.NamingStrategy{SingularTable: true}, 50 | }) 51 | 52 | if c.Debug { 53 | db = db.Debug() 54 | } 55 | 56 | if err != nil { 57 | return errors.New(fmt.Sprintf("failed to connect databse %s:%v", dsn, err)) 58 | } 59 | 60 | DBPools.Add(c.Key, db) 61 | return nil 62 | } 63 | 64 | // Close todo 关闭db连接 65 | func Close() error { 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /console/mods/game_db/db_sqlite.go: -------------------------------------------------------------------------------- 1 | package game_db 2 | 3 | import ( 4 | "console/mods/pathx" 5 | "errors" 6 | "fmt" 7 | "github.com/localhostjason/webserver/util" 8 | log "github.com/sirupsen/logrus" 9 | "gorm.io/driver/sqlite" 10 | "gorm.io/gorm" 11 | "gorm.io/gorm/schema" 12 | "os" 13 | "path/filepath" 14 | "sync" 15 | ) 16 | 17 | // ConnectWithSqliteConfig 连接,检验配置是否正确 18 | func ConnectWithSqliteConfig(cfgs []SqliteDBConfig) error { 19 | if len(cfgs) == 0 { 20 | return nil 21 | } 22 | 23 | var wg = &sync.WaitGroup{} 24 | 25 | for _, c := range cfgs { 26 | wg.Add(1) 27 | 28 | go func(c SqliteDBConfig) { 29 | defer wg.Done() 30 | err := connectSqliteOne(c) 31 | if err != nil { 32 | log.Fatal(err) 33 | } 34 | }(c) 35 | 36 | } 37 | 38 | wg.Wait() 39 | return nil 40 | } 41 | 42 | func connectSqliteOne(c SqliteDBConfig) error { 43 | var dbFile string 44 | if filepath.IsAbs(c.DbFile) { 45 | dbFile = c.DbFile 46 | } else { 47 | exePath, _ := pathx.GetExeDir() 48 | dbFile = filepath.Join(exePath, c.DbFile) 49 | } 50 | 51 | path, _ := filepath.Split(dbFile) 52 | if !util.PathExists(path) { 53 | _ = os.MkdirAll(path, os.ModePerm) 54 | } 55 | 56 | db, err := gorm.Open(sqlite.Open(dbFile), &gorm.Config{ 57 | FullSaveAssociations: true, 58 | SkipDefaultTransaction: true, 59 | NamingStrategy: schema.NamingStrategy{SingularTable: true}, 60 | }) 61 | if err != nil { 62 | return errors.New(fmt.Sprintf("db file:%s, err:%s", dbFile, err)) 63 | } 64 | 65 | if c.Debug { 66 | db = db.Debug() 67 | } 68 | 69 | if err != nil { 70 | return errors.New(fmt.Sprintf("failed to connect databse %s:%v", c.DbFile, err)) 71 | } 72 | DBPools.Add(c.Key, db) 73 | return nil 74 | } 75 | -------------------------------------------------------------------------------- /console/mods/game_db/migrate.go: -------------------------------------------------------------------------------- 1 | package game_db 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/sirupsen/logrus" 7 | ) 8 | 9 | func SyncDB() (err error) { 10 | if !DBEnable() { 11 | logrus.Info("no enable sql") 12 | return 13 | } 14 | 15 | err = Connect() 16 | if err != nil { 17 | return errors.New(fmt.Sprintf("failed to migrate:%v", err)) 18 | } 19 | err = Migrate() 20 | if err != nil { 21 | return 22 | } 23 | 24 | err = InitData() 25 | return 26 | } 27 | 28 | func AutoMigrate() (err error) { 29 | if !DBEnable() { 30 | return 31 | } 32 | err = Connect() 33 | if err != nil { 34 | return errors.New(fmt.Sprintf("failed to migrate:%v", err)) 35 | } 36 | return Migrate() 37 | } 38 | -------------------------------------------------------------------------------- /console/mods/game_db/model.go: -------------------------------------------------------------------------------- 1 | package game_db 2 | 3 | import ( 4 | "gorm.io/gorm" 5 | "sync" 6 | ) 7 | 8 | // DBPool 定义一个类,继承字典(异步,带锁的),一会存入db对象 { key : db } 9 | type DBPool struct { 10 | sync.Map 11 | } 12 | 13 | // Get 为这个 类<对象池> 添加方法,分别为 Get,Add,Del 14 | func (p *DBPool) Get(name string) *gorm.DB { 15 | if s, ok := p.Load(name); ok { 16 | return s.(*gorm.DB) 17 | } else { 18 | return nil 19 | } 20 | } 21 | 22 | func (p *DBPool) Add(name string, tx *gorm.DB) { 23 | p.Store(name, tx) 24 | } 25 | 26 | func (p *DBPool) Del(name string) { 27 | p.Delete(name) 28 | } 29 | -------------------------------------------------------------------------------- /console/mods/ginx/table.go: -------------------------------------------------------------------------------- 1 | package ginx 2 | 3 | import "github.com/localhostjason/webserver/db" 4 | 5 | type Authz struct { 6 | ID int `json:"id"` 7 | GroupName string `json:"group_name"` 8 | ApiName string `json:"api_name"` 9 | Url string `json:"url" description:"对象 obj"` 10 | Method string `json:"method" description:"act"` 11 | } 12 | 13 | func init() { 14 | db.RegTables(&Authz{}) 15 | } 16 | -------------------------------------------------------------------------------- /console/mods/pathx/path.go: -------------------------------------------------------------------------------- 1 | package pathx 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "path/filepath" 7 | "runtime" 8 | "strings" 9 | ) 10 | 11 | func GetExeDir() (string, error) { 12 | exePath, err := os.Executable() 13 | if err != nil { 14 | return "", err 15 | } 16 | res := filepath.Dir(exePath) 17 | 18 | if strings.Contains(exePath, getTmpDir()) { 19 | // run 模式下,确在当前程序入口目录 20 | return os.Getwd() 21 | } 22 | return res, nil 23 | } 24 | 25 | func getTmpDir() string { 26 | dir := os.Getenv("TEMP") 27 | if dir == "" { 28 | dir = os.Getenv("TMP") 29 | } 30 | return dir 31 | } 32 | 33 | // 获取当前执行文件绝对路径(go run) 34 | func getCurrentAbPathByCaller() string { 35 | var abPath string 36 | _, filename, _, ok := runtime.Caller(0) 37 | if ok { 38 | abPath = path.Dir(filename) 39 | } 40 | return abPath 41 | } 42 | -------------------------------------------------------------------------------- /console/mods/readme.md: -------------------------------------------------------------------------------- 1 | # 插件/库 2 | 3 | 1. 底层函数 4 | 2. 引用外部组件或者库 5 | 6 | 7 | -------------------------------------------------------------------------------- /console/source/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAxCN29bJSzKc1CMX0LUFBtvH12BohqucOLKzwx0olNAVdbNNR 3 | H8p2RAfvrV4QVh2KvxdrUmROVX1L+2sOl0H6zjR2UlnLeEEwls/rK1Al4saorzbU 4 | 5yCsg8zlEK6f+krgTGbEbwbsWv/i7UQTD3nAbZdK4eORpOuiMejupjnH4OE8rsMc 5 | msp1H93j56xOf/63ow7I4CcbGBFVAXOgDaao/8YSWZbyfMNqzuxS9EzHQfuIduEl 6 | e6oX8jOPvNP/1D5lgE4ucrv4pmJiVGuxfuOsI5EfYw0YPryehH+PasGzXvI61ysm 7 | E6f0TSCrKsmL9TjAccFjBsd0fH9oXzP80yIpjwIDAQABAoIBAB31NMROWms71tPi 8 | OGt5HiptRpmdVCsgY3/bYmNuJcSOVTi8BhYO/IVjmO4oAeLFXF3Xm+LXw0c3fhWG 9 | wpHD2CUKyk/Fu1hAzMUcONVCxqaepUEt5NLwoKj48LvdkD3QlfXVdIdozU0Q7H5E 10 | +YxRklyq0RszgRlpjDqHU3w8MxVbzUYhtPd58WdY6j0S+Auhkju7key+MHTPqzRK 11 | ZCxrEkL6nMl9R6GXmVWGZFw5O00usnrTsDVETd1pw6kezeqPLC1Dgz38zBBAuusv 12 | hbnrq0haS/jQmlbYMBtikJDtsY0TcLt1bBdq9q/HHbkiY3lyJbePw613+/lvaFvT 13 | oHtbLIECgYEA2PLaTQjSGXGTdhYUQnaM4I43WsUQlrUYHU5fwVsVDJEacfOBJrLp 14 | nySvI9Z3GasJALQHXftYtvWdGJItwjRNX4lLkatVu/MGeggck36xEdeAMOFjMIsX 15 | 9J/HA8mX9Qf5DFTkdomJxwGXHz1ichdz4Ha8L0wTOJl/7inwt9FIBO8CgYEA53Gq 16 | 12q3OR9SUQWvCQ4O0cecniBnjrFuwdqGEswpm6nt+Pxo73fT48dMbeldzB1q8X97 17 | vcIvO88GC3nDxztAscNBaQdvzPb1HpG07mU7a7MxZyNhtFzHa6f9cbXE98+13+vX 18 | 6Ka79+2H3xbHgEVAukqR7ph+faC5j+otN216ZWECgYEAirqhBenCECsklLqBsg6E 19 | /4NxukWR2g1rojHf4ZEQ4LxZIM0JpWl7Ix0eMdiOyIcqdpyoqVx02motTu0K/cjc 20 | QV9WR4w8grdhSN+vBlJZgINBogA+oWgQpYkWhkF/Pl0e0NfoUDSbOfq2XG+waCy/ 21 | GKZUqBoJoIPn3rBLEgBuAVkCgYA0XXd1/eMuvXN2eX684b1goXVCIbrMgkC5A6RK 22 | JH9VhQEe0J09cTMz2ifkxmQ+hnln4pwwtvrQ4WpQtmAhd7qPfcoS5WfaTBXxsK3r 23 | MmRbXdPTriGxGTzVktC5JZNHLmvMGiRjszXcRpXzV8gTsZePjset4DreWbsiYK2S 24 | WObUgQKBgGPHucZ8cNNRCadyfnHPTJqvychAbSQKzy3BUSNrXvGWpgKs38Zs0SRJ 25 | tnYjxByuzwFLhx9kmmAdBoR6aS6JLQOUsTXvrWNvrNX5CFHLO2F/iCFFd0SWIXvz 26 | JWlkbaakjNZX16xEile5xXjc2lJsmajwkykG6fm+yvjVHQugyYOs 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /console/source/publickey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCN29bJSzKc1CMX0LUFB 3 | tvH12BohqucOLKzwx0olNAVdbNNRH8p2RAfvrV4QVh2KvxdrUmROVX1L+2sOl0H6 4 | zjR2UlnLeEEwls/rK1Al4saorzbU5yCsg8zlEK6f+krgTGbEbwbsWv/i7UQTD3nA 5 | bZdK4eORpOuiMejupjnH4OE8rsMcmsp1H93j56xOf/63ow7I4CcbGBFVAXOgDaao 6 | /8YSWZbyfMNqzuxS9EzHQfuIduEle6oX8jOPvNP/1D5lgE4ucrv4pmJiVGuxfuOs 7 | I5EfYw0YPryehH+PasGzXvI61ysmE6f0TSCrKsmL9TjAccFjBsd0fH9oXzP80yIp 8 | jwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /dist/.gitignore: -------------------------------------------------------------------------------- 1 | /org 2 | /.vscode 3 | 4 | 5 | .vscode/* 6 | !.vscode/settings.json 7 | !.vscode/tasks.json 8 | !.vscode/launch.json 9 | !.vscode/extensions.json 10 | !.vscode/*.code-snippets 11 | 12 | # Local History for Visual Studio Code 13 | .history/ 14 | 15 | # Built Visual Studio Code Extensions 16 | *.vsix 17 | .idea 18 | 19 | data 20 | log 21 | -------------------------------------------------------------------------------- /dist/config/rbac_model.conf: -------------------------------------------------------------------------------- 1 | [request_definition] 2 | r = sub,obj,act 3 | 4 | [policy_definition] 5 | p = sub,obj,act 6 | 7 | [role_definition] 8 | g = _, _ 9 | 10 | [policy_effect] 11 | e = some(where (p.eft == allow)) 12 | 13 | [matchers] 14 | m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && r.act == p.act 15 | -------------------------------------------------------------------------------- /dist/main.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localhostjason/dnf-console/cd7cae945e9d25219aef516550e1d63e655f4952/dist/main.exe -------------------------------------------------------------------------------- /dist/source/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAxCN29bJSzKc1CMX0LUFBtvH12BohqucOLKzwx0olNAVdbNNR 3 | H8p2RAfvrV4QVh2KvxdrUmROVX1L+2sOl0H6zjR2UlnLeEEwls/rK1Al4saorzbU 4 | 5yCsg8zlEK6f+krgTGbEbwbsWv/i7UQTD3nAbZdK4eORpOuiMejupjnH4OE8rsMc 5 | msp1H93j56xOf/63ow7I4CcbGBFVAXOgDaao/8YSWZbyfMNqzuxS9EzHQfuIduEl 6 | e6oX8jOPvNP/1D5lgE4ucrv4pmJiVGuxfuOsI5EfYw0YPryehH+PasGzXvI61ysm 7 | E6f0TSCrKsmL9TjAccFjBsd0fH9oXzP80yIpjwIDAQABAoIBAB31NMROWms71tPi 8 | OGt5HiptRpmdVCsgY3/bYmNuJcSOVTi8BhYO/IVjmO4oAeLFXF3Xm+LXw0c3fhWG 9 | wpHD2CUKyk/Fu1hAzMUcONVCxqaepUEt5NLwoKj48LvdkD3QlfXVdIdozU0Q7H5E 10 | +YxRklyq0RszgRlpjDqHU3w8MxVbzUYhtPd58WdY6j0S+Auhkju7key+MHTPqzRK 11 | ZCxrEkL6nMl9R6GXmVWGZFw5O00usnrTsDVETd1pw6kezeqPLC1Dgz38zBBAuusv 12 | hbnrq0haS/jQmlbYMBtikJDtsY0TcLt1bBdq9q/HHbkiY3lyJbePw613+/lvaFvT 13 | oHtbLIECgYEA2PLaTQjSGXGTdhYUQnaM4I43WsUQlrUYHU5fwVsVDJEacfOBJrLp 14 | nySvI9Z3GasJALQHXftYtvWdGJItwjRNX4lLkatVu/MGeggck36xEdeAMOFjMIsX 15 | 9J/HA8mX9Qf5DFTkdomJxwGXHz1ichdz4Ha8L0wTOJl/7inwt9FIBO8CgYEA53Gq 16 | 12q3OR9SUQWvCQ4O0cecniBnjrFuwdqGEswpm6nt+Pxo73fT48dMbeldzB1q8X97 17 | vcIvO88GC3nDxztAscNBaQdvzPb1HpG07mU7a7MxZyNhtFzHa6f9cbXE98+13+vX 18 | 6Ka79+2H3xbHgEVAukqR7ph+faC5j+otN216ZWECgYEAirqhBenCECsklLqBsg6E 19 | /4NxukWR2g1rojHf4ZEQ4LxZIM0JpWl7Ix0eMdiOyIcqdpyoqVx02motTu0K/cjc 20 | QV9WR4w8grdhSN+vBlJZgINBogA+oWgQpYkWhkF/Pl0e0NfoUDSbOfq2XG+waCy/ 21 | GKZUqBoJoIPn3rBLEgBuAVkCgYA0XXd1/eMuvXN2eX684b1goXVCIbrMgkC5A6RK 22 | JH9VhQEe0J09cTMz2ifkxmQ+hnln4pwwtvrQ4WpQtmAhd7qPfcoS5WfaTBXxsK3r 23 | MmRbXdPTriGxGTzVktC5JZNHLmvMGiRjszXcRpXzV8gTsZePjset4DreWbsiYK2S 24 | WObUgQKBgGPHucZ8cNNRCadyfnHPTJqvychAbSQKzy3BUSNrXvGWpgKs38Zs0SRJ 25 | tnYjxByuzwFLhx9kmmAdBoR6aS6JLQOUsTXvrWNvrNX5CFHLO2F/iCFFd0SWIXvz 26 | JWlkbaakjNZX16xEile5xXjc2lJsmajwkykG6fm+yvjVHQugyYOs 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /dist/source/publickey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCN29bJSzKc1CMX0LUFB 3 | tvH12BohqucOLKzwx0olNAVdbNNRH8p2RAfvrV4QVh2KvxdrUmROVX1L+2sOl0H6 4 | zjR2UlnLeEEwls/rK1Al4saorzbU5yCsg8zlEK6f+krgTGbEbwbsWv/i7UQTD3nA 5 | bZdK4eORpOuiMejupjnH4OE8rsMcmsp1H93j56xOf/63ow7I4CcbGBFVAXOgDaao 6 | /8YSWZbyfMNqzuxS9EzHQfuIduEle6oX8jOPvNP/1D5lgE4ucrv4pmJiVGuxfuOs 7 | I5EfYw0YPryehH+PasGzXvI61ysmE6f0TSCrKsmL9TjAccFjBsd0fH9oXzP80yIp 8 | jwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /dist/web/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localhostjason/dnf-console/cd7cae945e9d25219aef516550e1d63e655f4952/dist/web/static/favicon.ico -------------------------------------------------------------------------------- /dist/web/static/index.html: -------------------------------------------------------------------------------- 1 |