| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- package admin
- import (
- "bytes"
- "encoding/base64"
- "encoding/json"
- "fmt"
- "io"
- "net/http"
- "net/url"
- "strconv"
- "strings"
- "text/template"
- "time"
- "github.com/bjdgyc/anylink/base"
- "github.com/bjdgyc/anylink/dbdata"
- "github.com/bjdgyc/anylink/sessdata"
- "github.com/skip2/go-qrcode"
- )
- func UserList(w http.ResponseWriter, r *http.Request) {
- _ = r.ParseForm()
- prefix := r.FormValue("prefix")
- pageS := r.FormValue("page")
- page, _ := strconv.Atoi(pageS)
- if page < 1 {
- page = 1
- }
- var (
- pageSize = dbdata.PageSize
- count int
- datas []dbdata.User
- err error
- )
- // 查询前缀匹配
- if len(prefix) > 0 {
- count = dbdata.CountPrefix("username", prefix, &dbdata.User{})
- err = dbdata.Prefix("username", prefix, &datas, pageSize, 1)
- } else {
- count = dbdata.CountAll(&dbdata.User{})
- err = dbdata.Find(&datas, pageSize, page)
- }
- if err != nil && !dbdata.CheckErrNotFound(err) {
- RespError(w, RespInternalErr, err)
- return
- }
- data := map[string]interface{}{
- "count": count,
- "page_size": pageSize,
- "datas": datas,
- }
- RespSucess(w, data)
- }
- func UserDetail(w http.ResponseWriter, r *http.Request) {
- _ = r.ParseForm()
- idS := r.FormValue("id")
- id, _ := strconv.Atoi(idS)
- if id < 1 {
- RespError(w, RespParamErr, "用户名错误")
- return
- }
- var user dbdata.User
- err := dbdata.One("Id", id, &user)
- if err != nil {
- RespError(w, RespInternalErr, err)
- return
- }
- RespSucess(w, user)
- }
- func UserSet(w http.ResponseWriter, r *http.Request) {
- _ = r.ParseForm()
- body, err := io.ReadAll(r.Body)
- if err != nil {
- RespError(w, RespInternalErr, err)
- return
- }
- defer r.Body.Close()
- data := &dbdata.User{}
- err = json.Unmarshal(body, data)
- if err != nil {
- RespError(w, RespInternalErr, err)
- return
- }
- err = dbdata.SetUser(data)
- if err != nil {
- RespError(w, RespInternalErr, err)
- return
- }
- // 发送邮件
- if data.SendEmail {
- err = userAccountMail(data)
- if err != nil {
- RespError(w, RespInternalErr, err)
- return
- }
- }
- //修改用户资料后执行过期用户检测
- sessdata.CloseUserLimittimeSession()
- RespSucess(w, nil)
- }
- func UserDel(w http.ResponseWriter, r *http.Request) {
- _ = r.ParseForm()
- idS := r.FormValue("id")
- id, _ := strconv.Atoi(idS)
- if id < 1 {
- RespError(w, RespParamErr, "用户id错误")
- return
- }
- user := dbdata.User{Id: id}
- err := dbdata.Del(&user)
- if err != nil {
- RespError(w, RespInternalErr, err)
- return
- }
- RespSucess(w, nil)
- }
- func UserOtpQr(w http.ResponseWriter, r *http.Request) {
- _ = r.ParseForm()
- b64S := r.FormValue("b64")
- idS := r.FormValue("id")
- id, _ := strconv.Atoi(idS)
- var b64 bool
- if b64S == "1" {
- b64 = true
- }
- data, err := userOtpQr(id, b64)
- if err != nil {
- base.Error(err)
- }
- io.WriteString(w, data)
- }
- func userOtpQr(uid int, b64 bool) (string, error) {
- var user dbdata.User
- err := dbdata.One("Id", uid, &user)
- if err != nil {
- return "", err
- }
- issuer := url.QueryEscape(base.Cfg.Issuer)
- qrstr := fmt.Sprintf("otpauth://totp/%s:%s?issuer=%s&secret=%s", issuer, user.Email, issuer, user.OtpSecret)
- qr, _ := qrcode.New(qrstr, qrcode.High)
- if b64 {
- data, err := qr.PNG(300)
- if err != nil {
- return "", err
- }
- s := base64.StdEncoding.EncodeToString(data)
- return s, nil
- }
- buf := bytes.NewBuffer(nil)
- err = qr.Write(300, buf)
- return buf.String(), err
- }
- // 在线用户
- func UserOnline(w http.ResponseWriter, r *http.Request) {
- datas := sessdata.OnlineSess()
- data := map[string]interface{}{
- "count": len(datas),
- "page_size": dbdata.PageSize,
- "datas": datas,
- }
- RespSucess(w, data)
- }
- func UserOffline(w http.ResponseWriter, r *http.Request) {
- _ = r.ParseForm()
- token := r.FormValue("token")
- sessdata.CloseSess(token, dbdata.UserLogoutAdmin)
- RespSucess(w, nil)
- }
- func UserReline(w http.ResponseWriter, r *http.Request) {
- _ = r.ParseForm()
- token := r.FormValue("token")
- sessdata.CloseCSess(token)
- RespSucess(w, nil)
- }
- type userAccountMailData struct {
- Issuer string
- LinkAddr string
- Group string
- Username string
- PinCode string
- OtpImg string
- OtpImgBase64 string
- }
- func userAccountMail(user *dbdata.User) error {
- // 平台通知
- htmlBody := `
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
- <title>Hello AnyLink!</title>
- </head>
- <body>
- %s
- </body>
- </html>
- `
- dataOther := &dbdata.SettingOther{}
- err := dbdata.SettingGet(dataOther)
- if err != nil {
- base.Error(err)
- return err
- }
- htmlBody = fmt.Sprintf(htmlBody, dataOther.AccountMail)
- // fmt.Println(htmlBody)
- // token有效期3天
- expiresAt := time.Now().Unix() + 3600*24*3
- jwtData := map[string]interface{}{"id": user.Id}
- tokenString, err := SetJwtData(jwtData, expiresAt)
- if err != nil {
- return err
- }
- setting := &dbdata.SettingOther{}
- err = dbdata.SettingGet(setting)
- if err != nil {
- base.Error(err)
- return err
- }
- otpData, _ := userOtpQr(user.Id, true)
- data := userAccountMailData{
- LinkAddr: setting.LinkAddr,
- Group: strings.Join(user.Groups, ","),
- Username: user.Username,
- PinCode: user.PinCode,
- OtpImg: fmt.Sprintf("https://%s/otp_qr?id=%d&jwt=%s", setting.LinkAddr, user.Id, tokenString),
- OtpImgBase64: "data:image/png;base64," + otpData,
- }
- w := bytes.NewBufferString("")
- t, _ := template.New("auth_complete").Parse(htmlBody)
- err = t.Execute(w, data)
- if err != nil {
- return err
- }
- // fmt.Println(w.String())
- return SendMail(base.Cfg.Issuer+"平台通知", user.Email, w.String())
- }
|