From f91863b37bfbf9eb79ff832c7368ace154f618a2 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Wed, 29 Oct 2014 23:03:03 +0800 Subject: [PATCH] #106 Basically completed the back-end implementation. --- conf/wide.go | 8 ++- i18n/en_US.json | 1 + i18n/ja_JP.json | 1 + i18n/zh_CN.json | 1 + i18n/zh_TW.json | 1 + main.go | 95 ++------------------------- session/users.go | 155 +++++++++++++++++++++++++++++++++++---------- views/sign_up.html | 11 ++++ 8 files changed, 150 insertions(+), 123 deletions(-) create mode 100644 views/sign_up.html diff --git a/conf/wide.go b/conf/wide.go index 8611ead..63338c5 100644 --- a/conf/wide.go +++ b/conf/wide.go @@ -20,7 +20,11 @@ import ( const ( PathSeparator = string(os.PathSeparator) // OS-specific path separator PathListSeparator = string(os.PathListSeparator) // OS-specific path list separator +) +const ( + WideVersion = "1.0.1" // wide version + CodeMirrorVer = "4.7" // editor version ) // The latest session content. @@ -288,7 +292,7 @@ func initWorkspaceDirs() { } for _, path := range paths { - createWorkspaceDir(path) + CreateWorkspaceDir(path) } } @@ -298,7 +302,7 @@ func initWorkspaceDirs() { // 2. src directory: {path}/src // 3. package directory: {path}/pkg // 4. binary directory: {path}/bin -func createWorkspaceDir(path string) { +func CreateWorkspaceDir(path string) { createDir(path) createDir(path + PathSeparator + "src") createDir(path + PathSeparator + "pkg") diff --git a/i18n/en_US.json b/i18n/en_US.json index 7839ae2..7baa88a 100644 --- a/i18n/en_US.json +++ b/i18n/en_US.json @@ -106,5 +106,6 @@ "credits": "Credits", "uptodate": "it is up to date", "test": "Test", + "sign_up": "Sign Up", "colon": ": " } \ No newline at end of file diff --git a/i18n/ja_JP.json b/i18n/ja_JP.json index 872c0fc..5f6dde5 100644 --- a/i18n/ja_JP.json +++ b/i18n/ja_JP.json @@ -106,5 +106,6 @@ "credits": "クレジット", "uptodate": "最新です", "test": "テスト", + "sign_up": "登録", "colon": ":" } diff --git a/i18n/zh_CN.json b/i18n/zh_CN.json index 059e8e8..acda5c8 100644 --- a/i18n/zh_CN.json +++ b/i18n/zh_CN.json @@ -106,5 +106,6 @@ "credits": "致谢", "uptodate": "已是最新版本", "test": "测试", + "sign_up": "注册", "colon": ":" } \ No newline at end of file diff --git a/i18n/zh_TW.json b/i18n/zh_TW.json index f9d3372..080d6b4 100644 --- a/i18n/zh_TW.json +++ b/i18n/zh_TW.json @@ -106,5 +106,6 @@ "credits": "致謝", "uptodate": "已是最新版本", "test": "測試", + "sign_up": "註冊", "colon": ":" } \ No newline at end of file diff --git a/main.go b/main.go index 8272e05..d08688b 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,11 @@ package main import ( - "encoding/json" "flag" "html/template" - "math/rand" "mime" "net/http" "runtime" - "strconv" "time" "github.com/b3log/wide/conf" @@ -24,11 +21,6 @@ import ( "github.com/golang/glog" ) -const ( - Ver = "1.0.1" // wide version - CodeMirrorVer = "4.7" // editor version -) - // The only one init function in Wide. func init() { // TODO: args @@ -45,78 +37,6 @@ func init() { session.FixedTimeRelease() } -// loginHandler handles request of user login. -func loginHandler(w http.ResponseWriter, r *http.Request) { - if "GET" == r.Method { - // show the login page - - model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(conf.Wide.Locale), - "locale": conf.Wide.Locale, "ver": Ver} - - t, err := template.ParseFiles("views/login.html") - - if nil != err { - glog.Error(err) - http.Error(w, err.Error(), 500) - - return - } - - t.Execute(w, model) - - return - } - - // non-GET request as login request - - succ := false - - data := map[string]interface{}{"succ": &succ} - defer util.RetJSON(w, r, data) - - args := struct { - Username string - Password string - }{} - - if err := json.NewDecoder(r.Body).Decode(&args); err != nil { - glog.Error(err) - succ = true - - return - } - - for _, user := range conf.Wide.Users { - if user.Name == args.Username && user.Password == args.Password { - succ = true - } - } - - if !succ { - return - } - - // create a HTTP session - httpSession, _ := session.HTTPSession.Get(r, "wide-session") - httpSession.Values["username"] = args.Username - httpSession.Values["id"] = strconv.Itoa(rand.Int()) - httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge - httpSession.Save(r, w) - - glog.Infof("Created a HTTP session [%s] for user [%s]", httpSession.Values["id"].(string), args.Username) -} - -// logoutHandler handles request of user logout (exit). -func logoutHandler(w http.ResponseWriter, r *http.Request) { - data := map[string]interface{}{"succ": true} - defer util.RetJSON(w, r, data) - - httpSession, _ := session.HTTPSession.Get(r, "wide-session") - - httpSession.Options.MaxAge = -1 - httpSession.Save(r, w) -} - // indexHandler handles request of Wide index. func indexHandler(w http.ResponseWriter, r *http.Request) { httpSession, _ := session.HTTPSession.Get(r, "wide-session") @@ -141,7 +61,7 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(locale), "locale": locale, "session": wideSession, "latestSessionContent": userConf.LatestSessionContent, - "pathSeparator": conf.PathSeparator, "codeMirrorVer": CodeMirrorVer} + "pathSeparator": conf.PathSeparator, "codeMirrorVer": conf.CodeMirrorVer} glog.V(3).Infof("User [%s] has [%d] sessions", username, len(wideSessions)) @@ -182,7 +102,7 @@ func startHandler(w http.ResponseWriter, r *http.Request) { userWorkspace := conf.Wide.GetUserWorkspace(username) model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(locale), "locale": locale, - "username": username, "workspace": userWorkspace, "ver": Ver} + "username": username, "workspace": userWorkspace, "ver": conf.WideVersion} t, err := template.ParseFiles("views/start.html") @@ -242,8 +162,8 @@ func aboutHandler(w http.ResponseWriter, r *http.Request) { username := httpSession.Values["username"].(string) locale := conf.Wide.GetUser(username).Locale - model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(locale), "locale": locale, "ver": Ver, - "goos": runtime.GOOS, "goarch": runtime.GOARCH, "gover": runtime.Version()} + model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(locale), "locale": locale, + "ver": conf.WideVersion, "goos": runtime.GOOS, "goarch": runtime.GOARCH, "gover": runtime.Version()} t, err := template.ParseFiles("views/about.html") @@ -266,8 +186,6 @@ func main() { defer glog.Flush() // IDE - http.HandleFunc("/login", handlerWrapper(loginHandler)) - http.HandleFunc("/logout", handlerWrapper(logoutHandler)) http.HandleFunc("/", handlerWrapper(indexHandler)) http.HandleFunc("/start", handlerWrapper(startHandler)) http.HandleFunc("/about", handlerWrapper(aboutHandler)) @@ -318,8 +236,9 @@ func main() { http.HandleFunc("/notification/ws", handlerWrapper(notification.WSHandler)) // user - http.HandleFunc("/user/new", handlerWrapper(session.AddUser)) - http.HandleFunc("/user/repos/init", handlerWrapper(session.InitGitRepos)) + http.HandleFunc("/login", handlerWrapper(session.LoginHandler)) + http.HandleFunc("/logout", handlerWrapper(session.LogoutHandler)) + http.HandleFunc("/signup", handlerWrapper(session.SignUpUser)) glog.V(0).Infof("Wide is running [%s]", conf.Wide.Server) diff --git a/session/users.go b/session/users.go index e33e304..88a95c7 100644 --- a/session/users.go +++ b/session/users.go @@ -1,32 +1,132 @@ package session -// TODO: this file not used currently, just a beginning :p - import ( "encoding/json" + "math/rand" "net/http" + "path/filepath" + "strconv" + "text/template" "github.com/b3log/wide/conf" + "github.com/b3log/wide/i18n" "github.com/b3log/wide/util" "github.com/golang/glog" ) const ( - USER_EXISTS = "user exists" - USER_CREATED = "user created" - USER_CREATE_FAILED = "user create failed" + UserExists = "user exists" + UserCreated = "user created" + UserCreateError = "user create error" ) -// 添加用户. -func AddUser(w http.ResponseWriter, r *http.Request) { +// LoginHandler handles request of user login. +func LoginHandler(w http.ResponseWriter, r *http.Request) { + if "GET" == r.Method { + // show the login page + + model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(conf.Wide.Locale), + "locale": conf.Wide.Locale, "ver": conf.WideVersion} + + t, err := template.ParseFiles("views/login.html") + + if nil != err { + glog.Error(err) + http.Error(w, err.Error(), 500) + + return + } + + t.Execute(w, model) + + return + } + + // non-GET request as login request + + succ := false + data := map[string]interface{}{"succ": &succ} + defer util.RetJSON(w, r, data) + + args := struct { + Username string + Password string + }{} + + if err := json.NewDecoder(r.Body).Decode(&args); err != nil { + glog.Error(err) + succ = true + + return + } + + for _, user := range conf.Wide.Users { + if user.Name == args.Username && user.Password == args.Password { + succ = true + } + } + + if !succ { + return + } + + // create a HTTP session + httpSession, _ := HTTPSession.Get(r, "wide-session") + httpSession.Values["username"] = args.Username + httpSession.Values["id"] = strconv.Itoa(rand.Int()) + httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge + httpSession.Save(r, w) + + glog.Infof("Created a HTTP session [%s] for user [%s]", httpSession.Values["id"].(string), args.Username) +} + +// LogoutHandler handles request of user logout (exit). +func LogoutHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} defer util.RetJSON(w, r, data) + httpSession, _ := HTTPSession.Get(r, "wide-session") + + httpSession.Options.MaxAge = -1 + httpSession.Save(r, w) +} + +// SignUpUser handles request of registering user. +func SignUpUser(w http.ResponseWriter, r *http.Request) { + if "GET" == r.Method { + // show the user sign up page + + firstUserWorkspace := conf.Wide.GetUserWorkspace(conf.Wide.Users[0].Name) + dir := filepath.Dir(firstUserWorkspace) + + model := map[string]interface{}{"conf": conf.Wide, "i18n": i18n.GetAll(conf.Wide.Locale), + "locale": conf.Wide.Locale, "ver": conf.WideVersion, "dir": dir} + + t, err := template.ParseFiles("views/sign_up.html") + + if nil != err { + glog.Error(err) + http.Error(w, err.Error(), 500) + + return + } + + t.Execute(w, model) + + return + } + + // non-GET request as add user request + + succ := true + data := map[string]interface{}{"succ": &succ} + defer util.RetJSON(w, r, data) + var args map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&args); err != nil { glog.Error(err) - data["succ"] = false + succ = false return } @@ -35,47 +135,36 @@ func AddUser(w http.ResponseWriter, r *http.Request) { password := args["password"].(string) msg := addUser(username, password) - if USER_CREATED != msg { - data["succ"] = false + if UserCreated != msg { + succ = false data["msg"] = msg } } -// 初始化用户 git 仓库. -func InitGitRepos(w http.ResponseWriter, r *http.Request) { - data := map[string]interface{}{"succ": true} - defer util.RetJSON(w, r, data) - - session, _ := HTTPSession.Get(r, "wide-session") - - username := session.Values["username"].(string) - userRepos := conf.Wide.GetUserWorkspace(username) + conf.PathSeparator + "src" - - glog.Info(userRepos) - - // TODO: git clone -} - func addUser(username, password string) string { - // TODO: https://github.com/b3log/wide/issues/23 - conf.Load() + // XXX: validate - // XXX: 新建用户校验增强 for _, user := range conf.Wide.Users { if user.Name == username { - return USER_EXISTS + return UserExists } } - // FIXME: 新建用户时保存工作空间 - newUser := &conf.User{Name: username, Password: password, Workspace: ""} + firstUserWorkspace := conf.Wide.GetUserWorkspace(conf.Wide.Users[0].Name) + dir := filepath.Dir(firstUserWorkspace) + workspace := filepath.Join(dir, username) + + newUser := &conf.User{Name: username, Password: password, Workspace: workspace, + Locale: conf.Wide.Locale, GoFormat: "gofmt"} conf.Wide.Users = append(conf.Wide.Users, newUser) if !conf.Save() { - return USER_CREATE_FAILED + return UserCreateError } + conf.CreateWorkspaceDir(workspace) + glog.Infof("Created a user [%s]", username) - return USER_CREATED + return UserCreated } diff --git a/views/sign_up.html b/views/sign_up.html new file mode 100644 index 0000000..a07ad62 --- /dev/null +++ b/views/sign_up.html @@ -0,0 +1,11 @@ + + + + + {{.i18n.wide}} - {{.i18n.sign_up}} + + + + {{.dir}} + +