From 5989d0fb7ba2692c0e2025218c1de939376eb074 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Fri, 17 May 2019 00:41:52 +0800 Subject: [PATCH] :art: #347 --- conf/wide.go | 53 +---------- conf/wide.json | 7 +- editor/editors.go | 10 +- editor/formatter.go | 2 +- file/files.go | 18 ++-- main.go | 150 ++++++++++++++---------------- notification/notifications.go | 2 +- output/build.go | 2 +- output/cross.go | 2 +- output/get.go | 2 +- output/install.go | 2 +- output/test.go | 2 +- output/vet.go | 2 +- playground/autocomplete.go | 2 +- playground/build.go | 2 +- playground/file.go | 4 +- playground/playgrounds.go | 5 +- session/oauthctl.go | 150 ++++++++++++++++++++++++++++-- session/sessions.go | 4 +- session/users.go | 145 +---------------------------- views/about.html | 2 +- views/index.html | 166 +++++++++++++++++----------------- views/playground/index.html | 80 ++++++++-------- views/preference.html | 2 +- views/shell.html | 35 ------- views/sign_up.html | 8 +- 26 files changed, 378 insertions(+), 481 deletions(-) delete mode 100644 views/shell.html diff --git a/conf/wide.go b/conf/wide.go index 491c928..15a7a45 100644 --- a/conf/wide.go +++ b/conf/wide.go @@ -57,13 +57,8 @@ func main() { // Configuration. type conf struct { - IP string // server ip, ${ip} - Port string // server port - Context string // server context - Server string // server host and port ({IP}:{Port}) - StaticServer string // static resources server scheme, host and port (http://{IP}:{Port}) + Server string // server LogLevel string // logging level: trace/debug/info/warn/error - Channel string // channel (ws://{IP}:{Port}) HTTPSessionMaxAge int // HTTP session max age (in seciond) StaticResourceVersion string // version of static resources MaxProcs int // Go max procs @@ -93,8 +88,8 @@ var Docker bool const DockerImageGo = "golang" // Load loads the Wide configurations from wide.json and users' configurations from users/{userId}.json. -func Load(confPath, confUsers, confIP, confPort, confServer, confLogLevel, confStaticServer, confContext, confChannel, confPlayground string, confUsersWorkspaces string) { - initWide(confPath, confUsers, confIP, confPort, confServer, confLogLevel, confStaticServer, confContext, confChannel, confPlayground, confUsersWorkspaces) +func Load(confPath, confUsers, confServer, confLogLevel, confPlayground string, confUsersWorkspaces string) { + initWide(confPath, confUsers, confServer, confLogLevel, confPlayground, confUsersWorkspaces) initUsers() cmd := exec.Command("docker", "version") @@ -168,7 +163,7 @@ func initUsers() { initCustomizedConfs() } -func initWide(confPath, confUsers, confIP, confPort, confServer, confLogLevel, confStaticServer, confContext, confChannel, confPlayground string, confUsersWorkspaces string) { +func initWide(confPath, confUsers, confServer, confLogLevel, confPlayground string, confUsersWorkspaces string) { bytes, err := ioutil.ReadFile(confPath) if nil != err { logger.Error(err) @@ -236,54 +231,14 @@ func initWide(confPath, confUsers, confIP, confPort, confServer, confLogLevel, c } } - // IP - if "" != confIP { - Wide.IP = confIP - } else { - ip, err := util.Net.LocalIP() - if nil != err { - logger.Error(err) - - os.Exit(-1) - } - - logger.Debugf("${ip} [%s]", ip) - Wide.IP = strings.Replace(Wide.IP, "${ip}", ip, 1) - } - - if "" != confPort { - Wide.Port = confPort - } - // Server - Wide.Server = strings.Replace(Wide.Server, "{IP}", Wide.IP, 1) - Wide.Server = strings.Replace(Wide.Server, "{Port}", Wide.Port, 1) if "" != confServer { Wide.Server = confServer } - // Static Server - Wide.StaticServer = strings.Replace(Wide.StaticServer, "{IP}", Wide.IP, 1) - Wide.StaticServer = strings.Replace(Wide.StaticServer, "{Port}", Wide.Port, 1) - if "" != confStaticServer { - Wide.StaticServer = confStaticServer - } - - // Context - if "" != confContext { - Wide.Context = confContext - } - time := strconv.FormatInt(time.Now().UnixNano(), 10) logger.Debugf("${time} [%s]", time) Wide.StaticResourceVersion = strings.Replace(Wide.StaticResourceVersion, "${time}", time, 1) - - // Channel - Wide.Channel = strings.Replace(Wide.Channel, "{IP}", Wide.IP, 1) - Wide.Channel = strings.Replace(Wide.Channel, "{Port}", Wide.Port, 1) - if "" != confChannel { - Wide.Channel = confChannel - } } // FixedTimeCheckEnv checks Wide runtime enviorment periodically (7 minutes). diff --git a/conf/wide.json b/conf/wide.json index af71a6d..1bd6144 100644 --- a/conf/wide.json +++ b/conf/wide.json @@ -1,11 +1,6 @@ { - "IP": "${ip}", - "Port": "7070", - "Context": "", - "Server": "{IP}:{Port}", - "StaticServer": "", + "Server": "http://127.0.0.1:7070", "LogLevel": "debug", - "Channel": "ws://{IP}:{Port}", "HTTPSessionMaxAge": 86400, "StaticResourceVersion": "${time}", "MaxProcs": 4, diff --git a/editor/editors.go b/editor/editors.go index 0a0dcd8..64c0e85 100644 --- a/editor/editors.go +++ b/editor/editors.go @@ -41,7 +41,7 @@ var logger = log.NewLogger(os.Stdout) // WSHandler handles request of creating editor channel. // XXX: NOT used at present func WSHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -111,7 +111,7 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) { return } - session, _ := session.HTTPSession.Get(r, "wide-session") + session, _ := session.HTTPSession.Get(r, session.CookieName) if session.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -182,7 +182,7 @@ func GetExprInfoHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - session, _ := session.HTTPSession.Get(r, "wide-session") + session, _ := session.HTTPSession.Get(r, session.CookieName) uid := session.Values["uid"].(string) var args map[string]interface{} @@ -253,7 +253,7 @@ func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - session, _ := session.HTTPSession.Get(r, "wide-session") + session, _ := session.HTTPSession.Get(r, session.CookieName) if session.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -341,7 +341,7 @@ func FindUsagesHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - session, _ := session.HTTPSession.Get(r, "wide-session") + session, _ := session.HTTPSession.Get(r, session.CookieName) if session.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/editor/formatter.go b/editor/formatter.go index 621f9ab..a550f65 100644 --- a/editor/formatter.go +++ b/editor/formatter.go @@ -34,7 +34,7 @@ func GoFmtHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - session, _ := session.HTTPSession.Get(r, "wide-session") + session, _ := session.HTTPSession.Get(r, session.CookieName) if session.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/file/files.go b/file/files.go index 678ed36..dcf66cd 100644 --- a/file/files.go +++ b/file/files.go @@ -74,7 +74,7 @@ func initAPINode() { // The Go API source code package also as a child node, // so that users can easily view the Go API source code in file tree. func GetFilesHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -123,7 +123,7 @@ func GetFilesHandler(w http.ResponseWriter, r *http.Request) { // RefreshDirectoryHandler handles request of refresh a directory of file tree. func RefreshDirectoryHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -156,7 +156,7 @@ func RefreshDirectoryHandler(w http.ResponseWriter, r *http.Request) { // GetFileHandler handles request of opening file by editor. func GetFileHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -232,7 +232,7 @@ func GetFileHandler(w http.ResponseWriter, r *http.Request) { // SaveFileHandler handles request of saving file. func SaveFileHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -288,7 +288,7 @@ func SaveFileHandler(w http.ResponseWriter, r *http.Request) { // NewFileHandler handles request of creating file or directory. func NewFileHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -340,7 +340,7 @@ func NewFileHandler(w http.ResponseWriter, r *http.Request) { // RemoveFileHandler handles request of removing file or directory. func RemoveFileHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -386,7 +386,7 @@ func RemoveFileHandler(w http.ResponseWriter, r *http.Request) { // RenameFileHandler handles request of renaming file or directory. func RenameFileHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -451,7 +451,7 @@ func (f foundPaths) Less(i, j int) bool { return f[i].score > f[j].score } // FindHandler handles request of find files under the specified directory with the specified filename pattern. func FindHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -505,7 +505,7 @@ func FindHandler(w http.ResponseWriter, r *http.Request) { // SearchTextHandler handles request of searching files under the specified directory with the specified keyword. func SearchTextHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/main.go b/main.go index f0bb7aa..5292c82 100644 --- a/main.go +++ b/main.go @@ -49,13 +49,8 @@ var logger *log.Logger func init() { confPath := flag.String("conf", "conf/wide.json", "path of wide.json") confUsers := flag.String("users", "conf/users", "path of users") - confIP := flag.String("ip", "", "this will overwrite Wide.IP if specified") - confPort := flag.String("port", "", "this will overwrite Wide.Port if specified") confServer := flag.String("server", "", "this will overwrite Wide.Server if specified") confLogLevel := flag.String("log_level", "", "this will overwrite Wide.LogLevel if specified") - confStaticServer := flag.String("static_server", "", "this will overwrite Wide.StaticServer if specified") - confContext := flag.String("context", "", "this will overwrite Wide.Context if specified") - confChannel := flag.String("channel", "", "this will overwrite Wide.Channel if specified") confStat := flag.Bool("stat", false, "whether report statistics periodically") confPlayground := flag.String("playground", "", "this will overwrite Wide.Playground if specified") confUsersWorkspaces := flag.String("users_workspaces", "", "this will overwrite Wide.UsersWorkspaces if specified") @@ -74,7 +69,7 @@ func init() { i18n.Load() event.Load() - conf.Load(*confPath, *confUsers, *confIP, *confPort, *confServer, *confLogLevel, *confStaticServer, *confContext, *confChannel, *confPlayground, *confUsersWorkspaces) + conf.Load(*confPath, *confUsers, *confServer, *confLogLevel, *confPlayground, *confUsersWorkspaces) conf.FixedTimeCheckEnv() session.FixedTimeSave() @@ -95,86 +90,91 @@ func main() { handleSignal() // IDE - http.HandleFunc(conf.Wide.Context+"/", handlerGzWrapper(indexHandler)) - http.HandleFunc(conf.Wide.Context+"/start", handlerWrapper(startHandler)) - http.HandleFunc(conf.Wide.Context+"/about", handlerWrapper(aboutHandler)) - http.HandleFunc(conf.Wide.Context+"/keyboard_shortcuts", handlerWrapper(keyboardShortcutsHandler)) + http.HandleFunc("/", handlerGzWrapper(indexHandler)) + http.HandleFunc("/start", handlerWrapper(startHandler)) + http.HandleFunc("/about", handlerWrapper(aboutHandler)) + http.HandleFunc("/keyboard_shortcuts", handlerWrapper(keyboardShortcutsHandler)) // static resources - http.Handle(conf.Wide.Context+"/static/", http.StripPrefix(conf.Wide.Context+"/static/", http.FileServer(http.Dir("static")))) + http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) serveSingle("/favicon.ico", "./static/favicon.ico") + // oauth + http.HandleFunc("/oauth/github", session.RedirectGitHubHandler) + http.HandleFunc("/oauth/github/callback", session.GithubCallbackHandler) + // workspaces for _, user := range conf.Users { - http.Handle(conf.Wide.Context+"/workspace/"+user.Name+"/", - http.StripPrefix(conf.Wide.Context+"/workspace/"+user.Name+"/", http.FileServer(http.Dir(user.WorkspacePath())))) + http.Handle("/workspace/"+user.Name+"/", + http.StripPrefix("/workspace/"+user.Name+"/", http.FileServer(http.Dir(user.WorkspacePath())))) } // session - http.HandleFunc(conf.Wide.Context+"/session/ws", handlerWrapper(session.WSHandler)) - http.HandleFunc(conf.Wide.Context+"/session/save", handlerWrapper(session.SaveContentHandler)) + http.HandleFunc("/session/ws", handlerWrapper(session.WSHandler)) + http.HandleFunc("/session/save", handlerWrapper(session.SaveContentHandler)) // run - http.HandleFunc(conf.Wide.Context+"/build", handlerWrapper(output.BuildHandler)) - http.HandleFunc(conf.Wide.Context+"/run", handlerWrapper(output.RunHandler)) - http.HandleFunc(conf.Wide.Context+"/stop", handlerWrapper(output.StopHandler)) - http.HandleFunc(conf.Wide.Context+"/go/test", handlerWrapper(output.GoTestHandler)) - http.HandleFunc(conf.Wide.Context+"/go/vet", handlerWrapper(output.GoVetHandler)) - http.HandleFunc(conf.Wide.Context+"/go/get", handlerWrapper(output.GoGetHandler)) - http.HandleFunc(conf.Wide.Context+"/go/install", handlerWrapper(output.GoInstallHandler)) - http.HandleFunc(conf.Wide.Context+"/output/ws", handlerWrapper(output.WSHandler)) + http.HandleFunc("/build", handlerWrapper(output.BuildHandler)) + http.HandleFunc("/run", handlerWrapper(output.RunHandler)) + http.HandleFunc("/stop", handlerWrapper(output.StopHandler)) + http.HandleFunc("/go/test", handlerWrapper(output.GoTestHandler)) + http.HandleFunc("/go/vet", handlerWrapper(output.GoVetHandler)) + http.HandleFunc("/go/get", handlerWrapper(output.GoGetHandler)) + http.HandleFunc("/go/install", handlerWrapper(output.GoInstallHandler)) + http.HandleFunc("/output/ws", handlerWrapper(output.WSHandler)) // cross-compilation - http.HandleFunc(conf.Wide.Context+"/cross", handlerWrapper(output.CrossCompilationHandler)) + http.HandleFunc("/cross", handlerWrapper(output.CrossCompilationHandler)) // file tree - http.HandleFunc(conf.Wide.Context+"/files", handlerWrapper(file.GetFilesHandler)) - http.HandleFunc(conf.Wide.Context+"/file/refresh", handlerWrapper(file.RefreshDirectoryHandler)) - http.HandleFunc(conf.Wide.Context+"/file", handlerWrapper(file.GetFileHandler)) - http.HandleFunc(conf.Wide.Context+"/file/save", handlerWrapper(file.SaveFileHandler)) - http.HandleFunc(conf.Wide.Context+"/file/new", handlerWrapper(file.NewFileHandler)) - http.HandleFunc(conf.Wide.Context+"/file/remove", handlerWrapper(file.RemoveFileHandler)) - http.HandleFunc(conf.Wide.Context+"/file/rename", handlerWrapper(file.RenameFileHandler)) - http.HandleFunc(conf.Wide.Context+"/file/search/text", handlerWrapper(file.SearchTextHandler)) - http.HandleFunc(conf.Wide.Context+"/file/find/name", handlerWrapper(file.FindHandler)) + http.HandleFunc("/files", handlerWrapper(file.GetFilesHandler)) + http.HandleFunc("/file/refresh", handlerWrapper(file.RefreshDirectoryHandler)) + http.HandleFunc("/file", handlerWrapper(file.GetFileHandler)) + http.HandleFunc("/file/save", handlerWrapper(file.SaveFileHandler)) + http.HandleFunc("/file/new", handlerWrapper(file.NewFileHandler)) + http.HandleFunc("/file/remove", handlerWrapper(file.RemoveFileHandler)) + http.HandleFunc("/file/rename", handlerWrapper(file.RenameFileHandler)) + http.HandleFunc("/file/search/text", handlerWrapper(file.SearchTextHandler)) + http.HandleFunc("/file/find/name", handlerWrapper(file.FindHandler)) // outline - http.HandleFunc(conf.Wide.Context+"/outline", handlerWrapper(file.GetOutlineHandler)) + http.HandleFunc("/outline", handlerWrapper(file.GetOutlineHandler)) // file export/import - http.HandleFunc(conf.Wide.Context+"/file/zip/new", handlerWrapper(file.CreateZipHandler)) - http.HandleFunc(conf.Wide.Context+"/file/zip", handlerWrapper(file.GetZipHandler)) - http.HandleFunc(conf.Wide.Context+"/file/decompress", handlerWrapper(file.DecompressHandler)) + http.HandleFunc("/file/zip/new", handlerWrapper(file.CreateZipHandler)) + http.HandleFunc("/file/zip", handlerWrapper(file.GetZipHandler)) + http.HandleFunc("/file/decompress", handlerWrapper(file.DecompressHandler)) // editor - http.HandleFunc(conf.Wide.Context+"/editor/ws", handlerWrapper(editor.WSHandler)) - http.HandleFunc(conf.Wide.Context+"/go/fmt", handlerWrapper(editor.GoFmtHandler)) - http.HandleFunc(conf.Wide.Context+"/autocomplete", handlerWrapper(editor.AutocompleteHandler)) - http.HandleFunc(conf.Wide.Context+"/exprinfo", handlerWrapper(editor.GetExprInfoHandler)) - http.HandleFunc(conf.Wide.Context+"/find/decl", handlerWrapper(editor.FindDeclarationHandler)) - http.HandleFunc(conf.Wide.Context+"/find/usages", handlerWrapper(editor.FindUsagesHandler)) + http.HandleFunc("/editor/ws", handlerWrapper(editor.WSHandler)) + http.HandleFunc("/go/fmt", handlerWrapper(editor.GoFmtHandler)) + http.HandleFunc("/autocomplete", handlerWrapper(editor.AutocompleteHandler)) + http.HandleFunc("/exprinfo", handlerWrapper(editor.GetExprInfoHandler)) + http.HandleFunc("/find/decl", handlerWrapper(editor.FindDeclarationHandler)) + http.HandleFunc("/find/usages", handlerWrapper(editor.FindUsagesHandler)) // notification - http.HandleFunc(conf.Wide.Context+"/notification/ws", handlerWrapper(notification.WSHandler)) + http.HandleFunc("/notification/ws", handlerWrapper(notification.WSHandler)) // user - http.HandleFunc(conf.Wide.Context+"/logout", handlerWrapper(session.LogoutHandler)) - http.HandleFunc(conf.Wide.Context+"/preference", handlerWrapper(session.PreferenceHandler)) + http.HandleFunc("/logout", handlerWrapper(session.LogoutHandler)) + http.HandleFunc("/preference", handlerWrapper(session.PreferenceHandler)) // playground - http.HandleFunc(conf.Wide.Context+"/playground", handlerWrapper(playground.IndexHandler)) - http.HandleFunc(conf.Wide.Context+"/playground/", handlerWrapper(playground.IndexHandler)) - http.HandleFunc(conf.Wide.Context+"/playground/ws", handlerWrapper(playground.WSHandler)) - http.HandleFunc(conf.Wide.Context+"/playground/save", handlerWrapper(playground.SaveHandler)) - http.HandleFunc(conf.Wide.Context+"/playground/short-url", handlerWrapper(playground.ShortURLHandler)) - http.HandleFunc(conf.Wide.Context+"/playground/build", handlerWrapper(playground.BuildHandler)) - http.HandleFunc(conf.Wide.Context+"/playground/run", handlerWrapper(playground.RunHandler)) - http.HandleFunc(conf.Wide.Context+"/playground/stop", handlerWrapper(playground.StopHandler)) - http.HandleFunc(conf.Wide.Context+"/playground/autocomplete", handlerWrapper(playground.AutocompleteHandler)) + http.HandleFunc("/playground", handlerWrapper(playground.IndexHandler)) + http.HandleFunc("/playground/", handlerWrapper(playground.IndexHandler)) + http.HandleFunc("/playground/ws", handlerWrapper(playground.WSHandler)) + http.HandleFunc("/playground/save", handlerWrapper(playground.SaveHandler)) + http.HandleFunc("/playground/short-url", handlerWrapper(playground.ShortURLHandler)) + http.HandleFunc("/playground/build", handlerWrapper(playground.BuildHandler)) + http.HandleFunc("/playground/run", handlerWrapper(playground.RunHandler)) + http.HandleFunc("/playground/stop", handlerWrapper(playground.StopHandler)) + http.HandleFunc("/playground/autocomplete", handlerWrapper(playground.AutocompleteHandler)) - logger.Infof("Wide is running [%s]", conf.Wide.Server+conf.Wide.Context) + logger.Infof("Wide is running [%s]", conf.Wide.Server) - err := http.ListenAndServe(conf.Wide.Server, nil) + listen := conf.Wide.Server[strings.Index(conf.Wide.Server, "://")+3:] + err := http.ListenAndServe(listen, nil) if err != nil { logger.Error(err) } @@ -182,37 +182,34 @@ func main() { // indexHandler handles request of Wide index. func indexHandler(w http.ResponseWriter, r *http.Request) { - if conf.Wide.Context+"/" != r.RequestURI { - http.Redirect(w, r, conf.Wide.Context+"/", http.StatusFound) + if "/" != r.RequestURI { + http.Redirect(w, r, "/", http.StatusFound) return } - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { - http.Redirect(w, r, conf.Wide.Context+"/login", http.StatusFound) + http.Redirect(w, r, "/start", http.StatusFound) return } uid := httpSession.Values["uid"].(string) if "playground" == uid { // reserved user for Playground - http.Redirect(w, r, conf.Wide.Context+"/login", http.StatusFound) + http.Redirect(w, r, "/start", http.StatusFound) return } httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge - if "" != conf.Wide.Context { - httpSession.Options.Path = conf.Wide.Context - } httpSession.Save(r, w) user := conf.GetUser(uid) if nil == user { logger.Warnf("Not found user [%s]", uid) - http.Redirect(w, r, conf.Wide.Context+"/login", http.StatusFound) + http.Redirect(w, r, "/start", http.StatusFound) return } @@ -264,17 +261,14 @@ func serveSingle(pattern string, filename string) { // startHandler handles request of start page. func startHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { - http.Redirect(w, r, conf.Wide.Context+"/login", http.StatusFound) + http.Redirect(w, r, "/login", http.StatusFound) return } httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge - if "" != conf.Wide.Context { - httpSession.Options.Path = conf.Wide.Context - } httpSession.Save(r, w) uid := httpSession.Values["uid"].(string) @@ -304,17 +298,14 @@ func startHandler(w http.ResponseWriter, r *http.Request) { // keyboardShortcutsHandler handles request of keyboard shortcuts page. func keyboardShortcutsHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { - http.Redirect(w, r, conf.Wide.Context+"/login", http.StatusFound) + http.Redirect(w, r, "/start", http.StatusFound) return } httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge - if "" != conf.Wide.Context { - httpSession.Options.Path = conf.Wide.Context - } httpSession.Save(r, w) uid := httpSession.Values["uid"].(string) @@ -336,17 +327,14 @@ func keyboardShortcutsHandler(w http.ResponseWriter, r *http.Request) { // aboutHandle handles request of about page. func aboutHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { - http.Redirect(w, r, conf.Wide.Context+"/login", http.StatusFound) + http.Redirect(w, r, "/login", http.StatusFound) return } httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge - if "" != conf.Wide.Context { - httpSession.Options.Path = conf.Wide.Context - } httpSession.Save(r, w) uid := httpSession.Values["uid"].(string) diff --git a/notification/notifications.go b/notification/notifications.go index d350cb1..580a10c 100644 --- a/notification/notifications.go +++ b/notification/notifications.go @@ -62,7 +62,7 @@ func event2Notification(e *event.Event) { return } - httpSession, _ := session.HTTPSession.Get(wsChannel.Request, "wide-session") + httpSession, _ := session.HTTPSession.Get(wsChannel.Request, session.CookieName) uid := httpSession.Values["uid"].(string) locale := conf.GetUser(uid).Locale diff --git a/output/build.go b/output/build.go index 0125bcd..196b822 100644 --- a/output/build.go +++ b/output/build.go @@ -38,7 +38,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/output/cross.go b/output/cross.go index 3f026fc..a667fd5 100644 --- a/output/cross.go +++ b/output/cross.go @@ -37,7 +37,7 @@ func CrossCompilationHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/output/get.go b/output/get.go index 5585e2f..660b1b9 100644 --- a/output/get.go +++ b/output/get.go @@ -35,7 +35,7 @@ func GoGetHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/output/install.go b/output/install.go index c789427..6bb53ae 100644 --- a/output/install.go +++ b/output/install.go @@ -37,7 +37,7 @@ func GoInstallHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/output/test.go b/output/test.go index 3b30de6..0636aab 100644 --- a/output/test.go +++ b/output/test.go @@ -35,7 +35,7 @@ func GoTestHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/output/vet.go b/output/vet.go index e199cac..2b67b37 100644 --- a/output/vet.go +++ b/output/vet.go @@ -35,7 +35,7 @@ func GoVetHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/playground/autocomplete.go b/playground/autocomplete.go index a766b69..81d5af0 100644 --- a/playground/autocomplete.go +++ b/playground/autocomplete.go @@ -37,7 +37,7 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) { return } - session, _ := session.HTTPSession.Get(r, "wide-session") + session, _ := session.HTTPSession.Get(r, session.CookieName) if session.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/playground/build.go b/playground/build.go index b8d5ad9..873b8e0 100644 --- a/playground/build.go +++ b/playground/build.go @@ -32,7 +32,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/playground/file.go b/playground/file.go index 80b792e..53fdefa 100644 --- a/playground/file.go +++ b/playground/file.go @@ -35,7 +35,7 @@ func SaveHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - session, _ := session.HTTPSession.Get(r, "wide-session") + session, _ := session.HTTPSession.Get(r, session.CookieName) if session.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) @@ -101,7 +101,7 @@ func ShortURLHandler(w http.ResponseWriter, r *http.Request) { result := util.NewResult() defer util.RetResult(w, r, result) - session, _ := session.HTTPSession.Get(r, "wide-session") + session, _ := session.HTTPSession.Get(r, session.CookieName) if session.IsNew { http.Error(w, "Forbidden", http.StatusForbidden) diff --git a/playground/playgrounds.go b/playground/playgrounds.go index c1abad3..3181e16 100644 --- a/playground/playgrounds.go +++ b/playground/playgrounds.go @@ -40,16 +40,13 @@ var logger = log.NewLogger(os.Stdout) // IndexHandler handles request of Playground index. func IndexHandler(w http.ResponseWriter, r *http.Request) { // create a HTTP session - httpSession, _ := session.HTTPSession.Get(r, "wide-session") + httpSession, _ := session.HTTPSession.Get(r, session.CookieName) if httpSession.IsNew { httpSession.Values["id"] = strconv.Itoa(rand.Int()) httpSession.Values["uid"] = "playground" } httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge - if "" != conf.Wide.Context { - httpSession.Options.Path = conf.Wide.Context - } httpSession.Save(r, w) uid := httpSession.Values["uid"].(string) diff --git a/session/oauthctl.go b/session/oauthctl.go index 887057a..a5337d6 100644 --- a/session/oauthctl.go +++ b/session/oauthctl.go @@ -16,13 +16,15 @@ package session import ( "crypto/tls" - "github.com/b3log/wide/conf" "math/rand" "net/http" + "os" + "path/filepath" "strconv" "strings" "time" + "github.com/b3log/wide/conf" "github.com/b3log/wide/util" "github.com/parnurzeal/gorequest" ) @@ -58,6 +60,7 @@ func RedirectGitHubHandler(w http.ResponseWriter, r *http.Request) { if strings.HasSuffix(referer, "/") { referer = referer[:len(referer)-1] } + referer += "__1" state := util.Rand.String(16) + referer states[state] = state path := loginAuthURL + "?client_id=" + clientId + "&state=" + state + "&scope=public_repo,read:user,user:follow" @@ -93,7 +96,7 @@ func GithubCallbackHandler(w http.ResponseWriter, r *http.Request) { githubId := githubUser["userId"].(string) userName := githubUser["userName"].(string) - avatar := githubUser["userAvatar"].(string) + avatar := githubUser["userAvatarURL"].(string) result := util.NewResult() defer util.RetResult(w, r, result) @@ -110,14 +113,10 @@ func GithubCallbackHandler(w http.ResponseWriter, r *http.Request) { } // create a HTTP session - httpSession, _ := HTTPSession.Get(r, "wide-session") + httpSession, _ := HTTPSession.Get(r, CookieName) httpSession.Values["uid"] = githubId - httpSession.Values["id"] = strconv.Itoa(rand.Int()) httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge - if "" != conf.Wide.Context { - httpSession.Options.Path = conf.Wide.Context - } httpSession.Save(r, w) logger.Debugf("Created a HTTP session [%s] for user [%s]", httpSession.Values["id"].(string), githubId) @@ -141,3 +140,140 @@ func GitHubUserInfo(accessToken string) (ret map[string]interface{}) { return result["data"].(map[string]interface{}) } + +// LogoutHandler handles request of user logout (exit). +func LogoutHandler(w http.ResponseWriter, r *http.Request) { + result := util.NewResult() + defer util.RetResult(w, r, result) + + httpSession, _ := HTTPSession.Get(r, CookieName) + + httpSession.Options.MaxAge = -1 + httpSession.Save(r, w) +} + +// addUser add a user with the specified user id, username and avatar. +// +// 1. create the user's workspace +// 2. generate 'Hello, 世界' demo code in the workspace (a console version and a HTTP version) +// 3. update the user customized configurations, such as style.css +// 4. serve files of the user's workspace via HTTP +// +// Note: user [playground] is a reserved mock user +func addUser(userId, userName, userAvatar string) string { + if !conf.Wide.AllowRegister { + return notAllowRegister + } + + if "playground" == userId { + return userExists + } + + addUserMutex.Lock() + defer addUserMutex.Unlock() + + for _, user := range conf.Users { + if strings.ToLower(user.Id) == strings.ToLower(userId) { + return userExists + } + } + + workspace := filepath.Join(conf.Wide.UsersWorkspaces, userId) + newUser := conf.NewUser(userId, userName, userAvatar, workspace) + conf.Users = append(conf.Users, newUser) + if !newUser.Save() { + return userCreateError + } + + conf.CreateWorkspaceDir(workspace) + helloWorld(workspace) + conf.UpdateCustomizedConf(userId) + + http.Handle("/workspace/"+userId+"/", + http.StripPrefix("/workspace/"+userId+"/", http.FileServer(http.Dir(newUser.WorkspacePath())))) + + logger.Infof("Created a user [%s]", userId) + + return userCreated +} + +// helloWorld generates the 'Hello, 世界' source code. +// 1. src/hello/main.go +// 2. src/web/main.go +func helloWorld(workspace string) { + consoleHello(workspace) + webHello(workspace) +} + +func consoleHello(workspace string) { + dir := workspace + conf.PathSeparator + "src" + conf.PathSeparator + "hello" + if err := os.MkdirAll(dir, 0755); nil != err { + logger.Error(err) + + return + } + + fout, err := os.Create(dir + conf.PathSeparator + "main.go") + if nil != err { + logger.Error(err) + + return + } + + fout.WriteString(conf.HelloWorld) + + fout.Close() +} + +func webHello(workspace string) { + dir := workspace + conf.PathSeparator + "src" + conf.PathSeparator + "web" + if err := os.MkdirAll(dir, 0755); nil != err { + logger.Error(err) + + return + } + + fout, err := os.Create(dir + conf.PathSeparator + "main.go") + if nil != err { + logger.Error(err) + + return + } + + code := `package main + +import ( + "fmt" + "math/rand" + "net/http" + "strconv" + "time" +) + +func main() { + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("Hello, 世界")) + }) + + port := getPort() + + // you may need to change the address + fmt.Println("Open https://wide.b3log.org:" + port + " in your browser to see the result") + + if err := http.ListenAndServe(":"+port, nil); nil != err { + fmt.Println(err) + } +} + +func getPort() string { + rand.Seed(time.Now().UnixNano()) + + return strconv.Itoa(7000 + rand.Intn(8000-7000)) +} + +` + + fout.WriteString(code) + + fout.Close() +} diff --git a/session/sessions.go b/session/sessions.go index 4eb2f6f..1e2c416 100644 --- a/session/sessions.go +++ b/session/sessions.go @@ -47,6 +47,8 @@ import ( const ( sessionStateActive = iota sessionStateClosed // (not used so far) + + CookieName = "wide-sess" ) // Logger. @@ -220,7 +222,7 @@ func WSHandler(w http.ResponseWriter, r *http.Request) { wSession := WideSessions.Get(sid) if nil == wSession { - httpSession, _ := HTTPSession.Get(r, "wide-session") + httpSession, _ := HTTPSession.Get(r, CookieName) if httpSession.IsNew { return diff --git a/session/users.go b/session/users.go index 6f60255..7ea242e 100644 --- a/session/users.go +++ b/session/users.go @@ -17,7 +17,6 @@ package session import ( "encoding/json" "net/http" - "os" "path/filepath" "runtime" "strings" @@ -44,18 +43,15 @@ var addUserMutex sync.Mutex // PreferenceHandler handles request of preference page. func PreferenceHandler(w http.ResponseWriter, r *http.Request) { - httpSession, _ := HTTPSession.Get(r, "wide-session") + httpSession, _ := HTTPSession.Get(r, CookieName) if httpSession.IsNew { - http.Redirect(w, r, conf.Wide.Context+"/login", http.StatusFound) + http.Redirect(w, r, "/start", http.StatusFound) return } httpSession.Options.MaxAge = conf.Wide.HTTPSessionMaxAge - if "" != conf.Wide.Context { - httpSession.Options.Path = conf.Wide.Context - } httpSession.Save(r, w) uid := httpSession.Values["uid"].(string) @@ -154,17 +150,6 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) { result.Succ = user.Save() } -// LogoutHandler handles request of user logout (exit). -func LogoutHandler(w http.ResponseWriter, r *http.Request) { - result := util.NewResult() - defer util.RetResult(w, r, result) - - httpSession, _ := HTTPSession.Get(r, "wide-session") - - httpSession.Options.MaxAge = -1 - httpSession.Save(r, w) -} - // FixedTimeSave saves online users' configurations periodically (1 minute). // // Main goal of this function is to save user session content, for restoring session content while user open Wide next time. @@ -230,129 +215,3 @@ func getOnlineUsers() []*conf.User { return ret } - -// addUser add a user with the specified user id, username and avatar. -// -// 1. create the user's workspace -// 2. generate 'Hello, 世界' demo code in the workspace (a console version and a HTTP version) -// 3. update the user customized configurations, such as style.css -// 4. serve files of the user's workspace via HTTP -// -// Note: user [playground] is a reserved mock user -func addUser(userId, userName, userAvatar string) string { - if !conf.Wide.AllowRegister { - return notAllowRegister - } - - if "playground" == userId { - return userExists - } - - addUserMutex.Lock() - defer addUserMutex.Unlock() - - for _, user := range conf.Users { - if strings.ToLower(user.Id) == strings.ToLower(userId) { - return userExists - } - } - - workspace := filepath.Join(conf.Wide.UsersWorkspaces, userId) - newUser := conf.NewUser(userId, userName, userAvatar, workspace) - conf.Users = append(conf.Users, newUser) - if !newUser.Save() { - return userCreateError - } - - conf.CreateWorkspaceDir(workspace) - helloWorld(workspace) - conf.UpdateCustomizedConf(userId) - - http.Handle("/workspace/"+userId+"/", - http.StripPrefix("/workspace/"+userId+"/", http.FileServer(http.Dir(newUser.WorkspacePath())))) - - logger.Infof("Created a user [%s]", userId) - - return userCreated -} - -// helloWorld generates the 'Hello, 世界' source code. -// 1. src/hello/main.go -// 2. src/web/main.go -func helloWorld(workspace string) { - consoleHello(workspace) - webHello(workspace) -} - -func consoleHello(workspace string) { - dir := workspace + conf.PathSeparator + "src" + conf.PathSeparator + "hello" - if err := os.MkdirAll(dir, 0755); nil != err { - logger.Error(err) - - return - } - - fout, err := os.Create(dir + conf.PathSeparator + "main.go") - if nil != err { - logger.Error(err) - - return - } - - fout.WriteString(conf.HelloWorld) - - fout.Close() -} - -func webHello(workspace string) { - dir := workspace + conf.PathSeparator + "src" + conf.PathSeparator + "web" - if err := os.MkdirAll(dir, 0755); nil != err { - logger.Error(err) - - return - } - - fout, err := os.Create(dir + conf.PathSeparator + "main.go") - if nil != err { - logger.Error(err) - - return - } - - code := `package main - -import ( - "fmt" - "math/rand" - "net/http" - "strconv" - "time" -) - -func main() { - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("Hello, 世界")) - }) - - port := getPort() - - // you may need to change the address - fmt.Println("Open https://wide.b3log.org:" + port + " in your browser to see the result") - - if err := http.ListenAndServe(":"+port, nil); nil != err { - fmt.Println(err) - } -} - -func getPort() string { - rand.Seed(time.Now().UnixNano()) - - return strconv.Itoa(7000 + rand.Intn(8000-7000)) -} - -` - - fout.WriteString(code) - - fout.Close() -} diff --git a/views/about.html b/views/about.html index fae6b25..a01af43 100644 --- a/views/about.html +++ b/views/about.html @@ -1,6 +1,6 @@
- +

Hello, 世界

Coding with Go on the Wide way.

diff --git a/views/index.html b/views/index.html index 84febd0..a18cdb4 100644 --- a/views/index.html +++ b/views/index.html @@ -8,27 +8,27 @@ {{if eq $.conf.RuntimeMode "dev"}} - - - - - - + + + + + + {{range $index, $theme := .editorThemes}} - {{end}} - - - - - - + {{end}} + + + + + + {{else}} - - + + {{end}} - - - + + + @@ -347,7 +347,7 @@
  @@ -560,7 +560,7 @@ {{if eq $.conf.RuntimeMode "dev"}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + {{else}} - - + + {{end}} - - + + diff --git a/views/playground/index.html b/views/playground/index.html index a0d3fe0..8de6671 100644 --- a/views/playground/index.html +++ b/views/playground/index.html @@ -8,20 +8,20 @@ - - - - - + + + + + - - - - - - - - + + + + + + + + @@ -30,7 +30,7 @@
  • -
  • @@ -84,7 +84,7 @@ - - + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - + + + diff --git a/views/preference.html b/views/preference.html index 2d09ffc..2e74cd3 100644 --- a/views/preference.html +++ b/views/preference.html @@ -115,7 +115,7 @@