// Logout deletes all sessions,then redirects to "/". // // Method POST // // Route /auth/logout // // Restrictions None // // Template None (All actions redirect to other routes ) // // Flash messages may be set before redirection. func Logout(ctx *echo.Context) error { utils.DeleteSession(ctx, settings.App.Session.Lang) utils.DeleteSession(ctx, settings.App.Session.Flash) utils.DeleteSession(ctx, settings.App.Session.Name) ctx.Redirect(http.StatusFound, "/") return nil }
// Modify 修改主题 func (TopicController) Modify(ctx echo.Context) error { tid := goutils.MustInt(ctx.FormValue("tid")) if tid == 0 { return ctx.Redirect(http.StatusSeeOther, "/topics") } nodes := logic.GenNodes() if ctx.Request().Method() != "POST" { topics := logic.DefaultTopic.FindByTids([]int{tid}) if len(topics) == 0 { return ctx.Redirect(http.StatusSeeOther, "/topics") } return render(ctx, "topics/new.html", map[string]interface{}{"nodes": nodes, "topic": topics[0], "activeTopics": "active"}) } me := ctx.Get("user").(*model.Me) err := logic.DefaultTopic.Publish(ctx, me, ctx.FormParams()) if err != nil { if err == logic.NotModifyAuthorityErr { return fail(ctx, 1, "没有权限操作") } return fail(ctx, 2, "服务错误,请稍后重试!") } return success(ctx, nil) }
// 消息列表 func (MessageController) ReadList(ctx echo.Context) error { user := ctx.Get("user").(*model.Me) msgtype := ctx.Param("msgtype") if msgtype == "" { msgtype = "system" } curPage := goutils.MustInt(ctx.QueryParam("p"), 1) paginator := logic.NewPaginator(curPage) var ( messages []map[string]interface{} total int64 ) switch msgtype { case "system": messages = logic.DefaultMessage.FindSysMsgsByUid(ctx, user.Uid, paginator) total = logic.DefaultMessage.SysMsgCount(ctx, user.Uid) case "inbox": messages = logic.DefaultMessage.FindToMsgsByUid(ctx, user.Uid, paginator) total = logic.DefaultMessage.ToMsgCount(ctx, user.Uid) case "outbox": messages = logic.DefaultMessage.FindFromMsgsByUid(ctx, user.Uid, paginator) total = logic.DefaultMessage.FromMsgCount(ctx, user.Uid) default: return ctx.Redirect(http.StatusSeeOther, "/") } pageHtml := paginator.SetTotal(total).GetPageHtml(fmt.Sprintf("/message/%s", msgtype)) return render(ctx, "messages/list.html", map[string]interface{}{"messages": messages, "msgtype": msgtype, "page": template.HTML(pageHtml)}) }
// Detail 文章详细页 func (ArticleController) Detail(ctx echo.Context) error { article, prevNext, err := logic.DefaultArticle.FindByIdAndPreNext(ctx, goutils.MustInt(ctx.Param("id"))) if err != nil { return ctx.Redirect(http.StatusSeeOther, "/articles") } if article == nil || article.Id == 0 || article.Status == model.ArticleStatusOffline { return ctx.Redirect(http.StatusSeeOther, "/articles") } likeFlag := 0 hadCollect := 0 me, ok := ctx.Get("user").(*model.Me) if ok { likeFlag = logic.DefaultLike.HadLike(ctx, me.Uid, article.Id, model.TypeArticle) hadCollect = logic.DefaultFavorite.HadFavorite(ctx, me.Uid, article.Id, model.TypeArticle) } logic.Views.Incr(Request(ctx), model.TypeArticle, article.Id) // 为了阅读数即时看到 article.Viewnum++ return render(ctx, "articles/detail.html,common/comment.html", map[string]interface{}{"activeArticles": "active", "article": article, "prev": prevNext[0], "next": prevNext[1], "likeflag": likeFlag, "hadcollect": hadCollect}) }
// RegisterPost handles registration form, and create a session for the new user if the registration // process is complete. // // Method POST // // Route /auth/register // // Restrictions None // // Template None (All actions redirect to other routes ) // // Flash messages may be set before redirection. func RegisterPost(ctx *echo.Context) error { var flashMessages = flash.New() f := forms.New(utils.GetLang(ctx)) lf := f.RegisterForm()(ctx.Request()) if !lf.IsValid() { // Case the form is not valid, ships it back with the errors exclusively utils.SetData(ctx, authForm, lf) return ctx.Render(http.StatusOK, tmpl.RegisterTpl, utils.GetData(ctx)) } // we are not interested in the returned user, rather we make sure the user has // been created. _, err := query.CreateNewUser(lf.GetModel().(forms.Register)) if err != nil { flashMessages.Err(msgAccountCreateFailed) flashMessages.Save(ctx) ctx.Redirect(http.StatusFound, "/auth/register") return nil } // TODO: improve the message to include directions to use the current email and // password to login? flashMessages.Success(msgAccountCreate) flashMessages.Save(ctx) // Don't create session in this route, its best to leave only one place which // messes with the main user session. So we redirect to the login page, and encourage // the user to login. ctx.Redirect(http.StatusFound, "/auth/login") return nil }
func (self InstallController) SetupConfig(ctx echo.Context) error { // config/env.ini 存在 if db.MasterDB != nil { if logic.DefaultInstall.IsTableExist(ctx) { return ctx.Redirect(http.StatusSeeOther, "/") } return ctx.Redirect(http.StatusSeeOther, "/install/do") } step := goutils.MustInt(ctx.QueryParam("step")) if step == 2 { err := self.genConfig(ctx) if err != nil { data := map[string]interface{}{ "dbhost": ctx.FormValue("dbhost"), "dbport": ctx.FormValue("dbport"), "dbname": ctx.FormValue("dbname"), "uname": ctx.FormValue("uname"), "err_type": 1, } if err == db.ConnectDBErr { data["err_type"] = 1 } else if err == db.UseDBErr { data["err_type"] = 2 } return renderInstall(ctx, "install/setup-err.html", data) } } return renderInstall(ctx, "install/setup-config.html", map[string]interface{}{"step": step}) }
func helloFlash(ctx *echo.Context) error { flashMessages := flash.New() flashMessages.Success(message) flashMessages.Save(ctx) ctx.Redirect(http.StatusFound, "/home") return nil }
// Delete deletes the resume. // // Method POST // // Route /resume/delete/:id // // Restrictions Yes // // Template None func Delete(ctx *echo.Context) error { var flashMessages = flash.New() id, err := utils.GetInt(ctx.Param("id")) if err != nil { utils.SetData(ctx, "Message", tmpl.BadRequestMessage) return ctx.Render(http.StatusBadRequest, tmpl.ErrBadRequest, utils.GetData(ctx)) } user := ctx.Get("User").(*models.Person) resume, err := query.GetResumeByID(id) if err != nil { utils.SetData(ctx, "Message", tmpl.NotFoundMessage) return ctx.Render(http.StatusNotFound, tmpl.ErrNotFoundTpl, tmpl.NotFoundMessage) } // Users are allowed to delete resumes that they don't own. if resume.PersonID != user.ID { utils.SetData(ctx, "Message", tmpl.BadRequestMessage) return ctx.Render(http.StatusBadRequest, tmpl.ErrBadRequest, utils.GetData(ctx)) } err = query.Delete(resume) if err != nil { utils.SetData(ctx, "Message", tmpl.ServerErrorMessage) return ctx.Render(http.StatusInternalServerError, tmpl.ErrServerTpl, utils.GetData(ctx)) } flashMessages.Success("resume successful deleted") flashMessages.Save(ctx) ctx.Redirect(http.StatusFound, "/resume/") return nil }
// Logout 注销 func (AccountController) Logout(ctx echo.Context) error { // 删除cookie信息 session := GetCookieSession(ctx) session.Options = &sessions.Options{Path: "/", MaxAge: -1} session.Save(Request(ctx), ResponseWriter(ctx)) // 重定向得到登录页(TODO:重定向到什么页面比较好?) return ctx.Redirect(http.StatusSeeOther, "/account/login") }
func Login(context echo.Context) error { _, err := helpers.ValidateJWT(context) if err != nil { return context.Render(http.StatusOK, "login", os.Getenv("AUTH0_CALLBACK")) } context.Redirect(http.StatusMovedPermanently, "/frontend") return context.String(http.StatusOK, "Done") }
func (a *Application) logout(c *echo.Context) error { loginCookie, err := c.Request().Cookie("login") if err != nil { fmt.Println(err) } else { a.Redis.RemoveSession(loginCookie.Value) http.SetCookie(c.Response(), &http.Cookie{Name: "login", MaxAge: -1}) } return c.Redirect(302, "/") }
// ReadList 开源项目列表页 func (ProjectController) ReadList(ctx echo.Context) error { limit := 20 lastId := goutils.MustInt(ctx.QueryParam("lastid")) projects := logic.DefaultProject.FindBy(ctx, limit+5, lastId) num := len(projects) if num == 0 { if lastId == 0 { return ctx.Redirect(http.StatusSeeOther, "/") } else { return ctx.Redirect(http.StatusSeeOther, "/projects") } } var ( hasPrev, hasNext bool prevId, nextId int ) if lastId > 0 { prevId = lastId // 避免因为项目下线,导致判断错误(所以 > 5) if prevId-projects[0].Id > 5 { hasPrev = false } else { prevId += limit hasPrev = true } } if num > limit { hasNext = true projects = projects[:limit] nextId = projects[limit-1].Id } else { nextId = projects[num-1].Id } pageInfo := map[string]interface{}{ "has_prev": hasPrev, "prev_id": prevId, "has_next": hasNext, "next_id": nextId, } // 获取当前用户喜欢对象信息 me, ok := ctx.Get("user").(*model.Me) var likeFlags map[int]int if ok { likeFlags, _ = logic.DefaultLike.FindUserLikeObjects(ctx, me.Uid, model.TypeProject, projects[0].Id, nextId) } return render(ctx, "projects/list.html", map[string]interface{}{"projects": projects, "activeProjects": "active", "page": pageInfo, "likeflags": likeFlags}) }
func (h *handler) OauthCallbackHandler(c *echo.Context) error { code := c.Query("code") token, err := oauthConf.Exchange(oauth2.NoContext, code) if err != nil { log.Println(err.Error(), "Can't exchange token") return c.Redirect(http.StatusTemporaryRedirect, "/") } oauthClient := oauthConf.Client(oauth2.NoContext, token) client := github.NewClient(oauthClient) user, _, err := client.Users.Get("") if err != nil { log.Println(err.Error(), "Can't get user") return c.Redirect(http.StatusTemporaryRedirect, "/") } userLogin := *user.Login userToken := token.AccessToken u := &model.UserRow{ Login: userLogin, Token: userToken, AvatarURL: *user.AvatarURL, } ci, err := h.back.Model.User.CreateOrUpdate(u) if err != nil { log.Println(err.Error(), "Can't create user") return c.Redirect(http.StatusTemporaryRedirect, "/") } s := session.Default(c) if ci.Updated == 0 { s.Set("just_signup", true) } else { u, err = h.back.Model.User.GetByLogin(userLogin) if err != nil { return c.Redirect(http.StatusTemporaryRedirect, "/") } } var buf bytes.Buffer enc := json.NewEncoder(&buf) enc.Encode(*u) s.Set("username", userLogin) s.Set("user", buf.String()) // hack to display username in header http.SetCookie(c.Response(), &http.Cookie{Name: "username", Value: userLogin, Path: "/"}) http.SetCookie(c.Response(), &http.Cookie{Name: "useravatar", Value: *user.AvatarURL, Path: "/"}) s.Set("token", userToken) s.Save() return c.Redirect(http.StatusFound, "/dashboard") }
func (h *handler) OauthRequestHandler(c *echo.Context) error { s := session.Default(c) if s.Get("user") != nil { return c.Redirect(http.StatusFound, "/dashboard") } oauthConf.ClientID = h.cfg.Github.ClientId oauthConf.ClientSecret = h.cfg.Github.ClientSecret oauthStateString := "random_string" url := oauthConf.AuthCodeURL(oauthStateString, oauth2.AccessTypeOnline) return c.Redirect(http.StatusTemporaryRedirect, url) }
func (handlerGroup *HandlerGroup) CallbackHandler(context echo.Context) error { domain := "jessemillar.auth0.com" // Instantiating the OAuth2 package to exchange the Code for a Token conf := &oauth2.Config{ ClientID: os.Getenv("AUTH0_CLIENT_ID"), ClientSecret: os.Getenv("AUTH0_CLIENT_SECRET"), RedirectURL: os.Getenv("AUTH0_CALLBACK"), Scopes: []string{"openid", "name", "email", "nickname"}, Endpoint: oauth2.Endpoint{ AuthURL: "https://" + domain + "/authorize", TokenURL: "https://" + domain + "/oauth/token", }, } // Getting the Code that we got from Auth0 code := context.QueryParam("code") // Exchanging the code for a token token, err := conf.Exchange(oauth2.NoContext, code) if err != nil { return context.String(http.StatusInternalServerError, err.Error()) } // Getting the user information client := conf.Client(oauth2.NoContext, token) resp, err := client.Get("https://" + domain + "/userinfo") if err != nil { return context.String(http.StatusInternalServerError, err.Error()) } // Reading the body raw, err := ioutil.ReadAll(resp.Body) defer resp.Body.Close() if err != nil { return context.String(http.StatusInternalServerError, err.Error()) } // Unmarshal the JSON of the Auth0 profile var profile map[string]interface{} if err := json.Unmarshal(raw, &profile); err != nil { return context.String(http.StatusInternalServerError, err.Error()) } helpers.MakeCookie(context, "id_token", token.Extra("id_token").(string)) // Redirect to logged in page context.Redirect(http.StatusMovedPermanently, "/frontend") return context.String(http.StatusOK, "Callback finished") // We'll never actually hit this...? }
// DoContact adds a new contact message into database and sends an email func DoContact(c *echo.Context) error { var contact models.Contact var err error contact.Name = c.Form("name") contact.Email = c.Form("email") contact.Company = c.Form("company") contact.Reason = c.Form("text") if contact.Name == "" { return c.Redirect(302, fmt.Sprintf("/contact?error=%s", url.QueryEscape("Empty contact name"))) } if contact.Reason == "" { return c.Redirect(302, fmt.Sprintf("/contact?error=%s", url.QueryEscape("Empty contact text"))) } _, err = database.Current.NamedExec(database.Queries.InsertContact, contact) if err != nil { log.Println(database.Queries.InsertContact) log.Println("Cannot insert new contact data:", err) return c.Redirect(302, fmt.Sprintf("/contact?error=%s", url.QueryEscape("Cannot create your comment"))) } return c.Redirect(302, fmt.Sprintf("/contact?msg=%s", url.QueryEscape("Thank you! We will contact you back in a few hours."))) }
// ResetPasswd 重置密码 func (AccountController) ResetPasswd(ctx echo.Context) error { if _, ok := ctx.Get("user").(*model.Me); ok { return ctx.Redirect(http.StatusSeeOther, "/") } uuid := ctx.FormValue("code") if uuid == "" { return ctx.Redirect(http.StatusSeeOther, "/") } contentTpl := "user/reset_pwd.html" data := map[string]interface{}{"activeUsers": "active"} method := ctx.Request().Method() passwd := ctx.FormValue("passwd") email, ok := resetPwdMap[uuid] if !ok { // 是提交重置密码 if passwd != "" && method == "POST" { data["error"] = template.HTML(`非法请求!<p>将在<span id="jumpTo">3</span>秒后跳转到<a href="/" id="jump_url">首页</a></p>`) } else { data["error"] = template.HTML(`链接无效或过期,请重新操作。<a href="/account/forgetpwd">忘记密码?</a>`) } return render(ctx, contentTpl, data) } data["valid"] = true data["code"] = uuid // 提交修改密码 if passwd != "" && method == "POST" { // 简单校验 if len(passwd) < 6 || len(passwd) > 32 { data["error"] = "密码长度必须在6到32个字符之间" } else if passwd != ctx.FormValue("pass2") { data["error"] = "两次密码输入不一致" } else { // 更新密码 _, err := logic.DefaultUser.ResetPasswd(ctx, email, passwd) if err != nil { data["error"] = "对不起,服务器错误,请重试!" } else { data["success"] = template.HTML(`密码重置成功,<p>将在<span id="jumpTo">3</span>秒后跳转到<a href="/account/login" id="jump_url">登录</a>页面</p>`) } } } return render(ctx, contentTpl, data) }
// ReadingList 晨读列表页 func (ReadingController) ReadingList(ctx echo.Context) error { limit := 20 lastId := goutils.MustInt(ctx.QueryParam("lastid")) rtype := goutils.MustInt(ctx.QueryParam("rtype"), model.RtypeGo) readings := logic.DefaultReading.FindBy(ctx, limit+5, rtype, lastId) num := len(readings) if num == 0 { if lastId == 0 { return ctx.Redirect(http.StatusSeeOther, "/") } else { return ctx.Redirect(http.StatusSeeOther, "/readings") } } var ( hasPrev, hasNext bool prevId, nextId int ) if lastId > 0 { prevId = lastId // 避免因为项目下线,导致判断错误(所以 > 5) if prevId-readings[0].Id > 5 { hasPrev = false } else { prevId += limit hasPrev = true } } if num > limit { hasNext = true readings = readings[:limit] nextId = readings[limit-1].Id } else { nextId = readings[num-1].Id } pageInfo := map[string]interface{}{ "has_prev": hasPrev, "prev_id": prevId, "has_next": hasNext, "next_id": nextId, } return render(ctx, "readings/list.html", map[string]interface{}{"activeReadings": "active", "readings": readings, "page": pageInfo, "rtype": rtype}) }
func (h *handler) PackageGetHandler(c *echo.Context) error { pName := strings.Replace(c.Request().RequestURI, "/p/", "", -1) p, err := h.back.Model.Package.GetItem(pName) if err != nil { log.Println(err) return c.Redirect(http.StatusTemporaryRedirect, "/") } data := struct { Package model.PackageRow }{ p, } return c.Render(http.StatusOK, "package.html", data) }
// LoginPost handlers login form, and logs in the user. If the form is valid, the user is // redirected to "/auth/login" with the form validation errors. When the user is validated // redirection is made to "/". // // Method POST // // Route /auth/login // // Restrictions None // // Template None (All actions redirect to other routes ) // // Flash messages may be set before redirection. func LoginPost(ctx *echo.Context) error { var flashMessages = flash.New() f := forms.New(utils.GetLang(ctx)) lf := f.LoginForm()(ctx.Request()) if !lf.IsValid() { utils.SetData(ctx, authForm, lf) ctx.Redirect(http.StatusFound, "/auth/login") return nil } // Check email and password user, err := query.AuthenticateUserByEmail(lf.GetModel().(forms.Login)) if err != nil { log.Error(ctx, err) // We want the user to try again, but rather than rendering the form right // away, we redirect him/her to /auth/login route(where the login process with // start aflsesh albeit with a flash message) flashMessages.Err(msgLoginErr) flashMessages.Save(ctx) ctx.Redirect(http.StatusFound, "/auth/login") return nil } // create a session for the user after the validation has passed. The info stored // in the session is the user ID, where as the key is userID. ss, err := sessStore.Get(ctx.Request(), settings.App.Session.Name) if err != nil { log.Error(ctx, err) } ss.Values["userID"] = user.ID err = ss.Save(ctx.Request(), ctx.Response()) if err != nil { log.Error(ctx, err) } person, err := query.GetPersonByUserID(user.ID) if err != nil { log.Error(ctx, err) flashMessages.Err(msgLoginErr) flashMessages.Save(ctx) ctx.Redirect(http.StatusFound, "/auth/login") return nil } // add context data. IsLoged is just a conveniece in template rendering. the User // contains a models.Person object, where the PersonName is already loaded. utils.SetData(ctx, "IsLoged", true) utils.SetData(ctx, "User", person) flashMessages.Success(msgLoginSuccess) flashMessages.Save(ctx) ctx.Redirect(http.StatusFound, "/") log.Info(ctx, "login success") return nil }
func (InstallController) SetupOptions(ctx echo.Context) error { var ( noEmailConf = false noQiniuConf = false ) if config.ConfigFile.MustValue("email", "smtp_username") == "" { noEmailConf = true } if config.ConfigFile.MustValue("qiniu", "access_key") == "" { noQiniuConf = true } if !noEmailConf && !noQiniuConf { return ctx.Redirect(http.StatusSeeOther, "/") } if ctx.Request().Method() == "POST" { config.ConfigFile.SetSectionComments("email", "用于注册发送激活码等") emailFields := []string{"smtp_host", "smtp_port", "smtp_username", "smtp_password", "from_email"} for _, field := range emailFields { if field == "smtp_port" && ctx.FormValue("smtp_port") == "" { config.ConfigFile.SetValue("email", field, "25") } else { config.ConfigFile.SetValue("email", field, ctx.FormValue(field)) } } config.ConfigFile.SetSectionComments("qiniu", "图片存储在七牛云,如果没有可以通过 https://portal.qiniu.com/signup?code=3lfz4at7pxfma 免费申请") qiniuFields := []string{"access_key", "secret_key", "bucket_name"} for _, field := range qiniuFields { config.ConfigFile.SetValue("qiniu", field, ctx.FormValue(field)) } config.SaveConfigFile() return renderInstall(ctx, "install/setup-options.html", map[string]interface{}{"success": true}) } data := map[string]interface{}{ "no_email_conf": noEmailConf, "no_qiniu_conf": noQiniuConf, } return renderInstall(ctx, "install/setup-options.html", data) }
func (h *handler) SearchbackHandler(c *echo.Context) error { searchq := strings.ToLower(c.Query("search")) packages, err := h.back.Model.Package.GetItems(searchq) if err != nil { log.Error(err) return c.Redirect(http.StatusTemporaryRedirect, "/") } if len(searchq) > 50 && len(searchq) < 4 { return c.Redirect(http.StatusBadRequest, "/") } data := struct { Packages []model.PackageRow }{ packages, } return c.Render(http.StatusOK, "search.html", data) }
// SetLanguage switches language, between swahili and english. This means when this // handler is accessed, if the current language is en it will be set to sw and vice versa. // // Method GET // // Route /language/:lang // // Restrictions None // // Template None ( Redirection is made to home route ("/")) func SetLanguage(ctx *echo.Context) error { lang := ctx.Param("lang") var language string switch lang { case "en", "sw": language = lang default: language = "en" } store := session.New() sess, _ := store.Get(ctx.Request(), settings.LangSessionName) sess.Values[settings.LangSessionKey] = language store.Save(ctx.Request(), ctx.Response(), sess) ctx.Redirect(http.StatusFound, "/") return nil }
// Handle handles all HTTP requests which // have no been caught via static file // handler or other middlewares. func (r *React) Handle(c *echo.Context) error { UUID := c.Get("uuid").(*uuid.UUID) defer func() { if r := recover(); r != nil { c.Render(http.StatusInternalServerError, "react.html", Resp{ UUID: UUID.String(), Error: r.(string), }) } }() vm := r.get() start := time.Now() select { case re := <-vm.Handle(map[string]interface{}{ "url": c.Request().URL.String(), "headers": c.Request().Header, "uuid": UUID.String(), }): re.RenderTime = time.Since(start) // Return vm back to the pool r.put(vm) // Handle the Response if len(re.Redirect) == 0 && len(re.Error) == 0 { // If no redirection and no errors c.Response().Header().Set("X-React-Render-Time", fmt.Sprintf("%s", re.RenderTime)) return c.Render(http.StatusOK, "react.html", re) // If redirect } else if len(re.Redirect) != 0 { return c.Redirect(http.StatusMovedPermanently, re.Redirect) // If internal error } else if len(re.Error) != 0 { c.Response().Header().Set("X-React-Render-Time", fmt.Sprintf("%s", re.RenderTime)) return c.Render(http.StatusInternalServerError, "react.html", re) } case <-time.After(2 * time.Second): // release duktape context r.drop(vm) return c.Render(http.StatusInternalServerError, "react.html", Resp{ UUID: UUID.String(), Error: "time is out", }) } return nil }
// WrapUrl 包装链接 func (IndexController) WrapUrl(ctx echo.Context) error { tUrl := ctx.QueryParam("u") if tUrl == "" { return ctx.Redirect(http.StatusSeeOther, "/") } if pUrl, err := url.Parse(tUrl); err != nil { return ctx.Redirect(http.StatusSeeOther, tUrl) } else { if !pUrl.IsAbs() { return ctx.Redirect(http.StatusSeeOther, tUrl) } // 本站 domain := config.ConfigFile.MustValue("global", "domain") if strings.Contains(pUrl.Host, domain) { return ctx.Redirect(http.StatusSeeOther, tUrl) } iframeDeny := config.ConfigFile.MustValue("crawl", "iframe_deny") // 检测是否禁止了 iframe 加载 // 看是否在黑名单中 for _, denyHost := range strings.Split(iframeDeny, ",") { if strings.Contains(pUrl.Host, denyHost) { return ctx.Redirect(http.StatusSeeOther, tUrl) } } // 检测会比较慢,进行异步检测,记录下来,以后分析再加黑名单 go func() { resp, err := http.Head(tUrl) if err != nil { logger.Errorln("[iframe] head url:", tUrl, "error:", err) return } defer resp.Body.Close() if resp.Header.Get("X-Frame-Options") != "" { logger.Errorln("[iframe] deny:", tUrl) return } }() } return render(ctx, "wr.html", map[string]interface{}{"url": tUrl}) }
func (a *Application) verifyEmail(c *echo.Context) error { user := a.Redis.GetUser(c.P(0)) fmt.Println(c.P(0)) fmt.Println(user) if user.EmailVerificationString == c.P(1) { user.EmailVerified = true user.EmailVerifiedDate = time.Now().UTC() user.ModifyDate = time.Now().UTC() userJSON, err := json.Marshal(user) if err != nil { fmt.Println(err) } else { a.Redis.UpdateUser(user.Id, string(userJSON)) } return c.Redirect(302, "/login?verified=true") } return c.Redirect(302, "/login?verified=false") }
// Home 用户个人首页 func (UserController) Home(ctx echo.Context) error { username := ctx.Param("username") user := logic.DefaultUser.FindOne(ctx, "username", username) if user == nil || user.Uid == 0 { return ctx.Redirect(http.StatusSeeOther, "/users") } topics := logic.DefaultTopic.FindRecent(5, user.Uid) resources := logic.DefaultResource.FindRecent(ctx, user.Uid) for _, resource := range resources { resource.CatName = logic.GetCategoryName(resource.Catid) } projects := logic.DefaultProject.FindRecent(ctx, user.Username) comments := logic.DefaultComment.FindRecent(ctx, user.Uid, -1, 5) return render(ctx, "user/profile.html", map[string]interface{}{"activeUsers": "active", "topics": topics, "resources": resources, "projects": projects, "comments": comments, "user": user}) }
// Login 登录 func (AccountController) Login(ctx echo.Context) error { if _, ok := ctx.Get("user").(*model.Me); ok { return ctx.Redirect(http.StatusSeeOther, "/") } // 支持跳转到源页面 uri := ctx.FormValue("redirect_uri") if uri == "" { uri = "/" } contentTpl := "login.html" data := make(map[string]interface{}) username := ctx.FormValue("username") if username == "" || ctx.Request().Method() != "POST" { data["redirect_uri"] = uri return render(ctx, contentTpl, data) } // 处理用户登录 passwd := ctx.FormValue("passwd") userLogin, err := logic.DefaultUser.Login(ctx, username, passwd) if err != nil { data["username"] = username data["error"] = err.Error() if util.IsAjax(ctx) { return fail(ctx, 1, err.Error()) } return render(ctx, contentTpl, data) } // 登录成功,种cookie SetCookie(ctx, userLogin.Username) if util.IsAjax(ctx) { return success(ctx, nil) } return ctx.Redirect(http.StatusSeeOther, uri) }
// Detail 展示wiki页 func (WikiController) Detail(ctx echo.Context) error { wiki := logic.DefaultWiki.FindOne(ctx, ctx.Param("uri")) if wiki == nil { return ctx.Redirect(http.StatusSeeOther, "/wiki") } // likeFlag := 0 // me, ok := ctx.Get("user").(*model.Me) // if ok { // likeFlag = logic.DefaultLike.HadLike(ctx, me.Uid, wiki.Id, model.TypeWiki) // } logic.Views.Incr(Request(ctx), model.TypeWiki, wiki.Id) // 为了阅读数即时看到 wiki.Viewnum++ return render(ctx, "wiki/content.html", map[string]interface{}{"activeWiki": "active", "wiki": wiki}) }
func (a *Application) login(c *echo.Context) error { id := c.Form("Id") user := a.Redis.GetUser(domain.ShaHashString(id)) password := domain.HashPassword([]byte(c.Form("Password")), []byte(id)) sessionKey := domain.HashPassword([]byte(id), []byte(user.CreateDate.String())) if user.Password == password { http.SetCookie(c.Response(), &http.Cookie{Name: "login", Value: sessionKey, MaxAge: 2592000}) userAsJson, err := json.Marshal(user) if err != nil { fmt.Println(err) } else { a.Redis.Put(sessionKey, string(userAsJson)) return c.Redirect(302, "/") } } else { fmt.Println("not a match") } return c.Redirect(302, "/login?failed=true") }