//BindCreate is default create binder func BindCreate(a *Admin, resource *Resource) { resource.ResourceController.Post(a.GetURL(resource, ""), func(request prago.Request) { ValidateCSRF(request) var item interface{} resource.newItem(&item) form, err := resource.StructCache.GetForm(item, GetLocale(request), resource.VisibilityFilter, resource.EditabilityFilter) prago.Must(err) if resource.AfterFormCreated != nil { form = resource.AfterFormCreated(form, request, true) } resource.StructCache.BindData(item, request.Params(), request.Request().MultipartForm, form.getFilter()) if resource.BeforeCreate != nil { if !resource.BeforeCreate(request, item) { return } } prago.Must(a.Create(item)) if resource.AfterCreate != nil { if !resource.AfterCreate(request, item) { return } } AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_item_created")) prago.Redirect(request, a.Prefix+"/"+resource.ID) }) }
//BindDelete is default delete binder func BindDelete(a *Admin, resource *Resource) { resource.ResourceController.Post(a.GetURL(resource, ":id/delete"), func(request prago.Request) { ValidateCSRF(request) id, err := strconv.Atoi(request.Params().Get("id")) prago.Must(err) if resource.BeforeDelete != nil { if !resource.BeforeDelete(request, id) { return } } var item interface{} resource.newItem(&item) _, err = a.Query().WhereIs("id", int64(id)).Delete(item) prago.Must(err) if resource.AfterDelete != nil { if !resource.AfterDelete(request, id) { return } } AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_item_deleted")) prago.Redirect(request, a.Prefix+"/"+resource.ID) }) }
//BindUpdate is default update binder func BindUpdate(a *Admin, resource *Resource) { resource.ResourceController.Post(a.GetURL(resource, ":id"), func(request prago.Request) { ValidateCSRF(request) id, err := strconv.Atoi(request.Params().Get("id")) prago.Must(err) var item interface{} resource.newItem(&item) prago.Must(a.Query().WhereIs("id", int64(id)).Get(item)) form, err := resource.StructCache.GetForm(item, GetLocale(request), resource.VisibilityFilter, resource.EditabilityFilter) prago.Must(err) if resource.AfterFormCreated != nil { form = resource.AfterFormCreated(form, request, false) } err = resource.StructCache.BindData(item, request.Params(), request.Request().MultipartForm, form.getFilter()) prago.Must(err) if resource.BeforeUpdate != nil { if !resource.BeforeUpdate(request, item) { return } } err = a.Save(item) prago.Must(err) if resource.AfterUpdate != nil { if !resource.AfterUpdate(request, item) { return } } AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_item_edited")) prago.Redirect(request, a.Prefix+"/"+resource.ID) }) }
//InitResource for user func (User) InitResource(a *Admin, resource *Resource) error { a.AdminAccessController.AddBeforeAction(func(request prago.Request) { request.SetData("locale", GetLocale(request)) }) loginForm := func(locale string) *Form { form := NewForm() form.Method = "POST" form.AddEmailInput("email", messages.Messages.Get(locale, "admin_email")).Focused = true form.AddPasswordInput("password", messages.Messages.Get(locale, "admin_password")) form.AddSubmit("send", messages.Messages.Get(locale, "admin_login_action")) return form } renderLogin := func(request prago.Request, form *Form, locale string) { title := fmt.Sprintf("%s - %s", messages.Messages.Get(locale, "admin_login_name"), a.AppName) request.SetData("bottom", fmt.Sprintf("<a href=\"registration\">%s</a><br><a href=\"forgot\">%s</a>", messages.Messages.Get(locale, "admin_register"), messages.Messages.Get(locale, "admin_forgoten"), )) request.SetData("admin_header_prefix", a.Prefix) request.SetData("admin_form", form) request.SetData("title", title) prago.Render(request, 200, "admin_login") } a.AdminAccessController.Get(a.GetURL(resource, "confirm_email"), func(request prago.Request) { email := request.Params().Get("email") token := request.Params().Get("token") var user User err := a.Query().WhereIs("email", email).Get(&user) if err == nil { if !user.emailConfirmed() { if token == user.emailToken(request.App()) { user.EmailConfirmedAt = time.Now() err = a.Save(&user) if err == nil { AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_confirm_email_ok")) prago.Redirect(request, a.Prefix+"/user/login") return } } } } AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_confirm_email_fail")) prago.Redirect(request, a.Prefix+"/user/login") }) forgotForm := func(locale string) *Form { form := NewForm() form.Method = "POST" form.AddEmailInput("email", messages.Messages.Get(locale, "admin_email")).Focused = true form.AddSubmit("send", messages.Messages.Get(locale, "admin_forgotten_submit")) return form } renderForgot := func(request prago.Request, form *Form, locale string) { title := fmt.Sprintf("%s - %s", messages.Messages.Get(locale, "admin_forgotten_name"), a.AppName) request.SetData("bottom", fmt.Sprintf("<a href=\"login\">%s</a>", messages.Messages.Get(locale, "admin_login_action"), )) request.SetData("admin_header_prefix", a.Prefix) request.SetData("admin_form", form) request.SetData("title", title) prago.Render(request, 200, "admin_login") } a.AdminAccessController.Get(a.GetURL(resource, "forgot"), func(request prago.Request) { locale := GetLocale(request) form := forgotForm(locale) renderForgot(request, form, locale) }) a.AdminAccessController.Post(a.GetURL(resource, "forgot"), func(request prago.Request) { email := request.Params().Get("email") email = fixEmail(email) var user User err := a.Query().WhereIs("email", email).Get(&user) if err == nil { if user.emailConfirmed() { if !time.Now().AddDate(0, 0, -1).Before(user.EmailRenewedAt) { user.EmailRenewedAt = time.Now() err = a.Save(&user) if err == nil { err = user.sendRenew(request, a) if err == nil { AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_forgoten_sent", user.Email)) prago.Redirect(request, a.Prefix+"/user/login") return } } } } } AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_forgoten_error", user.Email)) prago.Redirect(request, a.Prefix+"/user/forgot") }) renewPasswordForm := func(locale string) (form *Form) { form = NewForm() form.Method = "POST" passwordInput := form.AddPasswordInput("password", messages.Messages.Get(locale, "admin_password_new"), MinLengthValidator(messages.Messages.Get(locale, "admin_password_length"), 8)) passwordInput.Focused = true form.AddSubmit("send", messages.Messages.Get(locale, "admin_forgoten_set")) return } renderRenew := func(request prago.Request, form *Form, locale string) { email := request.Params().Get("email") email = fixEmail(email) title := fmt.Sprintf("%s - %s", email, messages.Messages.Get(locale, "admin_forgoten_set")) request.SetData("bottom", fmt.Sprintf("<a href=\"login\">%s</a>", messages.Messages.Get(locale, "admin_login_action"), )) request.SetData("admin_header_prefix", a.Prefix) request.SetData("admin_form", form) request.SetData("title", title) prago.Render(request, 200, "admin_login") } a.AdminAccessController.Get(a.GetURL(resource, "renew_password"), func(request prago.Request) { locale := GetLocale(request) form := renewPasswordForm(locale) renderRenew(request, form, locale) }) a.AdminAccessController.Post(a.GetURL(resource, "renew_password"), func(request prago.Request) { locale := GetLocale(request) form := renewPasswordForm(locale) form.BindData(request.Params()) form.Validate() email := request.Params().Get("email") email = fixEmail(email) token := request.Params().Get("token") errStr := messages.Messages.Get(locale, "admin_error") var user User err := a.Query().WhereIs("email", email).Get(&user) if err == nil { if token == user.emailToken(request.App()) { if form.Valid { err = user.newPassword(request.Params().Get("password")) if err == nil { err = a.Save(&user) if err == nil { AddFlashMessage(request, messages.Messages.Get(locale, "admin_password_changed")) prago.Redirect(request, a.Prefix+"/user/login") return } } } } } AddFlashMessage(request, errStr) form.GetItemByName("password").Value = "" renderLogin(request, form, locale) }) a.AdminAccessController.Get(a.GetURL(resource, "login"), func(request prago.Request) { locale := GetLocale(request) form := loginForm(locale) renderLogin(request, form, locale) }) a.AdminAccessController.Post(a.GetURL(resource, "login"), func(request prago.Request) { email := request.Params().Get("email") email = fixEmail(email) password := request.Params().Get("password") session := request.GetData("session").(*sessions.Session) locale := GetLocale(request) form := loginForm(locale) form.Items[0].Value = email form.Errors = []string{messages.Messages.Get(locale, "admin_login_error")} var user User err := a.Query().WhereIs("email", email).Get(&user) if err != nil { if err == ErrItemNotFound { prago.Must(session.Save(request.Request(), request.Response())) renderLogin(request, form, locale) return } panic(err) } if !user.isPassword(password) { renderLogin(request, form, locale) return } user.LoggedInTime = time.Now() user.LoggedInUseragent = request.Request().UserAgent() user.LoggedInIP = request.Request().Header.Get("X-Forwarded-For") prago.Must(a.Save(&user)) session.Values["user_id"] = user.ID session.AddFlash(messages.Messages.Get(locale, "admin_login_ok")) prago.Must(session.Save(request.Request(), request.Response())) prago.Redirect(request, a.Prefix) }) a.AdminController.Get(a.GetURL(resource, "as")+"/:id", func(request prago.Request) { u := GetUser(request) if !u.IsSysadmin { panic("access denied") } id, err := strconv.Atoi(request.Params().Get("id")) if err != nil { panic(err) } var user User prago.Must(a.Query().WhereIs("id", id).Get(&user)) session := request.GetData("session").(*sessions.Session) session.Values["user_id"] = user.ID prago.Must(session.Save(request.Request(), request.Response())) prago.Redirect(request, a.Prefix) }) newUserForm := func(locale string) *Form { form := NewForm() form.Method = "POST" form.AddTextInput("name", messages.Messages.Get(locale, "Name"), NonEmptyValidator(messages.Messages.Get(locale, "admin_user_name_not_empty")), ) form.AddEmailInput("email", messages.Messages.Get(locale, "admin_email"), EmailValidator(messages.Messages.Get(locale, "admin_email_not_valid")), NewValidator(func(field *FormItem) bool { if len(field.Errors) != 0 { return true } var user User a.Query().WhereIs("email", field.Value).Get(&user) if user.Email == field.Value { return false } return true }, messages.Messages.Get(locale, "admin_email_already_registered")), ) form.AddPasswordInput("password", messages.Messages.Get(locale, "admin_register_password"), MinLengthValidator("", 8), ) form.AddSubmit("send", messages.Messages.Get(locale, "admin_register")) return form } renderRegistration := func(request prago.Request, form *Form, locale string) { title := fmt.Sprintf("%s - %s", messages.Messages.Get(locale, "admin_register"), a.AppName) request.SetData("bottom", fmt.Sprintf("<a href=\"login\">%s</a>", messages.Messages.Get(locale, "admin_login_action"), )) request.SetData("admin_header_prefix", a.Prefix) request.SetData("admin_form", form) request.SetData("title", title) prago.Render(request, 200, "admin_login") } a.AdminAccessController.Get(a.GetURL(resource, "registration"), func(request prago.Request) { locale := GetLocale(request) renderRegistration(request, newUserForm(locale), locale) }) a.AdminAccessController.Post(a.GetURL(resource, "registration"), func(request prago.Request) { locale := GetLocale(request) form := newUserForm(locale) form.BindData(request.Params()) form.Validate() if form.Valid { email := request.Params().Get("email") email = fixEmail(email) user := &User{} user.Email = email user.Name = request.Params().Get("name") user.IsActive = true user.Locale = locale prago.Must(user.newPassword(request.Params().Get("password"))) prago.Must(user.sendConfirmEmail(request, a)) err := user.sendAdminEmail(request, a) if err != nil { request.App().Log().Println(err) } prago.Must(a.Create(user)) AddFlashMessage(request, messages.Messages.Get(locale, "admin_confirm_email_send", user.Email)) prago.Redirect(request, a.Prefix+"/user/login") } else { form.GetItemByName("password").Value = "" renderRegistration(request, form, locale) } }) a.AdminController.Get(a.Prefix+"/logout", func(request prago.Request) { ValidateCSRF(request) session := request.GetData("session").(*sessions.Session) delete(session.Values, "user_id") session.AddFlash(messages.Messages.Get(GetLocale(request), "admin_logout_ok")) err := session.Save(request.Request(), request.Response()) if err != nil { panic(err) } prago.Redirect(request, a.GetURL(resource, "login")) }) settingsForm := func(locale string, user *User) *Form { form, err := resource.StructCache.GetForm(user, locale, whiteListFilter("Name", "Email"), whiteListFilter("Name", "Locale")) if err != nil { panic(err) } sel := form.AddSelect("Locale", messages.Messages.Get(locale, "admin_locale"), availableLocales) sel.Value = user.Locale form.AddSubmit("_submit", messages.Messages.Get(locale, "admin_edit")) return form } renderSettings := func(request prago.Request, user *User, form *Form) { request.SetData("admin_item", user) request.SetData("admin_form", form) request.SetData("admin_yield", "admin_settings") prago.Render(request, 200, "admin_layout") } a.AdminController.Get(a.GetURL(resource, "settings"), func(request prago.Request) { user := GetUser(request) form := settingsForm(GetLocale(request), user) AddCSRFToken(form, request) request.SetData("admin_title", messages.Messages.Get(GetLocale(request), "admin_settings")) renderSettings(request, user, form) }) a.AdminController.Post(a.GetURL(resource, "settings"), func(request prago.Request) { ValidateCSRF(request) user := GetUser(request) form := settingsForm(GetLocale(request), user) AddCSRFToken(form, request) form.Validate() if form.Valid { prago.Must(resource.StructCache.BindData(user, request.Params(), request.Request().MultipartForm, form.getFilter())) prago.Must(a.Save(user)) AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_settings_changed")) prago.Redirect(request, a.GetURL(resource, "settings")) return } renderSettings(request, user, form) }) changePasswordForm := func(request prago.Request) *Form { user := GetUser(request) locale := GetLocale(request) oldValidator := NewValidator(func(field *FormItem) bool { if !user.isPassword(field.Value) { return false } return true }, messages.Messages.Get(locale, "admin_password_wrong")) form := NewForm() form.Method = "POST" form.AddPasswordInput("oldpassword", messages.Messages.Get(locale, "admin_password_old"), oldValidator, ) form.AddPasswordInput("newpassword", messages.Messages.Get(locale, "admin_password_new"), MinLengthValidator(messages.Messages.Get(locale, "admin_password_length"), 8), ) form.AddSubmit("_submit", messages.Messages.Get(locale, "admin_save")) return form } renderPasswordForm := func(request prago.Request, form *Form) { request.SetData("admin_title", messages.Messages.Get(GetLocale(request), "admin_password_change")) request.SetData("admin_form", form) request.SetData("admin_yield", "admin_form_view") prago.Render(request, 200, "admin_layout") } a.AdminController.Get(a.GetURL(resource, "password"), func(request prago.Request) { form := changePasswordForm(request) renderPasswordForm(request, form) }) a.AdminController.Post(a.GetURL(resource, "password"), func(request prago.Request) { form := changePasswordForm(request) form.BindData(request.Params()) form.Validate() if form.Valid { password := request.Params().Get("newpassword") user := GetUser(request) prago.Must(user.newPassword(password)) prago.Must(a.Save(user)) AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_password_changed")) prago.Redirect(request, a.GetURL(resource, "settings")) } else { renderPasswordForm(request, form) } }) return nil }
//Init admin middleware func (a *Admin) Init(app *prago.App) error { a.App = app a.db = app.Data()["db"].(*sql.DB) a.AdminAccessController = app.MainController().SubController() a.AdminController = a.AdminAccessController.SubController() googleApiKey := app.Config.GetStringWithFallback("google", "") a.AdminController.AddBeforeAction(func(request prago.Request) { request.SetData("google", googleApiKey) }) bindDBBackupCron(app) bindMarkdownAPI(a) bindListResourceAPI(a) var err error a.sendgridClient = sendgrid.NewSendGridClientWithApiKey(app.Config.GetStringWithFallback("sendgridApi", "")) a.noReplyEmail = app.Config.GetStringWithFallback("noReplyEmail", "") err = a.bindAdminCommand(app) if err != nil { return err } err = a.initTemplates(app) if err != nil { return err } err = app.LoadTemplateFromString(adminTemplates) if err != nil { panic(err) } a.AdminController.AddAroundAction(func(request prago.Request, next func()) { request.SetData("admin_yield", "admin_home") session := request.GetData("session").(*sessions.Session) userID, ok := session.Values["user_id"].(int64) if !ok { prago.Redirect(request, a.Prefix+"/user/login") return } var user User err := a.Query().WhereIs("id", userID).Get(&user) if err != nil { prago.Redirect(request, a.Prefix+"/user/login") return } randomness := app.Config.GetString("random") request.SetData("_csrfToken", user.CSRFToken(randomness)) request.SetData("currentuser", &user) request.SetData("locale", GetLocale(request)) request.SetData("appName", a.AppName) request.SetData("appCode", request.App().Data()["appName"].(string)) request.SetData("appVersion", request.App().Data()["version"].(string)) request.SetData("admin_header", a.adminHeaderData(request)) next() }) a.AdminController.Get(a.Prefix, func(request prago.Request) { prago.Render(request, 200, "admin_layout") }) a.AdminController.Get(a.Prefix+"/_stats", stats) a.AdminController.Get(a.Prefix+"/_static/admin.js", func(request prago.Request) { request.Response().Header().Set("Content-type", "text/javascript") request.Response().WriteHeader(200) request.Response().Write([]byte(adminJS)) request.SetProcessed() }) a.App.MainController().Get(a.Prefix+"/_static/admin.css", func(request prago.Request) { request.Response().Header().Set("Content-type", "text/css; charset=utf-8") request.Response().WriteHeader(200) request.Response().Write([]byte(adminCSS)) request.SetProcessed() }) for i := range a.Resources { resource := a.Resources[i] err = a.initResource(resource) if err != nil { return err } } a.AdminController.Get(a.Prefix+"/*", func(request prago.Request) { render404(request) }) return nil }
//InitResource of file func (File) InitResource(a *Admin, resource *Resource) error { resource.Pagination = 100 fileUploadPath = a.App.Config.GetString("fileUploadPath") fileDownloadPath = a.App.Config.GetString("fileDownloadPath") if !strings.HasSuffix(fileUploadPath, "/") { fileUploadPath += "/" } if !strings.HasSuffix(fileDownloadPath, "/") { fileDownloadPath += "/" } bindImageAPI(a, fileDownloadPath) resource.Actions["create"] = func(a *Admin, resource *Resource) { resource.ResourceController.Post(a.GetURL(resource, ""), func(request prago.Request) { ValidateCSRF(request) multipartFiles := request.Request().MultipartForm.File["file"] if len(multipartFiles) != 1 { panic("must have 1 file selected") } file, err := uploadFile(multipartFiles[0], fileUploadPath) if err != nil { panic(err) } file.User = GetUser(request).ID file.Description = request.Params().Get("Description") prago.Must(a.Create(file)) AddFlashMessage(request, messages.Messages.Get(GetLocale(request), "admin_item_created")) prago.Redirect(request, a.Prefix+"/"+resource.ID) }) } resource.Actions["detail"] = func(a *Admin, resource *Resource) { resource.ResourceController.Get(a.GetURL(resource, ":id"), func(request prago.Request) { id, err := strconv.Atoi(request.Params().Get("id")) prago.Must(err) var file File prago.Must(a.Query().WhereIs("id", int64(id)).Get(&file)) form := NewForm() form.Method = "POST" fi := form.AddTextInput("Name", messages.Messages.Get(GetLocale(request), "Name")) fi.Readonly = true fi.Value = file.Name _, fileURL := file.getPath(fileDownloadPath + "original") fi = form.AddTextInput("url", messages.Messages.Get(GetLocale(request), "Url")) fi.Readonly = true fi.Value = fileURL fi.SubTemplate = "admin_item_link" fi = form.AddTextInput("size", messages.Messages.Get(GetLocale(request), "Size")) fi.Readonly = true fi.Value = fmt.Sprintf("%d", file.Size) fi = form.AddTextInput("uploadedBy", messages.Messages.Get(GetLocale(request), "Uploaded By")) fi.Readonly = true fi.Value = fmt.Sprintf("%d", file.User) fi = form.AddTextInput("fileType", messages.Messages.Get(GetLocale(request), "Type")) fi.Readonly = true fi.Value = file.FileType if file.isImage() { fi = form.AddTextInput("width", messages.Messages.Get(GetLocale(request), "Width")) fi.Readonly = true fi.Value = fmt.Sprintf("%d", file.Width) fi = form.AddTextInput("height", messages.Messages.Get(GetLocale(request), "Height")) fi.Readonly = true fi.Value = fmt.Sprintf("%d", file.Height) for _, v := range []string{"large", "medium", "small"} { fi = form.AddTextInput("thumb"+v, messages.Messages.Get(GetLocale(request), v)) fi.Readonly = true _, path := file.getPath(fileDownloadPath + "thumb/" + v) fi.Value = path fi.SubTemplate = "admin_item_link" } } fi = form.AddTextareaInput("Description", messages.Messages.Get(GetLocale(request), "Description")) fi.Value = file.Description fi.Focused = true form.AddSubmit("_submit", messages.Messages.Get(GetLocale(request), "admin_edit")) AddCSRFToken(form, request) request.SetData("admin_item", file) request.SetData("admin_form", form) request.SetData("admin_yield", "admin_edit") prago.Render(request, 200, "admin_layout") }) } return nil }
func Newsletter(request prago.Request) { email := request.Params().Get("email") println(email) prago.Redirect(request, "/index.html?submitted") }
func HomeRedirect(request prago.Request) { prago.Redirect(request, "/index.html") }