func ArticleListHandler(ctx *app.Context) { data := map[string]interface{}{ "Articles": getArticles(ctx), "Title": ctx.App().Name(), } ctx.MustExecute("list.html", data) }
func decodeResetPayload(ctx *app.Context, payload string) (reflect.Value, error) { se, err := ctx.App().EncryptSigner(Salt) if err != nil { return reflect.Value{}, err } value, err := se.UnsignDecrypt(payload) if err != nil { return reflect.Value{}, err } qs, err := url.ParseQuery(string(value)) if err != nil { return reflect.Value{}, err } userId, err := strconv.ParseInt(qs.Get("u"), 36, 64) if err != nil { return reflect.Value{}, err } ts, err := strconv.ParseInt(qs.Get("t"), 36, 64) if err != nil { return reflect.Value{}, err } if time.Since(time.Unix(ts, 0)) > PasswordResetExpiry { return reflect.Value{}, errResetExpired } user, userVal := newEmptyUser(ctx) ok := ctx.Orm().MustOne(orm.Eq("User.UserId", userId), userVal) if !ok { return reflect.Value{}, errNoSuchUser } return user, nil }
func printResources(ctx *app.Context) { // TODO: Define an interface in package vfs, so this fails // if the interface is changed or renamed. type rooter interface { Root() string } var assets string var templates string if mgr := ctx.App().AssetsManager(); mgr != nil { if r, ok := mgr.VFS().(rooter); ok { assets = r.Root() } } if r, ok := ctx.App().TemplatesFS().(rooter); ok { templates = r.Root() } resources := map[string]string{ "assets": assets, "templates": templates, } data, err := json.Marshal(resources) if err != nil { panic(err) } fmt.Println(string(data)) }
func getGeoIPRecord(ctx *app.Context) *geoip.Record { if rec, _ := ctx.Get(recordKey).(*geoip.Record); rec != nil { return rec } g, _ := ctx.App().Get(geoIPKey).(*geoip.GeoIP) if g == nil { log.Warning("no GeoIP data loaded - did you call geoip.Load()?") return nil } rec, _ := g.Lookup(ctx.RemoteAddress()) ctx.Set(recordKey, rec) return rec }
func ArticleHandler(ctx *app.Context) { slug := ctx.IndexValue(0) var art *article.Article articles := getArticles(ctx) for _, v := range articles { if v.Slug() == slug { art = v break } } if art == nil { for _, v := range articles { for _, s := range v.AllSlugs() { if s == slug { ctx.MustRedirectReverse(true, ctx.HandlerName(), s) return } } } ctx.NotFound("article not found") return } fs := vfs.Memory() filename := path.Base(art.Filename) if filename == "" { filename = "article.html" } if err := vfs.WriteFile(fs, filename, art.Text, 0644); err != nil { panic(err) } log.Debugf("loading article %s", articleId(art)) tmpl, err := app.LoadTemplate(ctx.App(), fs, nil, filename) if err != nil { panic(err) } var buf bytes.Buffer if err := tmpl.ExecuteTo(&buf, ctx, nil); err != nil { panic(err) } body := buf.String() data := map[string]interface{}{ "Article": art, "Title": art.Title(), "Body": template.HTML(body), } ctx.MustExecute("article.html", data) }
func makeAssets(ctx *app.Context) { a := ctx.App() if cfg := a.Config(); cfg != nil { cfg.TemplateDebug = false } err := vfs.Walk(a.TemplatesFS(), "/", func(fs vfs.VFS, p string, info os.FileInfo, err error) error { if err != nil || info.IsDir() || p == "" || p[0] == '.' { return err } if _, err := a.LoadTemplate(p); err != nil { log.Errorf("error loading template %s: %s", p, err) } return nil }) if err != nil { log.Errorf("error listing templates: %s", err) } }
func renderTemplate(ctx *app.Context) { var template string ctx.MustParseIndexValue(0, &template) tmpl, err := ctx.App().LoadTemplate(template) if err != nil { panic(err) } var buf bytes.Buffer if err := tmpl.ExecuteTo(&buf, ctx, nil); err != nil { panic(err) } var output string ctx.ParseParamValue("o", &output) if output == "" || output == "-" { fmt.Print(buf.String()) } else { if err := ioutil.WriteFile(output, buf.Bytes(), 0644); err != nil { panic(err) } } }
func csrfEncryptSigner(ctx *app.Context, salt string) (*cryptoutil.EncryptSigner, error) { a := ctx.App() signer, err := a.Signer([]byte(salt)) if err != nil { return nil, err } encrypter, _ := a.Encrypter() if encrypter == nil { var key []byte cfg := a.Config() if cfg == nil || cfg.Secret == "" { return nil, errors.New("can't generate CSRF tokens, App configuration has no Secret") } if len(cfg.EncryptionKey) > 0 { key = []byte(cfg.EncryptionKey) } else { s := sha256.New() s.Write([]byte(cfg.Secret)) key = s.Sum(nil) } encrypter = &cryptoutil.Encrypter{Cipherer: a.Cipherer, Key: key} } return &cryptoutil.EncryptSigner{Encrypter: encrypter, Signer: signer}, nil }
// Data is a shorthand for AppData(ctx.App()) func Data(ctx *app.Context) interface{} { return AppData(ctx.App()) }
func reverseArticle(ctx *app.Context, article interface{}) (string, error) { return reverseAppArticle(ctx.App(), article) }
func forgotHandler(ctx *app.Context) { d := data(ctx) if !d.allowDirectSignIn() { ctx.NotFound("") return } var user User var isEmail bool var sent bool var fields struct { Username string `form:",singleline,label=Username or Email"` ValidateUsername func(*app.Context) error } fields.ValidateUsername = func(c *app.Context) error { username := Normalize(fields.Username) isEmail = strings.Contains(username, "@") var field string if isEmail { field = "User.NormalizedEmail" } else { field = "User.NormalizedUsername" } userVal, userIface := newEmptyUser(ctx) ok := c.Orm().MustOne(orm.Eq(field, username), userIface) if !ok { if isEmail { return i18n.Errorf("address %q does not belong to any registered user", username) } return i18n.Errorf("username %q does not belong to any registered user", username) } user = getUserValue(userVal, "User").(User) if user.Email == "" { return i18n.Errorf("username %q does not have any registered emails", username) } return nil } f := form.New(ctx, &fields) if f.Submitted() && f.IsValid() { se, err := ctx.App().EncryptSigner(Salt) if err != nil { panic(err) } values := make(url.Values) values.Add("u", strconv.FormatInt(user.Id(), 36)) values.Add("t", strconv.FormatInt(time.Now().Unix(), 36)) values.Add("n", stringutil.Random(64)) payload := values.Encode() p, err := se.EncryptSign([]byte(payload)) if err != nil { panic(err) } abs := ctx.URL() reset := fmt.Sprintf("%s://%s%s?p=%s", abs.Scheme, abs.Host, ctx.MustReverse(ResetHandlerName), p) data := map[string]interface{}{ "URL": reset, } from := mail.DefaultFrom() if from == "" { from = fmt.Sprintf("no-reply@%s", abs.Host) } msg := &mail.Message{ To: user.Email, From: from, Subject: fmt.Sprintf(ctx.T("Reset your %s password"), d.opts.SiteName), } ctx.MustSendMail("reset_password.txt", data, msg) sent = true } data := map[string]interface{}{ "ForgotForm": f, "IsEmail": isEmail, "Sent": sent, "User": user, } ctx.MustExecute(ForgotTemplateName, data) }
func data(ctx *app.Context) *appData { d, _ := reusableapp.AppDataWithKey(ctx.App(), appDataKey).(*appData) return d }
// Execute runs the given handler in a task context. If the handler fails // with a panic, it will be returned in the error return value. func Execute(ctx *app.Context, handler app.Handler) error { t := &Task{App: ctx.App(), Handler: handler} _, err := executeTask(ctx, t) return err }
func SourceHandler(ctx *app.Context) { dctx := doc.GetEnvironment(ctx.App()) rel := ctx.IndexValue(0) p := dctx.FromSlash(rel) pDir := dctx.Dir(p) if pDir == "." { pDir = p } else { } dir := packageDir(dctx, pDir) filePath := dir if pDir+dctx.Separator != p && pDir != p { filePath = dctx.Join(dir, dctx.Base(p)) } log.Debugf("Loading source from %s", filePath) var breadcrumbs []*breadcrumb for ii := 0; ii < len(rel); { var end int slash := strings.IndexByte(rel[ii:], '/') if slash < 0 { end = len(rel) } else { end = ii + slash } breadcrumbs = append(breadcrumbs, &breadcrumb{ Title: rel[ii:end], Href: ctx.MustReverse(SourceHandlerName, rel[:end]), }) ii = end + 1 } var tmpl string var title string var files []string var code template.HTML var lines []int if dctx.IsDir(filePath) { if rel != "" && rel[len(rel)-1] != '/' { ctx.MustRedirectReverse(true, SourceHandlerName, rel+"/") return } contents, err := dctx.ReadDir(filePath) if err != nil { panic(err) } for _, v := range contents { if n := v.Name(); len(n) > 0 && n[0] != '.' { files = append(files, n) } } title = "Directory " + dctx.Base(rel) tmpl = "dir.html" } else { f, err := dctx.OpenFile(filePath) if err != nil { ctx.NotFound("File not found") return } defer f.Close() contents, err := ioutil.ReadAll(f) if err != nil { panic(err) } contentType := http.DetectContentType(contents) if !strings.HasPrefix(contentType, "text") { ctx.Header().Set("Content-Type", contentType) switch contentType { case "image/gif", "image/png", "image/jpeg": default: ctx.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s;", dctx.Base(rel))) } ctx.Write(contents) return } title = "File " + dctx.Base(rel) var buf bytes.Buffer buf.WriteString("<span id=\"line-1\">") last := 0 line := 1 for ii, v := range contents { if v == '\n' { buf.WriteString(html.Escape(string(contents[last:ii]))) lines = append(lines, line) last = ii line++ buf.WriteString(fmt.Sprintf("</span><span id=\"line-%d\">", line)) } } buf.Write(contents[last:]) buf.WriteString("</span>") code = template.HTML(buf.String()) tmpl = "source.html" } data := map[string]interface{}{ "Title": rel, "Header": title, "Breadcrumbs": breadcrumbs, "Files": files, "Code": code, "Lines": lines, "Padding": math.Ceil(math.Log10(float64(len(lines)+1))) + 0.1, "Highlighter": highlighters[path.Ext(rel)], } ctx.MustExecute(tmpl, data) }