Added delete account and edit profile
Cette révision appartient à :
Parent
6a49afab5f
révision
8aa8a0593c
14 fichiers modifiés avec 420 ajouts et 61 suppressions
|
@ -35,6 +35,7 @@ func init() {
|
|||
gzipUserLoginPostHandler := handlers.CompressHandler(http.HandlerFunc(UserLoginPostHandler))
|
||||
gzipUserLogoutHandler := handlers.CompressHandler(http.HandlerFunc(UserLogoutHandler))
|
||||
gzipUserProfileHandler := handlers.CompressHandler(http.HandlerFunc(UserProfileHandler))
|
||||
gzipUserProfileFormHandler := handlers.CompressHandler(http.HandlerFunc(UserProfileFormHandler))
|
||||
|
||||
Router = mux.NewRouter()
|
||||
|
||||
|
@ -61,6 +62,7 @@ func init() {
|
|||
Router.Handle("/user/login", gzipUserLoginPostHandler).Name("user_login").Methods("POST")
|
||||
Router.Handle("/user/logout", gzipUserLogoutHandler).Name("user_logout")
|
||||
Router.Handle("/user/{id}/{username}", gzipUserProfileHandler).Name("user_profile").Methods("GET")
|
||||
Router.Handle("/user/{id}/{username}", gzipUserProfileFormHandler).Name("user_profile").Methods("POST")
|
||||
Router.PathPrefix("/captcha").Methods("GET").HandlerFunc(captcha.ServeFiles)
|
||||
|
||||
Router.NotFoundHandler = http.HandlerFunc(NotFoundHandler)
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
var TemplateDir = "templates"
|
||||
|
||||
var homeTemplate, searchTemplate, faqTemplate, uploadTemplate, viewTemplate, viewRegisterTemplate, viewLoginTemplate, viewRegisterSuccessTemplate, viewVerifySuccessTemplate, viewProfileTemplate, notFoundTemplate *template.Template
|
||||
var homeTemplate, searchTemplate, faqTemplate, uploadTemplate, viewTemplate, viewRegisterTemplate, viewLoginTemplate, viewRegisterSuccessTemplate, viewVerifySuccessTemplate, viewProfileTemplate, viewProfileEditTemplate, viewUserDeleteTemplate, notFoundTemplate *template.Template
|
||||
|
||||
type templateLoader struct {
|
||||
templ **template.Template
|
||||
|
@ -68,6 +68,16 @@ func ReloadTemplates() {
|
|||
name: "user_profile",
|
||||
file: "user/profile.html",
|
||||
},
|
||||
templateLoader{
|
||||
templ: &viewProfileEditTemplate,
|
||||
name: "user_profile",
|
||||
file: "user/profile_edit.html",
|
||||
},
|
||||
templateLoader{
|
||||
templ: &viewUserDeleteTemplate,
|
||||
name: "user_delete",
|
||||
file: "user/delete_success.html",
|
||||
},
|
||||
templateLoader{
|
||||
templ: ¬FoundTemplate,
|
||||
name: "404",
|
||||
|
|
|
@ -65,5 +65,6 @@ var FuncMap = template.FuncMap{
|
|||
},
|
||||
"CurrentOrAdmin": userPermission.CurrentOrAdmin,
|
||||
"CurrentUserIdentical": userPermission.CurrentUserIdentical,
|
||||
"HasAdmin": userPermission.HasAdmin,
|
||||
"GetRole": userPermission.GetRole,
|
||||
}
|
||||
|
|
|
@ -54,6 +54,18 @@ type UserRegisterTemplateVariables struct {
|
|||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
||||
type UserProfileEditVariables struct {
|
||||
UserProfile *model.User
|
||||
UserForm userForms.UserForm
|
||||
FormErrors map[string][]string
|
||||
FormInfos map[string][]string
|
||||
Search SearchForm
|
||||
Navigation Navigation
|
||||
User *model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
||||
type UserVerifyTemplateVariables struct {
|
||||
FormErrors map[string][]string
|
||||
Search SearchForm
|
||||
|
@ -75,7 +87,6 @@ type UserLoginFormVariables struct {
|
|||
|
||||
type UserProfileVariables struct {
|
||||
UserProfile *model.User
|
||||
FormErrors map[string][]string
|
||||
Search SearchForm
|
||||
Navigation Navigation
|
||||
User *model.User
|
||||
|
|
|
@ -54,11 +54,33 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
|
||||
if (errorUser == nil) {
|
||||
currentUser := GetUser(r)
|
||||
view := r.URL.Query().Get("view")
|
||||
if ((view == "edit")&&(userPermission.CurrentOrAdmin(currentUser, userProfile.Id))) {
|
||||
} else {
|
||||
view := r.URL.Query()["edit"]
|
||||
deleteVar := r.URL.Query()["delete"]
|
||||
if ((view != nil)&&(userPermission.CurrentOrAdmin(currentUser, userProfile.Id))) {
|
||||
b := form.UserForm{}
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
languages.SetTranslationFromRequest(viewProfileEditTemplate, r, "en-us")
|
||||
htv := UserProfileEditVariables{&userProfile, b, form.NewErrors(), form.NewInfos(), NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
|
||||
err := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
} else if ((deleteVar != nil)&&(userPermission.CurrentOrAdmin(currentUser, userProfile.Id))) {
|
||||
err := form.NewErrors()
|
||||
_, errUser := userService.DeleteUser(w, currentUser, id)
|
||||
if (errUser != nil) {
|
||||
err["errors"] = append(err["errors"], errUser.Error())
|
||||
}
|
||||
languages.SetTranslationFromRequest(viewUserDeleteTemplate, r, "en-us")
|
||||
htv := UserVerifyTemplateVariables{err, NewSearchForm(), Navigation{}, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
errorTmpl := viewUserDeleteTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
} else {
|
||||
languages.SetTranslationFromRequest(viewProfileTemplate, r, "en-us")
|
||||
htv := UserProfileVariables{&userProfile, form.NewErrors(), NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
htv := UserProfileVariables{&userProfile, NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
|
||||
err := viewProfileTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
|
@ -79,7 +101,60 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Getting View User Profile Update
|
||||
func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
currentUser := GetUser(r)
|
||||
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
|
||||
if (errorUser == nil) {
|
||||
if (userPermission.CurrentOrAdmin(currentUser, userProfile.Id)) {
|
||||
b := form.UserForm{}
|
||||
err := form.NewErrors()
|
||||
infos := form.NewInfos()
|
||||
T := languages.SetTranslationFromRequest(viewProfileEditTemplate, r, "en-us")
|
||||
if len(r.PostFormValue("email")) > 0 {
|
||||
_, err = form.EmailValidation(r.PostFormValue("email"), err)
|
||||
}
|
||||
if len(r.PostFormValue("username")) > 0 {
|
||||
_, err = form.ValidateUsername(r.PostFormValue("username"), err)
|
||||
}
|
||||
if (len(err) == 0) {
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
err = modelHelper.ValidateForm(&b, err)
|
||||
if (len(err) == 0) {
|
||||
userProfile, _, errorUser = userService.UpdateUser(w, &b, currentUser, id)
|
||||
if (errorUser != nil) {
|
||||
err["errors"] = append(err["errors"], errorUser.Error())
|
||||
}
|
||||
if (len(err) == 0) {
|
||||
infos["infos"] = append(infos["infos"], T("profile_updated"))
|
||||
}
|
||||
}
|
||||
}
|
||||
htv := UserProfileEditVariables{&userProfile, b, err, infos, NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
errorTmpl := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if errorTmpl != nil {
|
||||
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
} else {
|
||||
searchForm := NewSearchForm()
|
||||
searchForm.HideAdvancedSearch = true
|
||||
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r, "en-us")
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{Navigation{}, searchForm, GetUser(r), r.URL, mux.CurrentRoute(r)})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
searchForm := NewSearchForm()
|
||||
searchForm.HideAdvancedSearch = true
|
||||
|
||||
languages.SetTranslationFromRequest(notFoundTemplate, r, "en-us")
|
||||
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{Navigation{}, searchForm, GetUser(r), r.URL, mux.CurrentRoute(r)})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Post Registration controller, we do some check on the form here, the rest on user service
|
||||
|
@ -104,7 +179,6 @@ func UserRegisterPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
err["errors"] = append(err["errors"], errorUser.Error())
|
||||
}
|
||||
if (len(err) == 0) {
|
||||
b := form.RegistrationForm{}
|
||||
languages.SetTranslationFromRequest(viewRegisterSuccessTemplate, r, "en-us")
|
||||
htv := UserRegisterTemplateVariables{b, err, NewSearchForm(), Navigation{}, GetUser(r), r.URL, mux.CurrentRoute(r)}
|
||||
errorTmpl := viewRegisterSuccessTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
|
@ -173,8 +247,3 @@ func UserLogoutHandler(w http.ResponseWriter, r *http.Request) {
|
|||
url, _ := Router.Get("home").URL()
|
||||
http.Redirect(w, r, url.String(), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// Post Profule Update controller
|
||||
func UserProfilePostHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,10 @@ func NewErrors() map[string][]string {
|
|||
err := make(map[string][]string)
|
||||
return err
|
||||
}
|
||||
func NewInfos() map[string][]string {
|
||||
infos := make(map[string][]string)
|
||||
return infos
|
||||
}
|
||||
func IsAgreed(t_and_c string) bool {
|
||||
if t_and_c == "1" {
|
||||
return true
|
||||
|
@ -46,7 +50,7 @@ func IsAgreed(t_and_c string) bool {
|
|||
// RegistrationForm is used when creating a user.
|
||||
type RegistrationForm struct {
|
||||
Username string `form:"username" needed:"true" len_min:"3" len_max:"20"`
|
||||
Email string `form:"email"`
|
||||
Email string `form:"email" needed:"true"`
|
||||
Password string `form:"password" needed:"true" len_min:"6" len_max:"25" equalInput:"Confirm_Password"`
|
||||
Confirm_Password string `form:"password_confirmation" omit:"true" needed:"true"`
|
||||
CaptchaID string `form:"captchaID" omit:"true" needed:"true"`
|
||||
|
@ -61,7 +65,13 @@ type LoginForm struct {
|
|||
|
||||
// UserForm is used when updating a user.
|
||||
type UserForm struct {
|
||||
Email string `form:"email"`
|
||||
Username string `form:"username" needed:"true" len_min:"3" len_max:"20"`
|
||||
Email string `form:"email" needed:"true"`
|
||||
Language string `form:"language" default:"en-us"`
|
||||
CurrentPassword string `form:"password" len_min:"6" len_max:"25" omit:"true"`
|
||||
Password string `form:"password" len_min:"6" len_max:"25" equalInput:"Confirm_Password"`
|
||||
Confirm_Password string `form:"password_confirmation" omit:"true"`
|
||||
Status int `form:"language" default:"0"`
|
||||
}
|
||||
|
||||
// PasswordForm is used when updating a user password.
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/ewhal/nyaa/db"
|
||||
"github.com/ewhal/nyaa/model"
|
||||
formStruct "github.com/ewhal/nyaa/service/user/form"
|
||||
"github.com/ewhal/nyaa/service/user/permission"
|
||||
"github.com/ewhal/nyaa/util/crypto"
|
||||
"github.com/ewhal/nyaa/util/log"
|
||||
"github.com/ewhal/nyaa/util/modelHelper"
|
||||
|
@ -151,46 +152,47 @@ func UpdateUserCore(user *model.User) (int, error) {
|
|||
}
|
||||
|
||||
// UpdateUser updates a user.
|
||||
func UpdateUser(w http.ResponseWriter, r *http.Request, id string) (*model.User, int, error) {
|
||||
func UpdateUser(w http.ResponseWriter, form *formStruct.UserForm, currentUser *model.User, id string) (model.User, int, error) {
|
||||
var user model.User
|
||||
if db.ORM.First(&user, id).RecordNotFound() {
|
||||
return &user, http.StatusNotFound, errors.New("User is not found.")
|
||||
}
|
||||
switch r.FormValue("type") {
|
||||
case "password":
|
||||
var passwordForm formStruct.PasswordForm
|
||||
modelHelper.BindValueForm(&passwordForm, r)
|
||||
log.Debugf("form %+v\n", passwordForm)
|
||||
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(passwordForm.CurrentPassword))
|
||||
if err != nil {
|
||||
log.Error("Password Incorrect.")
|
||||
return &user, http.StatusInternalServerError, errors.New("User is not updated. Password Incorrect.")
|
||||
} else {
|
||||
newPassword, err := bcrypt.GenerateFromPassword([]byte(passwordForm.Password), 10)
|
||||
if err != nil {
|
||||
return &user, http.StatusInternalServerError, errors.New("User is not updated. Password not Generated.")
|
||||
} else {
|
||||
passwordForm.Password = string(newPassword)
|
||||
modelHelper.AssignValue(&user, &passwordForm)
|
||||
}
|
||||
}
|
||||
default:
|
||||
var form formStruct.UserForm
|
||||
modelHelper.BindValueForm(&form, r)
|
||||
log.Debugf("form %+v\n", form)
|
||||
modelHelper.AssignValue(&user, &form)
|
||||
return user, http.StatusNotFound, errors.New("User is not found.")
|
||||
}
|
||||
|
||||
if (form.Password != "") {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(form.CurrentPassword))
|
||||
if err != nil && !userPermission.HasAdmin(currentUser) {
|
||||
log.Error("Password Incorrect.")
|
||||
return user, http.StatusInternalServerError, errors.New("User is not updated. Password Incorrect.")
|
||||
} else {
|
||||
newPassword, err := bcrypt.GenerateFromPassword([]byte(form.Password), 10)
|
||||
if err != nil {
|
||||
return user, http.StatusInternalServerError, errors.New("User is not updated. Password not Generated.")
|
||||
} else {
|
||||
form.Password = string(newPassword)
|
||||
}
|
||||
}
|
||||
} else { // Then no change of password
|
||||
form.Password = user.Password
|
||||
}
|
||||
if !userPermission.HasAdmin(currentUser) { // We don't want users to be able to modify some fields
|
||||
form.Status = user.Status
|
||||
form.Username = user.Username
|
||||
}
|
||||
log.Debugf("form %+v\n", form)
|
||||
modelHelper.AssignValue(&user, form)
|
||||
|
||||
status, err := UpdateUserCore(&user)
|
||||
if err != nil {
|
||||
return &user, status, err
|
||||
return user, status, err
|
||||
}
|
||||
status, err = SetCookie(w, user.Token)
|
||||
return &user, status, err
|
||||
if (userPermission.CurrentUserIdentical(currentUser, user.Id)) {
|
||||
status, err = SetCookie(w, user.Token)
|
||||
}
|
||||
return user, status, err
|
||||
}
|
||||
|
||||
// DeleteUser deletes a user.
|
||||
func DeleteUser(w http.ResponseWriter, id string) (int, error) {
|
||||
func DeleteUser(w http.ResponseWriter, currentUser *model.User, id string) (int, error) {
|
||||
var user model.User
|
||||
if db.ORM.First(&user, id).RecordNotFound() {
|
||||
return http.StatusNotFound, errors.New("User is not found.")
|
||||
|
@ -198,8 +200,10 @@ func DeleteUser(w http.ResponseWriter, id string) (int, error) {
|
|||
if db.ORM.Delete(&user).Error != nil {
|
||||
return http.StatusInternalServerError, errors.New("User is not deleted.")
|
||||
}
|
||||
status, err := ClearCookie(w)
|
||||
return status, err
|
||||
if (userPermission.CurrentUserIdentical(currentUser, user.Id)) {
|
||||
return ClearCookie(w)
|
||||
}
|
||||
return http.StatusOK, nil
|
||||
}
|
||||
|
||||
// RetrieveCurrentUser retrieves a current user.
|
||||
|
|
105
templates/_profile_edit.html
Fichier normal
105
templates/_profile_edit.html
Fichier normal
|
@ -0,0 +1,105 @@
|
|||
{{define "profile_edit_content"}}
|
||||
{{with .UserProfile}}
|
||||
{{ range (index $.FormInfos "infos")}}
|
||||
<div class="alert alert-info"><a class="panel-close close" data-dismiss="alert">×</a><i class="glyphicon glyphicon-info-sign"></i> {{ . }}</div>
|
||||
{{end}}
|
||||
{{ range (index $.FormErrors "errors")}}
|
||||
<div class="alert alert-danger"><a class="panel-close close" data-dismiss="alert">×</a><i class="glyphicon glyphicon-exclamation-sign"></i> {{ . }}</div>
|
||||
{{end}}
|
||||
<h3>{{ T "personal_info"}}</h3>
|
||||
|
||||
<form class="form-horizontal" role="form" method="POST">
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ T "email" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<input class="form-control" type="text" name="email" id="email" value="{{.Email}}">
|
||||
{{ range (index $.FormErrors "email")}}
|
||||
<p class="bg-danger">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ T "language"}}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="language" name="language" class="form-control">
|
||||
<option value="en-us" {{ if eq .Language "en-us" }}selected{{end}}>{{T "english"}} ({{ T "default" }})</option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "language")}}
|
||||
<p class="bg-danger">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{ if not (HasAdmin .)}}
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">{{ T "current_password"}}:</label>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" name="current_password" id="current_password" type="password">
|
||||
{{ range (index $.FormErrors "current_password")}}
|
||||
<p class="bg-danger">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">{{ T "password"}}:</label>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" name="password" id="password" type="password">
|
||||
{{ range (index $.FormErrors "password")}}
|
||||
<p class="bg-danger">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">{{ T "confirm_password"}}:</label>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" name="password_confirmation" id="password_confirmation" type="password">
|
||||
{{ range (index $.FormErrors "password_confirmation")}}
|
||||
<p class="bg-danger">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{ if HasAdmin .}}
|
||||
<h3>{{ T "moderation"}}</h3>
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">{{ T "username"}}:</label>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" name="username" id="username" type="text" value="{{.Username}}">
|
||||
{{ range (index $.FormErrors "username")}}
|
||||
<p class="bg-danger">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">{{ T "role" }}:</label>
|
||||
<div class="col-lg-8">
|
||||
<div class="ui-select">
|
||||
<select id="status" name="status" class="form-control">
|
||||
<option value="-1" {{ if eq .Status -1 }}selected{{end}}>{{ T "banned"}}</option>
|
||||
<option value="0" {{ if eq .Status 0 }}selected{{end}}>{{ T "member"}} ({{ T "default" }})</option>
|
||||
<option value="1" {{ if eq .Status 1 }}selected{{end}}>{{ T "trusted_member"}} </option>
|
||||
<option value="2" {{ if eq .Status 2 }}selected{{end}}>{{ T "moderator"}} </option>
|
||||
</select>
|
||||
</div>
|
||||
{{ range (index $.FormErrors "status")}}
|
||||
<p class="bg-danger">{{ . }}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label"></label>
|
||||
<div class="col-md-8">
|
||||
<input type="submit" class="btn btn-primary" name="save" value="{{ T "save_changes"}}">
|
||||
<span></span>
|
||||
<input type="reset" class="btn btn-default" value="Cancel">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{ if CurrentOrAdmin $.User .Id }}
|
||||
<hr>
|
||||
<a href="?delete" onclick="if (!confirm('{{ T "delete_account_confirm" }}')) return false;" class="btn btn-danger btn-lg"><i class="glyphicon glyphicon-trash"></i> {{ T "delete_account"}}</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
17
templates/user/delete_success.html
Fichier normal
17
templates/user/delete_success.html
Fichier normal
|
@ -0,0 +1,17 @@
|
|||
{{define "title"}}{{ T "delete_account" }}{{end}}
|
||||
{{define "contclass"}}cont-view{{end}}
|
||||
{{define "content"}}
|
||||
<div class="blockBody">
|
||||
<div class="row" style="margin-top:20px">
|
||||
<div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
|
||||
|
||||
<h2>{{T "delete_success"}}</h2>
|
||||
<hr class="colorgraph">
|
||||
{{ range (index $.FormErrors "errors")}}
|
||||
<div class="alert alert-danger">{{ . }}</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{define "js_footer"}}<script type="text/javascript" charset="utf-8" src="{{.URL.Parse "/js/registerPage.js"}}"></script>{{end}}
|
|
@ -41,7 +41,7 @@
|
|||
{{if gt $.User.Id 0 }}
|
||||
{{if CurrentOrAdmin $.User .Id }}
|
||||
<li>
|
||||
<a href="#">
|
||||
<a href="?edit">
|
||||
<i class="glyphicon glyphicon-user"></i>
|
||||
{{T "settings"}} </a>
|
||||
</li>
|
||||
|
|
62
templates/user/profile_edit.html
Fichier normal
62
templates/user/profile_edit.html
Fichier normal
|
@ -0,0 +1,62 @@
|
|||
{{define "title"}}{{ T "profile_edit_page" .UserProfile.Username }}{{end}}
|
||||
{{define "contclass"}}cont-view{{end}}
|
||||
{{define "content"}}
|
||||
<div class="row profile">
|
||||
{{with .UserProfile}}
|
||||
<div class="col-md-3">
|
||||
<div class="profile-sidebar">
|
||||
<!-- SIDEBAR USERPIC -->
|
||||
<div class="profile-userpic">
|
||||
<img src="{{ getAvatar .Md5 130 }}" class="img-responsive" alt="{{.Username}}">
|
||||
</div>
|
||||
<!-- END SIDEBAR USERPIC -->
|
||||
<!-- SIDEBAR USER TITLE -->
|
||||
<div class="profile-usertitle">
|
||||
<div class="profile-usertitle-name">
|
||||
{{.Username}}
|
||||
</div>
|
||||
<div class="profile-usertitle-job">
|
||||
{{GetRole . }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- END SIDEBAR USER TITLE -->
|
||||
<!-- SIDEBAR BUTTONS -->
|
||||
<div class="profile-userbuttons">
|
||||
{{if gt $.User.Id 0 }}
|
||||
{{if not (CurrentUserIdentical $.User .Id) }}
|
||||
<button type="button" class="btn btn-success btn-sm">{{ T "follow"}}</button>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<!-- <button type="button" class="btn btn-danger btn-sm">Message</button> -->
|
||||
</div>
|
||||
<!-- END SIDEBAR BUTTONS -->
|
||||
<!-- SIDEBAR MENU -->
|
||||
<div class="profile-usermenu">
|
||||
<ul class="nav">
|
||||
<li>
|
||||
<a href="#">
|
||||
<i class="glyphicon glyphicon-home"></i>
|
||||
{{T "torrents"}} </a>
|
||||
</li>
|
||||
{{if gt $.User.Id 0 }}
|
||||
{{if CurrentOrAdmin $.User .Id }}
|
||||
<li class="active">
|
||||
<a href="?edit">
|
||||
<i class="glyphicon glyphicon-user"></i>
|
||||
{{T "settings"}} </a>
|
||||
</li>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
<!-- END MENU -->
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="col-md-9">
|
||||
<div class="profile-content">
|
||||
{{ block "profile_edit_content" . }}{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -494,5 +494,57 @@
|
|||
{
|
||||
"id": "submit",
|
||||
"translation": "Submit"
|
||||
},
|
||||
{
|
||||
"id": "personal_info",
|
||||
"translation": "Personal Info"
|
||||
},
|
||||
{
|
||||
"id": "language",
|
||||
"translation": "Language"
|
||||
},
|
||||
{
|
||||
"id": "current_password",
|
||||
"translation": "Current password"
|
||||
},
|
||||
{
|
||||
"id": "role",
|
||||
"translation": "Role"
|
||||
},
|
||||
{
|
||||
"id": "banned",
|
||||
"translation": "Banned"
|
||||
},
|
||||
{
|
||||
"id": "default",
|
||||
"translation": "Default"
|
||||
},
|
||||
{
|
||||
"id": "trusted_member",
|
||||
"translation": "Trusted member"
|
||||
},
|
||||
{
|
||||
"id": "moderator",
|
||||
"translation": "Moderator"
|
||||
},
|
||||
{
|
||||
"id": "save_changes",
|
||||
"translation": "Save Changes"
|
||||
},
|
||||
{
|
||||
"id": "profile_updated",
|
||||
"translation": "Your profile has been correctly updated!"
|
||||
},
|
||||
{
|
||||
"id": "delete_account",
|
||||
"translation": "Delete Account"
|
||||
},
|
||||
{
|
||||
"id": "delete_account_confirm",
|
||||
"translation": "Are you sure you want to delete this account?"
|
||||
},
|
||||
{
|
||||
"id": "delete_success",
|
||||
"translation": "The account has been successfully deleted!"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -7,16 +7,17 @@ import (
|
|||
"net/http"
|
||||
)
|
||||
|
||||
func SetTranslation(tmpl *template.Template, language string, languages ...string) {
|
||||
func SetTranslation(tmpl *template.Template, language string, languages ...string) i18n.TranslateFunc {
|
||||
T, _ := i18n.Tfunc(language, languages...)
|
||||
tmpl.Funcs(map[string]interface{}{
|
||||
"T": func(str string, args ...interface{}) template.HTML {
|
||||
return template.HTML(fmt.Sprintf(T(str), args...))
|
||||
},
|
||||
})
|
||||
return T
|
||||
}
|
||||
|
||||
func SetTranslationFromRequest(tmpl *template.Template, r *http.Request, defaultLanguage string) {
|
||||
func SetTranslationFromRequest(tmpl *template.Template, r *http.Request, defaultLanguage string) i18n.TranslateFunc {
|
||||
cookie, err := r.Cookie("lang")
|
||||
cookieLanguage := ""
|
||||
if err == nil {
|
||||
|
@ -24,5 +25,5 @@ func SetTranslationFromRequest(tmpl *template.Template, r *http.Request, default
|
|||
}
|
||||
// go-i18n supports the format of the Accept-Language header, thankfully.
|
||||
headerLanguage := r.Header.Get("Accept-Language")
|
||||
SetTranslation(tmpl, cookieLanguage, headerLanguage, defaultLanguage)
|
||||
return SetTranslation(tmpl, cookieLanguage, headerLanguage, defaultLanguage)
|
||||
}
|
||||
|
|
|
@ -65,19 +65,19 @@ func ValidateForm(form interface{}, errorForm map[string][]string) (map[string][
|
|||
if (tag.Get("hum_name") != "") { // For more human input name than gibberish
|
||||
inputName = tag.Get("hum_name")
|
||||
}
|
||||
if tag.Get("len_min") != "" { // Check minimum length
|
||||
if tag.Get("len_min") != "" && (tag.Get("needed") != ""||formElem.Field(i).Len()>0) { // Check minimum length
|
||||
lenMin, _ := strconv.Atoi(tag.Get("len_min"))
|
||||
if formElem.Field(i).Len() < lenMin {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Minimal length of %s required for the input: %s", strconv.Itoa(lenMin), inputName))
|
||||
}
|
||||
}
|
||||
if tag.Get("len_max") != "" { // Check minimum length
|
||||
if tag.Get("len_max") != "" && (tag.Get("needed") != ""||formElem.Field(i).Len()>0) { // Check maximum length
|
||||
lenMax, _ := strconv.Atoi(tag.Get("len_max"))
|
||||
if formElem.Field(i).Len() > lenMax {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Maximal length of %s required for the input: %s", strconv.Itoa(lenMax), inputName))
|
||||
}
|
||||
}
|
||||
if tag.Get("equalInput") != "" {
|
||||
if tag.Get("equalInput") != "" && (tag.Get("needed") != ""||formElem.Field(i).Len()>0) {
|
||||
otherInput := formElem.FieldByName(tag.Get("equalInput"))
|
||||
if formElem.Field(i).Interface() != otherInput.Interface() {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Must be same %s", inputName))
|
||||
|
@ -91,26 +91,37 @@ func ValidateForm(form interface{}, errorForm map[string][]string) (map[string][
|
|||
if tag.Get("needed") != "" && formElem.Field(i).String() == "" {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
|
||||
}
|
||||
if tag.Get("default") != "" {
|
||||
formElem.Field(i).SetString(tag.Get("default"))
|
||||
}
|
||||
case "int" :
|
||||
if tag.Get("equal") != "" { // Check minimum length
|
||||
equal, _ := strconv.Atoi(tag.Get("equal"))
|
||||
if formElem.Field(i).Int() > int64(equal) {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
|
||||
}
|
||||
if tag.Get("needed") != "" && formElem.Field(i).Int() == 0 {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
|
||||
}
|
||||
}
|
||||
if tag.Get("needed") != "" && formElem.Field(i).Int() == 0 {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
|
||||
}
|
||||
if tag.Get("default") != "" {
|
||||
defaultValue, _ := strconv.Atoi(tag.Get("default"))
|
||||
formElem.Field(i).SetInt(int64(defaultValue))
|
||||
}
|
||||
case "float" :
|
||||
if tag.Get("equal") != "" { // Check minimum length
|
||||
equal, _ := strconv.Atoi(tag.Get("equal"))
|
||||
if formElem.Field(i).Float() != float64(equal) {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
|
||||
if tag.Get("equal") != "" { // Check minimum length
|
||||
equal, _ := strconv.Atoi(tag.Get("equal"))
|
||||
if formElem.Field(i).Float() != float64(equal) {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
|
||||
}
|
||||
}
|
||||
if tag.Get("needed") != "" && formElem.Field(i).Float() == 0 {
|
||||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Field needed: %s", inputName))
|
||||
}
|
||||
}
|
||||
if tag.Get("default") != "" {
|
||||
defaultValue, _ := strconv.Atoi(tag.Get("default"))
|
||||
formElem.Field(i).SetFloat(float64(defaultValue))
|
||||
}
|
||||
case "bool" :
|
||||
if tag.Get("equal") != "" { // Check minimum length
|
||||
equal, _ := strconv.ParseBool(tag.Get("equal"))
|
||||
|
@ -118,6 +129,10 @@ func ValidateForm(form interface{}, errorForm map[string][]string) (map[string][
|
|||
errorForm[tag.Get("form")] = append(errorForm[tag.Get("form")], fmt.Sprintf("Wrong value for the input: %s", inputName))
|
||||
}
|
||||
}
|
||||
if tag.Get("default") != "" {
|
||||
defaultValue, _ := strconv.ParseBool(tag.Get("default"))
|
||||
formElem.Field(i).SetBool(defaultValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
return errorForm
|
||||
|
|
Référencer dans un nouveau ticket