123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- package controllers
- import (
- "math/rand"
- "net"
- "sync"
- "time"
- "ehang.io/nps/lib/common"
- "ehang.io/nps/lib/file"
- "ehang.io/nps/server"
- "github.com/astaxie/beego"
- )
- type LoginController struct {
- beego.Controller
- }
- var ipRecord sync.Map
- type record struct {
- hasLoginFailTimes int
- lastLoginTime time.Time
- }
- func (self *LoginController) Index() {
- // Try login implicitly, will succeed if it's configured as no-auth(empty username&password).
- webBaseUrl := beego.AppConfig.String("web_base_url")
- if self.doLogin("", "", false) {
- self.Redirect(webBaseUrl+"/index/index", 302)
- }
- self.Data["web_base_url"] = webBaseUrl
- self.Data["register_allow"], _ = beego.AppConfig.Bool("allow_user_register")
- self.TplName = "login/index.html"
- }
- func (self *LoginController) Verify() {
- username := self.GetString("username")
- password := self.GetString("password")
- if self.doLogin(username, password, true) {
- self.Data["json"] = map[string]interface{}{"status": 1, "msg": "login success"}
- } else {
- self.Data["json"] = map[string]interface{}{"status": 0, "msg": "username or password incorrect"}
- }
- self.ServeJSON()
- }
- func (self *LoginController) doLogin(username, password string, explicit bool) bool {
- clearIprecord()
- ip, _, _ := net.SplitHostPort(self.Ctx.Request.RemoteAddr)
- if v, ok := ipRecord.Load(ip); ok {
- vv := v.(*record)
- if (time.Now().Unix() - vv.lastLoginTime.Unix()) >= 60 {
- vv.hasLoginFailTimes = 0
- }
- if vv.hasLoginFailTimes >= 10 {
- return false
- }
- }
- var auth bool
- if password == beego.AppConfig.String("web_password") && username == beego.AppConfig.String("web_username") {
- self.SetSession("isAdmin", true)
- self.DelSession("clientId")
- self.DelSession("username")
- auth = true
- server.Bridge.Register.Store(common.GetIpByAddr(self.Ctx.Input.IP()), time.Now().Add(time.Hour*time.Duration(2)))
- }
- b, err := beego.AppConfig.Bool("allow_user_login")
- if err == nil && b && !auth {
- file.GetDb().JsonDb.Clients.Range(func(key, value interface{}) bool {
- v := value.(*file.Client)
- if !v.Status || v.NoDisplay {
- return true
- }
- if v.WebUserName == "" && v.WebPassword == "" {
- if username != "user" || v.VerifyKey != password {
- return true
- } else {
- auth = true
- }
- }
- if !auth && v.WebPassword == password && v.WebUserName == username {
- auth = true
- }
- if auth {
- self.SetSession("isAdmin", false)
- self.SetSession("clientId", v.Id)
- self.SetSession("username", v.WebUserName)
- return false
- }
- return true
- })
- }
- if auth {
- self.SetSession("auth", true)
- ipRecord.Delete(ip)
- return true
- }
- if v, load := ipRecord.LoadOrStore(ip, &record{hasLoginFailTimes: 1, lastLoginTime: time.Now()}); load && explicit {
- vv := v.(*record)
- vv.lastLoginTime = time.Now()
- vv.hasLoginFailTimes += 1
- ipRecord.Store(ip, vv)
- }
- return false
- }
- func (self *LoginController) Register() {
- if self.Ctx.Request.Method == "GET" {
- self.Data["web_base_url"] = beego.AppConfig.String("web_base_url")
- self.TplName = "login/register.html"
- } else {
- if b, err := beego.AppConfig.Bool("allow_user_register"); err != nil || !b {
- self.Data["json"] = map[string]interface{}{"status": 0, "msg": "register is not allow"}
- self.ServeJSON()
- return
- }
- if self.GetString("username") == "" || self.GetString("password") == "" || self.GetString("username") == beego.AppConfig.String("web_username") {
- self.Data["json"] = map[string]interface{}{"status": 0, "msg": "please check your input"}
- self.ServeJSON()
- return
- }
- t := &file.Client{
- Id: int(file.GetDb().JsonDb.GetClientId()),
- Status: true,
- Cnf: &file.Config{},
- WebUserName: self.GetString("username"),
- WebPassword: self.GetString("password"),
- Flow: &file.Flow{},
- }
- if err := file.GetDb().NewClient(t); err != nil {
- self.Data["json"] = map[string]interface{}{"status": 0, "msg": err.Error()}
- } else {
- self.Data["json"] = map[string]interface{}{"status": 1, "msg": "register success"}
- }
- self.ServeJSON()
- }
- }
- func (self *LoginController) Out() {
- self.SetSession("auth", false)
- self.Redirect(beego.AppConfig.String("web_base_url")+"/login/index", 302)
- }
- func clearIprecord() {
- rand.Seed(time.Now().UnixNano())
- x := rand.Intn(100)
- if x == 1 {
- ipRecord.Range(func(key, value interface{}) bool {
- v := value.(*record)
- if time.Now().Unix()-v.lastLoginTime.Unix() >= 60 {
- ipRecord.Delete(key)
- }
- return true
- })
- }
- }
|