diff --git a/app/controllers/api/ApiAuthController.go b/app/controllers/api/ApiAuthController.go new file mode 100644 index 0000000..a58790a --- /dev/null +++ b/app/controllers/api/ApiAuthController.go @@ -0,0 +1,155 @@ +package api + +import ( + "github.com/revel/revel" + "github.com/leanote/leanote/app/info" + . "github.com/leanote/leanote/app/lea" +// "strconv" +) + +// 用户登录后生成一个token, 将这个token保存到session中 +// 以后每次的请求必须带这个token, 并从session中获取userId + +// 用户登录/注销/找回密码 + +type ApiAuth struct { + ApiBaseContrller +} + +// 为了demo和register +func (c ApiAuth) doLogin(email, pwd string) revel.Result { + sessionId := c.Session.Id() + var msg = "" + + userInfo := authService.Login(email, pwd) + if userInfo.Email != "" { + c.SetSession(userInfo) + sessionService.ClearLoginTimes(sessionId) + return c.RenderJson(info.Re{Ok: true}) + } else { + // 登录错误, 则错误次数++ + msg = "wrongUsernameOrPassword" + } + + return c.RenderJson(info.Re{Ok: false, Item: sessionService.LoginTimesIsOver(sessionId) , Msg: c.Message(msg)}) +} +func (c ApiAuth) Login(email, pwd string, captcha string) revel.Result { + sessionId := c.Session.Id() + var msg = "" + + // > 5次需要验证码, 直到登录成功 + if sessionService.LoginTimesIsOver(sessionId) && sessionService.GetCaptcha(sessionId) != captcha { + msg = "captchaError" + } else { + userInfo := authService.Login(email, pwd) + if userInfo.Email != "" { + c.SetSession(userInfo) + sessionService.ClearLoginTimes(sessionId) + return c.RenderJson(info.Re{Ok: true}) + } else { + // 登录错误, 则错误次数++ + msg = "wrongUsernameOrPassword" + sessionService.IncrLoginTimes(sessionId) + } + } + + return c.RenderJson(info.Re{Ok: false, Item: sessionService.LoginTimesIsOver(sessionId) , Msg: c.Message(msg)}) +} + +// 注销 +func (c ApiAuth) Logout() revel.Result { + sessionId := c.Session.Id() + sessionService.Clear(sessionId) + c.ClearSession() + re := info.NewRe() + re.Ok = true + return c.RenderJson(re) +} + +// 体验一下 +func (c ApiAuth) Demo() revel.Result { + c.doLogin(configService.GetGlobalStringConfig("demoUsername"), configService.GetGlobalStringConfig("demoPassword")) + return c.Redirect("/note") +} + +//-------- +// 注册 +func (c ApiAuth) Register(from string) revel.Result { + if !configService.IsOpenRegister() { + return c.Redirect("/index") + } + c.SetLocale() + c.RenderArgs["from"] = from + + c.RenderArgs["title"] = c.Message("register") + c.RenderArgs["subTitle"] = c.Message("register") + return c.RenderTemplate("home/register.html") +} +func (c ApiAuth) DoRegister(email, pwd string) revel.Result { + if !configService.IsOpenRegister() { + return c.Redirect("/index") + } + + re := info.NewRe(); + + if re.Ok, re.Msg = Vd("email", email); !re.Ok { + return c.RenderRe(re); + } + if re.Ok, re.Msg = Vd("password", pwd); !re.Ok { + return c.RenderRe(re); + } + + // 注册 + re.Ok, re.Msg = authService.Register(email, pwd) + + // 注册成功, 则立即登录之 + if re.Ok { + c.doLogin(email, pwd) + } + + return c.RenderRe(re) +} + +//-------- +// 找回密码 +func (c ApiAuth) FindPassword() revel.Result { + c.RenderArgs["title"] = c.Message("findPassword") + c.RenderArgs["subTitle"] = c.Message("findPassword") + return c.RenderTemplate("home/find_password.html") +} +func (c ApiAuth) DoFindPassword(email string) revel.Result { + pwdService.FindPwd(email) + re := info.NewRe() + re.Ok = true + return c.RenderJson(re) +} +// 点击链接后, 先验证之 +func (c ApiAuth) FindPassword2(token string) revel.Result { + c.RenderArgs["title"] = c.Message("findPassword") + c.RenderArgs["subTitle"] = c.Message("findPassword") + if token == "" { + return c.RenderTemplate("find_password2_timeout.html") + } + ok, _, findPwd := tokenService.VerifyToken(token, info.TokenPwd); + if !ok { + return c.RenderTemplate("home/find_password2_timeout.html") + } + c.RenderArgs["findPwd"] = findPwd + + c.RenderArgs["title"] = c.Message("updatePassword") + c.RenderArgs["subTitle"] = c.Message("updatePassword") + + return c.RenderTemplate("home/find_password2.html") +} +// 找回密码修改密码 +func (c ApiAuth) FindPasswordUpdate(token, pwd string) revel.Result { + re := info.NewRe(); + + if re.Ok, re.Msg = Vd("password", pwd); !re.Ok { + return c.RenderRe(re); + } + + // 修改之 + re.Ok, re.Msg = pwdService.UpdatePwd(token, pwd) + return c.RenderRe(re) +} diff --git a/app/controllers/api/ApiBaseController.go b/app/controllers/api/ApiBaseController.go new file mode 100644 index 0000000..cea9563 --- /dev/null +++ b/app/controllers/api/ApiBaseController.go @@ -0,0 +1,19 @@ +package api + +import ( +// "github.com/revel/revel" +// "gopkg.in/mgo.v2/bson" +// "encoding/json" +// . "github.com/leanote/leanote/app/lea" + "github.com/leanote/leanote/app/controllers" +// "io/ioutil" +// "fmt" +// "math" +// "strconv" +// "strings" +) + +// 公用Controller, 其它Controller继承它 +type ApiBaseContrller struct { + controllers.BaseController // 不能用*BaseController +} \ No newline at end of file diff --git a/app/controllers/api/UserController.go b/app/controllers/api/ApiUserController.go similarity index 96% rename from app/controllers/api/UserController.go rename to app/controllers/api/ApiUserController.go index 0e384b8..d1b04db 100644 --- a/app/controllers/api/UserController.go +++ b/app/controllers/api/ApiUserController.go @@ -11,12 +11,13 @@ import ( // "fmt" // "math" // "os" + // "path" // "strconv" ) type ApiUser struct { - *revel.Controller + ApiBaseContrller } // 修改用户名, 需要重置session diff --git a/app/controllers/api/init.go b/app/controllers/api/init.go new file mode 100644 index 0000000..a1bbfc0 --- /dev/null +++ b/app/controllers/api/init.go @@ -0,0 +1,139 @@ +package api + +import ( + "github.com/leanote/leanote/app/service" + "github.com/leanote/leanote/app/info" +// . "github.com/leanote/leanote/app/lea" + "github.com/revel/revel" + "strings" +) + +var userService *service.UserService +var noteService *service.NoteService +var trashService *service.TrashService +var notebookService *service.NotebookService +var noteContentHistoryService *service.NoteContentHistoryService +var authService *service.AuthService +var shareService *service.ShareService +var blogService *service.BlogService +var tagService *service.TagService +var pwdService *service.PwdService +var tokenService *service.TokenService +var suggestionService *service.SuggestionService +var albumService *service.AlbumService +var noteImageService *service.NoteImageService +var fileService *service.FileService +var attachService *service.AttachService +var configService *service.ConfigService +var emailService *service.EmailService +var sessionService *service.SessionService + +var pageSize = 1000 +var defaultSortField = "UpdatedTime" +var leanoteUserId = "admin" // 不能更改 +var siteUrl = "http://leanote.com" + +// 拦截器 +// 不需要拦截的url +// Index 除了Note之外都不需要 +var commonUrl = map[string]map[string]bool{"Index": map[string]bool{"Index": true, + "Login": true, + "DoLogin": true, + "Logout": true, + "Register": true, + "DoRegister": true, + "FindPasswword": true, + "DoFindPassword": true, + "FindPassword2": true, + "FindPasswordUpdate": true, + "Suggestion": true, + }, + "Note": map[string]bool{"ToImage": true}, + "Blog": map[string]bool{"Index": true, + "View": true, + "AboutMe": true, + "Cate": true, + "Search": true, + "GetLikeAndComments": true, + "IncReadNum": true, + "ListComments": true, + }, + // 用户的激活与修改邮箱都不需要登录, 通过链接地址 + "User": map[string]bool{"UpdateEmail": true, + "ActiveEmail":true, + }, + "Oauth": map[string]bool{"GithubCallback": true}, + "File": map[string]bool{"OutputImage": true, "OutputFile": true}, + "Attach": map[string]bool{"Download": true, "DownloadAll": true}, +} +func needValidate(controller, method string) bool { + // 在里面 + if v, ok := commonUrl[controller]; ok { + // 在commonUrl里 + if _, ok2 := v[method]; ok2 { + return false + } + return true + } else { + // controller不在这里的, 肯定要验证 + return true; + } +} +func AuthInterceptor(c *revel.Controller) revel.Result { + // 全部变成首字大写 + var controller = strings.Title(c.Name) + var method = strings.Title(c.MethodName) + + // 是否需要验证? + if !needValidate(controller, method) { + return nil + } + + // 验证是否已登录 + if userId, ok := c.Session["UserId"]; ok && userId != "" { + return nil // 已登录 + } + + // 没有登录, 判断是否是ajax操作 + if c.Request.Header.Get("X-Requested-With") == "XMLHttpRequest" { + re := info.NewRe() + re.Msg = "NOTLOGIN" + return c.RenderJson(re) + } + + return c.Redirect("/login") +} + +// 最外层init.go调用 +// 获取service, 单例 +func InitService() { + notebookService = service.NotebookS + noteService = service.NoteS + noteContentHistoryService = service.NoteContentHistoryS + trashService = service.TrashS + shareService = service.ShareS + userService = service.UserS + tagService = service.TagS + blogService = service.BlogS + tokenService = service.TokenS + noteImageService = service.NoteImageS + fileService = service.FileS + albumService= service.AlbumS + attachService = service.AttachS + pwdService = service.PwdS + suggestionService = service.SuggestionS + authService = service.AuthS + configService = service.ConfigS + emailService = service.EmailS + sessionService = service.SessionS +} + +func init() { + // interceptors + revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &ApiAuth{}) + revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &ApiUser{}) + + revel.OnAppStart(func() { + siteUrl, _ = revel.Config.String("site.url") + }) +} \ No newline at end of file diff --git a/app/service/ConfigService.go b/app/service/ConfigService.go index dfe7401..f715198 100644 --- a/app/service/ConfigService.go +++ b/app/service/ConfigService.go @@ -293,7 +293,7 @@ func (this *ConfigService) Backup(remark string) (ok bool, msg string) { port, _ := revel.Config.String("db.port") username, _ := revel.Config.String("db.username") password, _ := revel.Config.String("db.password") - // mongodump -h localhost -d leanote -o /root/mongodb_backup/leanote-9-22/ -u leanote -p nKFAkxKnWkEQy8Vv2LlM + // mongodump -h localhost -d leanote -o /root/mongodb_backup/leanote-10-25/ -u leanote -p xx binPath = binPath + " -h " + host + " -d " + dbname + " -port " + port if username != "" { binPath += " -u " + username + " -p " + password