forked from jason/cpolis
Let admins edit other user's profiles
This commit is contained in:
@ -51,9 +51,11 @@ func main() {
|
||||
|
||||
mux.HandleFunc("GET /create-tag", view.CreateTag(args))
|
||||
mux.HandleFunc("GET /create-user", view.CreateUser(args))
|
||||
mux.HandleFunc("GET /edit-user", view.EditUser(args, db, store))
|
||||
mux.HandleFunc("GET /edit-self", view.EditSelf(args, db, store))
|
||||
mux.HandleFunc("GET /edit-user/{id}", view.EditUser(args, db))
|
||||
mux.HandleFunc("GET /hub", view.ShowHub(args, db, store))
|
||||
mux.HandleFunc("GET /logout", view.Logout(args, store))
|
||||
mux.HandleFunc("GET /pics/{pic}", view.ServeImage(args, store))
|
||||
mux.HandleFunc("GET /publish-article/{id}", view.PublishArticle(args, db, store))
|
||||
mux.HandleFunc("GET /publish-issue", view.PublishLatestIssue(args, db, store))
|
||||
mux.HandleFunc("GET /reject-article/{id}", view.RejectArticle(args, db, store))
|
||||
@ -63,7 +65,7 @@ func main() {
|
||||
mux.HandleFunc("GET /rss", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, args.RSSFile)
|
||||
})
|
||||
mux.HandleFunc("GET /pics/{pic}", view.ServeImage(args, store))
|
||||
mux.HandleFunc("GET /show-all-users", view.ShowAllUsers(args, db))
|
||||
mux.HandleFunc("GET /this-issue", view.ShowCurrentArticles(args, db))
|
||||
mux.HandleFunc("GET /unpublished-articles", view.ShowUnpublishedArticles(args, db))
|
||||
mux.HandleFunc("GET /write-article", view.WriteArticle(args, db))
|
||||
@ -74,7 +76,8 @@ func main() {
|
||||
mux.HandleFunc("POST /login", view.Login(args, db, store))
|
||||
mux.HandleFunc("POST /resubmit-article/{id}", view.ResubmitArticle(args, db, store))
|
||||
mux.HandleFunc("POST /submit-article", view.SubmitArticle(args, db, store))
|
||||
mux.HandleFunc("POST /update-user", view.UpdateUser(args, db, store))
|
||||
mux.HandleFunc("POST /update-self", view.UpdateSelf(args, db, store))
|
||||
mux.HandleFunc("POST /update-user/{id}", view.UpdateUser(args, db, store))
|
||||
mux.HandleFunc("POST /upload-image", view.UploadImage(args))
|
||||
|
||||
log.Fatalln(http.ListenAndServe(args.Port, mux))
|
||||
|
@ -145,7 +145,7 @@ func (db *DB) GetUser(id int64) (*User, error) {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (db *DB) UpdateUserAttributes(id int64, user, first, last, oldPass, newPass, newPass2 string) error {
|
||||
func (db *DB) UpdateOwnAttributes(id int64, user, first, last, oldPass, newPass, newPass2 string) error {
|
||||
passwordEmpty := true
|
||||
if len(newPass) > 0 || len(newPass2) > 0 {
|
||||
if newPass != newPass2 {
|
||||
@ -268,3 +268,105 @@ func (db *DB) AddFirstUser(u *User, pass string) (int64, error) {
|
||||
}
|
||||
return 0, fmt.Errorf("error: %v unsuccessful retries for DB operation, aborting", TxMaxRetries)
|
||||
}
|
||||
|
||||
func (db *DB) GetAllUsers() ([]*User, error) {
|
||||
query := "SELECT id, username, first_name, last_name, role FROM users"
|
||||
|
||||
rows, err := db.Query(query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting all users from DB: %v", err)
|
||||
}
|
||||
|
||||
users := make([]*User, 0)
|
||||
for rows.Next() {
|
||||
user := new(User)
|
||||
if err = rows.Scan(&user.ID, &user.UserName, &user.FirstName,
|
||||
&user.LastName, &user.Role); err != nil {
|
||||
return nil, fmt.Errorf("error getting user info: %v", err)
|
||||
}
|
||||
users = append(users, user)
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (tx *Tx) SetPassword(id int64, newPass string) error {
|
||||
hashedPass, err := bcrypt.GenerateFromPassword([]byte(newPass), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
|
||||
}
|
||||
return fmt.Errorf("error creating password hash: %v", err)
|
||||
}
|
||||
|
||||
setQuery := `
|
||||
UPDATE users
|
||||
SET password = ?
|
||||
WHERE id = ?
|
||||
`
|
||||
if _, err = tx.Exec(setQuery, string(hashedPass), id); err != nil {
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
|
||||
}
|
||||
return fmt.Errorf("error updating password in DB: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DB) UpdateUserAttributes(id int64, user, first, last, newPass, newPass2 string, role int) error {
|
||||
passwordEmpty := true
|
||||
if len(newPass) > 0 || len(newPass2) > 0 {
|
||||
if newPass != newPass2 {
|
||||
return fmt.Errorf("error: passwords do not match")
|
||||
}
|
||||
passwordEmpty = false
|
||||
}
|
||||
|
||||
tx := new(Tx)
|
||||
var err error
|
||||
|
||||
for i := 0; i < TxMaxRetries; i++ {
|
||||
err := func() error {
|
||||
tx.Tx, err = db.Begin()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error starting transaction: %v", err)
|
||||
}
|
||||
|
||||
if !passwordEmpty {
|
||||
if err = tx.SetPassword(id, newPass); err != nil {
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
|
||||
}
|
||||
return fmt.Errorf("error changing password: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = tx.UpdateAttributes(
|
||||
&Attribute{Table: "users", ID: id, AttName: "username", Value: user},
|
||||
&Attribute{Table: "users", ID: id, AttName: "first_name", Value: first},
|
||||
&Attribute{Table: "users", ID: id, AttName: "last_name", Value: last},
|
||||
&Attribute{Table: "users", ID: id, AttName: "role", Value: role},
|
||||
); err != nil {
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
|
||||
}
|
||||
return fmt.Errorf("error updating attributes in DB: %v", err)
|
||||
}
|
||||
|
||||
if err = tx.Commit(); err != nil {
|
||||
return fmt.Errorf("error committing transaction: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Println(err)
|
||||
wait(i)
|
||||
}
|
||||
|
||||
return fmt.Errorf("error: %v unsuccessful retries for DB operation, aborting", TxMaxRetries)
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func AddUser(c *control.CliArgs, db *model.DB, s *control.CookieStore) http.Hand
|
||||
}
|
||||
}
|
||||
|
||||
func EditUser(c *control.CliArgs, db *model.DB, s *control.CookieStore) http.HandlerFunc {
|
||||
func EditSelf(c *control.CliArgs, db *model.DB, s *control.CookieStore) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
session, err := s.Get(r, "cookie")
|
||||
if err != nil {
|
||||
@ -116,12 +116,12 @@ func EditUser(c *control.CliArgs, db *model.DB, s *control.CookieStore) http.Han
|
||||
return
|
||||
}
|
||||
|
||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-self.html")
|
||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", user)
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateUser(c *control.CliArgs, db *model.DB, s *control.CookieStore) http.HandlerFunc {
|
||||
func UpdateSelf(c *control.CliArgs, db *model.DB, s *control.CookieStore) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
session, err := s.Get(r, "cookie")
|
||||
if err != nil {
|
||||
@ -172,7 +172,7 @@ func UpdateUser(c *control.CliArgs, db *model.DB, s *control.CookieStore) http.H
|
||||
}
|
||||
}
|
||||
|
||||
if err = db.UpdateUserAttributes(
|
||||
if err = db.UpdateOwnAttributes(
|
||||
userData.ID,
|
||||
userData.UserName,
|
||||
userData.FirstName,
|
||||
@ -265,3 +265,115 @@ func AddFirstUser(c *control.CliArgs, db *model.DB, s *control.CookieStore) http
|
||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", 0)
|
||||
}
|
||||
}
|
||||
|
||||
func ShowAllUsers(c *control.CliArgs, db *model.DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
users, err := db.GetAllUsers()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/show-all-users.html")
|
||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", users)
|
||||
}
|
||||
}
|
||||
|
||||
func EditUser(c *control.CliArgs, db *model.DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := db.GetUser(id)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", user)
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateUser(c *control.CliArgs, db *model.DB, s *control.CookieStore) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
role, err := strconv.Atoi(r.PostFormValue("role"))
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
userData := UserData{
|
||||
User: &model.User{
|
||||
ID: id,
|
||||
UserName: r.PostFormValue("username"),
|
||||
FirstName: r.PostFormValue("first-name"),
|
||||
LastName: r.PostFormValue("last-name"),
|
||||
Role: role,
|
||||
},
|
||||
}
|
||||
newPass := r.PostFormValue("password")
|
||||
newPass2 := r.PostFormValue("password2")
|
||||
|
||||
if len(userData.UserName) == 0 || len(userData.FirstName) == 0 ||
|
||||
len(userData.LastName) == 0 {
|
||||
userData.Msg = "Alle Felder mit * müssen ausgefüllt sein."
|
||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
||||
tmpl = template.Must(tmpl, err)
|
||||
tmpl.ExecuteTemplate(w, "page-content", userData.Msg)
|
||||
return
|
||||
}
|
||||
|
||||
userString, stringLen, ok := checkUserStrings(userData.User)
|
||||
if !ok {
|
||||
userData.Msg = fmt.Sprint(userString, " ist zu lang. Maximal ",
|
||||
stringLen, " Zeichen erlaubt.")
|
||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
||||
tmpl = template.Must(tmpl, err)
|
||||
tmpl.ExecuteTemplate(w, "page-content", userData)
|
||||
return
|
||||
}
|
||||
|
||||
if id, ok := db.GetID(userData.UserName); ok {
|
||||
if id != userData.ID {
|
||||
userData.Msg = "Benutzername bereits vergeben."
|
||||
userData.UserName = ""
|
||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
||||
tmpl = template.Must(tmpl, err)
|
||||
tmpl.ExecuteTemplate(w, "page-content", userData)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = db.UpdateUserAttributes(
|
||||
userData.ID,
|
||||
userData.UserName,
|
||||
userData.FirstName,
|
||||
userData.LastName,
|
||||
newPass,
|
||||
newPass2,
|
||||
userData.Role); err != nil {
|
||||
userData.Msg = "Aktualisierung der Benutzerdaten fehlgeschlagen."
|
||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/edit-user.html")
|
||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", userData)
|
||||
}
|
||||
|
||||
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
|
||||
tmpl = template.Must(tmpl, err)
|
||||
tmpl.ExecuteTemplate(w, "page-content", 0)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user