1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2025-01-08 19:00:25 +00:00

New user form in /admin/users/

This commit is contained in:
handlerug 2021-07-02 19:02:42 +07:00
parent d4fea3d24a
commit 1c24450a8f
No known key found for this signature in database
GPG Key ID: 38009F0605051491
6 changed files with 420 additions and 101 deletions

View File

@ -313,9 +313,6 @@ mark { background: rgba(130, 80, 30, 5); color: inherit; }
} }
} }
/* handlerug: sorry but I can't write in that unique and very special way */
/* i have to resort to the BORING way of writing CSS */
/* bouncepaw: they say that the best codes style is the consistent code style ☝️ */
kbd { kbd {
display: inline-block; display: inline-block;
min-width: 1.5ch; min-width: 1.5ch;
@ -435,3 +432,55 @@ kbd {
.table-cell--fill { .table-cell--fill {
width: 100%; width: 100%;
} }
/*
* Form fields
*/
.form-field {
margin: 1em 0;
}
.form-field label {
display: block;
}
@media (min-width: 600px) {
.form-field {
display: grid;
grid-template-columns: 150px max-content;
grid-column-gap: 16px;
}
.form-field label {
grid-column: 1;
}
.form-field input,
.form-field button,
.form-field select,
.form-field textarea,
.form-field .form-field__input {
grid-column: 2;
}
}
/*
* Notices
*/
.notice {
margin: 0.5em 0;
border: 1px solid;
padding: 0.5em 0.7em;
}
.notice--error {
border-color: #e15757;
background-color: #ffb1b1;
}
@media (prefers-color-scheme: dark) {
.notice--error {
border-color: #a84343;
background-color: #5b3535;
}
}

View File

@ -41,10 +41,12 @@ func Register(username, password, group string, force bool) error {
switch { switch {
case !util.IsPossibleUsername(username): case !util.IsPossibleUsername(username):
return fmt.Errorf("illegal username \"%s\"", username) return fmt.Errorf("illegal username \"%s\"", username)
case !ValidGroup(group):
return fmt.Errorf("invalid group \"%s\"", group)
case HasUsername(username):
return fmt.Errorf("username \"%s\" is already taken", username)
case !force && cfg.RegistrationLimit > 0 && Count() >= cfg.RegistrationLimit: case !force && cfg.RegistrationLimit > 0 && Count() >= cfg.RegistrationLimit:
return fmt.Errorf("reached the limit of registered users (%d)", cfg.RegistrationLimit) return fmt.Errorf("reached the limit of registered users (%d)", cfg.RegistrationLimit)
case !force && HasUsername(username):
return fmt.Errorf("username \"%s\" is already taken", username)
} }
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)

View File

@ -91,3 +91,49 @@ func HyphaNameFromRq(rq *http.Request, actions ...string) string {
log.Println("HyphaNameFromRq: this request is invalid, fall back to home hypha") log.Println("HyphaNameFromRq: this request is invalid, fall back to home hypha")
return cfg.HomeHypha return cfg.HomeHypha
} }
// FormData is a convenient struct for passing user input and errors to HTML
// forms and showing to the user.
type FormData struct {
err error
fields map[string]string
}
func NewFormData() FormData {
return FormData{
err: nil,
fields: map[string]string{},
}
}
func FormDataFromRequest(r *http.Request, keys []string) FormData {
formData := NewFormData()
for _, key := range keys {
formData.Put(key, r.FormValue(key))
}
return formData
}
func (f FormData) HasError() bool {
return f.err != nil
}
func (f FormData) Error() string {
if f.err == nil {
return ""
}
return f.err.Error()
}
func (f FormData) WithError(err error) FormData {
f.err = err
return f
}
func (f FormData) Get(key string) string {
return f.fields[key]
}
func (f FormData) Put(key, value string) {
f.fields[key] = value
}

View File

@ -1,5 +1,6 @@
{% import "github.com/bouncepaw/mycorrhiza/cfg" %} {% import "github.com/bouncepaw/mycorrhiza/cfg" %}
{% import "github.com/bouncepaw/mycorrhiza/user" %} {% import "github.com/bouncepaw/mycorrhiza/user" %}
{% import "github.com/bouncepaw/mycorrhiza/util" %}
{% func AdminPanelHTML() %} {% func AdminPanelHTML() %}
<div class="layout"> <div class="layout">
@ -39,10 +40,11 @@
<h1>Manage users</h1> <h1>Manage users</h1>
<form action="/admin/reindex-users" method="post"> <form action="/admin/reindex-users" method="post">
<a class="btn" href="/admin/user/new">Create a new user</a>
<button class="btn" type="submit">Reindex users</button> <button class="btn" type="submit">Reindex users</button>
</form> </form>
<h2>Users list</h2> <br>
<table class="users-table"> <table class="users-table">
<thead> <thead>
@ -78,6 +80,51 @@
</div> </div>
{% endfunc %} {% endfunc %}
{% func AdminUserNewHTML(formData util.FormData) %}
<div class="layout">
<main class="main-width">
<h1>New user</h1>
{% if formData.HasError() %}
<div class="notice notice--error">
<strong>Error:</strong>
{%s formData.Error() %}
</div>
{% endif %}
<form action="" method="post">
<div class="form-field">
<label for="name">Name:</label>
<input type="text" name="name" id="name" value="{%s formData.Get("name") %}">
</div>
<div class="form-field">
<label for="password">Password:</label>
<input type="password" name="password" id="password" value="{%s formData.Get("password") %}">
</div>
<div class="form-field">
<label for="group">Group:</label>
<select id="group" name="group">
<option{% if formData.Get("group") == "anon" %} selected{% endif %}>anon</option>
<option{% if formData.Get("group") == "editor" %} selected{% endif %}>editor</option>
<option{% if formData.Get("group") == "trusted" %} selected{% endif %}>trusted</option>
<option{% if formData.Get("group") == "moderator" %} selected{% endif %}>moderator</option>
<option{% if formData.Get("group") == "admin" %} selected{% endif %}>admin</option>
</select>
</div>
<div class="form-field">
<div class="form-field__input">
<button class="btn" type="submit">Create</button>
<a class="btn btn_weak" href="/admin/users/">Cancel</a>
</div>
</div>
</form>
</main>
</div>
{% endfunc %}
{% func AdminUsersUserHTML(u *user.User) %} {% func AdminUsersUserHTML(u *user.User) %}
<div class="layout"> <div class="layout">
<main class="main-width"> <main class="main-width">

View File

@ -10,22 +10,25 @@ import "github.com/bouncepaw/mycorrhiza/cfg"
//line views/admin.qtpl:2 //line views/admin.qtpl:2
import "github.com/bouncepaw/mycorrhiza/user" import "github.com/bouncepaw/mycorrhiza/user"
//line views/admin.qtpl:4 //line views/admin.qtpl:3
import "github.com/bouncepaw/mycorrhiza/util"
//line views/admin.qtpl:5
import ( import (
qtio422016 "io" qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate" qt422016 "github.com/valyala/quicktemplate"
) )
//line views/admin.qtpl:4 //line views/admin.qtpl:5
var ( var (
_ = qtio422016.Copy _ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer _ = qt422016.AcquireByteBuffer
) )
//line views/admin.qtpl:4 //line views/admin.qtpl:5
func StreamAdminPanelHTML(qw422016 *qt422016.Writer) { func StreamAdminPanelHTML(qw422016 *qt422016.Writer) {
//line views/admin.qtpl:4 //line views/admin.qtpl:5
qw422016.N().S(` qw422016.N().S(`
<div class="layout"> <div class="layout">
<main class="main-width"> <main class="main-width">
@ -57,48 +60,49 @@ func StreamAdminPanelHTML(qw422016 *qt422016.Writer) {
</main> </main>
</div> </div>
`) `)
//line views/admin.qtpl:34 //line views/admin.qtpl:35
} }
//line views/admin.qtpl:34 //line views/admin.qtpl:35
func WriteAdminPanelHTML(qq422016 qtio422016.Writer) { func WriteAdminPanelHTML(qq422016 qtio422016.Writer) {
//line views/admin.qtpl:34 //line views/admin.qtpl:35
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/admin.qtpl:34 //line views/admin.qtpl:35
StreamAdminPanelHTML(qw422016) StreamAdminPanelHTML(qw422016)
//line views/admin.qtpl:34 //line views/admin.qtpl:35
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line views/admin.qtpl:34 //line views/admin.qtpl:35
} }
//line views/admin.qtpl:34 //line views/admin.qtpl:35
func AdminPanelHTML() string { func AdminPanelHTML() string {
//line views/admin.qtpl:34 //line views/admin.qtpl:35
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line views/admin.qtpl:34 //line views/admin.qtpl:35
WriteAdminPanelHTML(qb422016) WriteAdminPanelHTML(qb422016)
//line views/admin.qtpl:34 //line views/admin.qtpl:35
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/admin.qtpl:34 //line views/admin.qtpl:35
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/admin.qtpl:34 //line views/admin.qtpl:35
return qs422016 return qs422016
//line views/admin.qtpl:34 //line views/admin.qtpl:35
} }
//line views/admin.qtpl:36 //line views/admin.qtpl:37
func StreamAdminUsersPanelHTML(qw422016 *qt422016.Writer, userList []*user.User) { func StreamAdminUsersPanelHTML(qw422016 *qt422016.Writer, userList []*user.User) {
//line views/admin.qtpl:36 //line views/admin.qtpl:37
qw422016.N().S(` qw422016.N().S(`
<div class="layout"> <div class="layout">
<main class="main-width"> <main class="main-width">
<h1>Manage users</h1> <h1>Manage users</h1>
<form action="/admin/reindex-users" method="post"> <form action="/admin/reindex-users" method="post">
<a class="btn" href="/admin/user/new">Create a new user</a>
<button class="btn" type="submit">Reindex users</button> <button class="btn" type="submit">Reindex users</button>
</form> </form>
<h2>Users list</h2> <br>
<table class="users-table"> <table class="users-table">
<thead> <thead>
@ -111,111 +115,247 @@ func StreamAdminUsersPanelHTML(qw422016 *qt422016.Writer, userList []*user.User)
</thead> </thead>
<tbody> <tbody>
`) `)
//line views/admin.qtpl:57 //line views/admin.qtpl:59
for _, u := range userList { for _, u := range userList {
//line views/admin.qtpl:57 //line views/admin.qtpl:59
qw422016.N().S(` qw422016.N().S(`
<tr> <tr>
<td class="table-cell--fill"> <td class="table-cell--fill">
<a href="/hypha/`) <a href="/hypha/`)
//line views/admin.qtpl:60 //line views/admin.qtpl:62
qw422016.N().U(cfg.UserHypha) qw422016.N().U(cfg.UserHypha)
//line views/admin.qtpl:60 //line views/admin.qtpl:62
qw422016.N().S(`/`) qw422016.N().S(`/`)
//line views/admin.qtpl:60 //line views/admin.qtpl:62
qw422016.N().U(u.Name) qw422016.N().U(u.Name)
//line views/admin.qtpl:60 //line views/admin.qtpl:62
qw422016.N().S(`">`) qw422016.N().S(`">`)
//line views/admin.qtpl:60 //line views/admin.qtpl:62
qw422016.E().S(u.Name) qw422016.E().S(u.Name)
//line views/admin.qtpl:60 //line views/admin.qtpl:62
qw422016.N().S(`</a> qw422016.N().S(`</a>
</td> </td>
<td>`) <td>`)
//line views/admin.qtpl:62 //line views/admin.qtpl:64
qw422016.E().S(u.Group) qw422016.E().S(u.Group)
//line views/admin.qtpl:62 //line views/admin.qtpl:64
qw422016.N().S(`</td> qw422016.N().S(`</td>
<td> <td>
`) `)
//line views/admin.qtpl:64 //line views/admin.qtpl:66
if u.RegisteredAt.IsZero() { if u.RegisteredAt.IsZero() {
//line views/admin.qtpl:64 //line views/admin.qtpl:66
qw422016.N().S(` qw422016.N().S(`
unknown unknown
`) `)
//line views/admin.qtpl:66 //line views/admin.qtpl:68
} else { } else {
//line views/admin.qtpl:66 //line views/admin.qtpl:68
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/admin.qtpl:67 //line views/admin.qtpl:69
qw422016.E().S(u.RegisteredAt.UTC().Format("2006-01-02 15:04")) qw422016.E().S(u.RegisteredAt.UTC().Format("2006-01-02 15:04"))
//line views/admin.qtpl:67 //line views/admin.qtpl:69
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/admin.qtpl:68 //line views/admin.qtpl:70
} }
//line views/admin.qtpl:68 //line views/admin.qtpl:70
qw422016.N().S(` qw422016.N().S(`
</td> </td>
<td> <td>
<a href="/admin/users/`) <a href="/admin/users/`)
//line views/admin.qtpl:71 //line views/admin.qtpl:73
qw422016.N().U(u.Name) qw422016.N().U(u.Name)
//line views/admin.qtpl:71 //line views/admin.qtpl:73
qw422016.N().S(`/edit">Edit</a> qw422016.N().S(`/edit">Edit</a>
</td> </td>
</tr> </tr>
`) `)
//line views/admin.qtpl:74 //line views/admin.qtpl:76
} }
//line views/admin.qtpl:74 //line views/admin.qtpl:76
qw422016.N().S(` qw422016.N().S(`
</tbody> </tbody>
</table> </table>
</main> </main>
</div> </div>
`) `)
//line views/admin.qtpl:79 //line views/admin.qtpl:81
} }
//line views/admin.qtpl:79 //line views/admin.qtpl:81
func WriteAdminUsersPanelHTML(qq422016 qtio422016.Writer, userList []*user.User) { func WriteAdminUsersPanelHTML(qq422016 qtio422016.Writer, userList []*user.User) {
//line views/admin.qtpl:79 //line views/admin.qtpl:81
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/admin.qtpl:79 //line views/admin.qtpl:81
StreamAdminUsersPanelHTML(qw422016, userList) StreamAdminUsersPanelHTML(qw422016, userList)
//line views/admin.qtpl:79 //line views/admin.qtpl:81
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line views/admin.qtpl:79 //line views/admin.qtpl:81
} }
//line views/admin.qtpl:79 //line views/admin.qtpl:81
func AdminUsersPanelHTML(userList []*user.User) string { func AdminUsersPanelHTML(userList []*user.User) string {
//line views/admin.qtpl:79 //line views/admin.qtpl:81
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line views/admin.qtpl:79 //line views/admin.qtpl:81
WriteAdminUsersPanelHTML(qb422016, userList) WriteAdminUsersPanelHTML(qb422016, userList)
//line views/admin.qtpl:79 //line views/admin.qtpl:81
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/admin.qtpl:79 //line views/admin.qtpl:81
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/admin.qtpl:79 //line views/admin.qtpl:81
return qs422016 return qs422016
//line views/admin.qtpl:79 //line views/admin.qtpl:81
} }
//line views/admin.qtpl:81 //line views/admin.qtpl:83
func StreamAdminUserNewHTML(qw422016 *qt422016.Writer, formData util.FormData) {
//line views/admin.qtpl:83
qw422016.N().S(`
<div class="layout">
<main class="main-width">
<h1>New user</h1>
`)
//line views/admin.qtpl:88
if formData.HasError() {
//line views/admin.qtpl:88
qw422016.N().S(`
<div class="notice notice--error">
<strong>Error:</strong>
`)
//line views/admin.qtpl:91
qw422016.E().S(formData.Error())
//line views/admin.qtpl:91
qw422016.N().S(`
</div>
`)
//line views/admin.qtpl:93
}
//line views/admin.qtpl:93
qw422016.N().S(`
<form action="" method="post">
<div class="form-field">
<label for="name">Name:</label>
<input type="text" name="name" id="name" value="`)
//line views/admin.qtpl:98
qw422016.E().S(formData.Get("name"))
//line views/admin.qtpl:98
qw422016.N().S(`">
</div>
<div class="form-field">
<label for="password">Password:</label>
<input type="password" name="password" id="password" value="`)
//line views/admin.qtpl:103
qw422016.E().S(formData.Get("password"))
//line views/admin.qtpl:103
qw422016.N().S(`">
</div>
<div class="form-field">
<label for="group">Group:</label>
<select id="group" name="group">
<option`)
//line views/admin.qtpl:109
if formData.Get("group") == "anon" {
//line views/admin.qtpl:109
qw422016.N().S(` selected`)
//line views/admin.qtpl:109
}
//line views/admin.qtpl:109
qw422016.N().S(`>anon</option>
<option`)
//line views/admin.qtpl:110
if formData.Get("group") == "editor" {
//line views/admin.qtpl:110
qw422016.N().S(` selected`)
//line views/admin.qtpl:110
}
//line views/admin.qtpl:110
qw422016.N().S(`>editor</option>
<option`)
//line views/admin.qtpl:111
if formData.Get("group") == "trusted" {
//line views/admin.qtpl:111
qw422016.N().S(` selected`)
//line views/admin.qtpl:111
}
//line views/admin.qtpl:111
qw422016.N().S(`>trusted</option>
<option`)
//line views/admin.qtpl:112
if formData.Get("group") == "moderator" {
//line views/admin.qtpl:112
qw422016.N().S(` selected`)
//line views/admin.qtpl:112
}
//line views/admin.qtpl:112
qw422016.N().S(`>moderator</option>
<option`)
//line views/admin.qtpl:113
if formData.Get("group") == "admin" {
//line views/admin.qtpl:113
qw422016.N().S(` selected`)
//line views/admin.qtpl:113
}
//line views/admin.qtpl:113
qw422016.N().S(`>admin</option>
</select>
</div>
<div class="form-field">
<div class="form-field__input">
<button class="btn" type="submit">Create</button>
<a class="btn btn_weak" href="/admin/users/">Cancel</a>
</div>
</div>
</form>
</main>
</div>
`)
//line views/admin.qtpl:126
}
//line views/admin.qtpl:126
func WriteAdminUserNewHTML(qq422016 qtio422016.Writer, formData util.FormData) {
//line views/admin.qtpl:126
qw422016 := qt422016.AcquireWriter(qq422016)
//line views/admin.qtpl:126
StreamAdminUserNewHTML(qw422016, formData)
//line views/admin.qtpl:126
qt422016.ReleaseWriter(qw422016)
//line views/admin.qtpl:126
}
//line views/admin.qtpl:126
func AdminUserNewHTML(formData util.FormData) string {
//line views/admin.qtpl:126
qb422016 := qt422016.AcquireByteBuffer()
//line views/admin.qtpl:126
WriteAdminUserNewHTML(qb422016, formData)
//line views/admin.qtpl:126
qs422016 := string(qb422016.B)
//line views/admin.qtpl:126
qt422016.ReleaseByteBuffer(qb422016)
//line views/admin.qtpl:126
return qs422016
//line views/admin.qtpl:126
}
//line views/admin.qtpl:128
func StreamAdminUsersUserHTML(qw422016 *qt422016.Writer, u *user.User) { func StreamAdminUsersUserHTML(qw422016 *qt422016.Writer, u *user.User) {
//line views/admin.qtpl:81 //line views/admin.qtpl:128
qw422016.N().S(` qw422016.N().S(`
<div class="layout"> <div class="layout">
<main class="main-width"> <main class="main-width">
<h1>`) <h1>`)
//line views/admin.qtpl:84 //line views/admin.qtpl:131
qw422016.E().S(u.Name) qw422016.E().S(u.Name)
//line views/admin.qtpl:84 //line views/admin.qtpl:131
qw422016.N().S(`</h1> qw422016.N().S(`</h1>
<form action="" method="post"> <form action="" method="post">
@ -223,49 +363,49 @@ func StreamAdminUsersUserHTML(qw422016 *qt422016.Writer, u *user.User) {
<label for="group">Group:</label> <label for="group">Group:</label>
<select id="group" name="group"> <select id="group" name="group">
<option`) <option`)
//line views/admin.qtpl:90 //line views/admin.qtpl:137
if u.Group == "anon" { if u.Group == "anon" {
//line views/admin.qtpl:90 //line views/admin.qtpl:137
qw422016.N().S(` selected`) qw422016.N().S(` selected`)
//line views/admin.qtpl:90 //line views/admin.qtpl:137
} }
//line views/admin.qtpl:90 //line views/admin.qtpl:137
qw422016.N().S(`>anon</option> qw422016.N().S(`>anon</option>
<option`) <option`)
//line views/admin.qtpl:91 //line views/admin.qtpl:138
if u.Group == "editor" { if u.Group == "editor" {
//line views/admin.qtpl:91 //line views/admin.qtpl:138
qw422016.N().S(` selected`) qw422016.N().S(` selected`)
//line views/admin.qtpl:91 //line views/admin.qtpl:138
} }
//line views/admin.qtpl:91 //line views/admin.qtpl:138
qw422016.N().S(`>editor</option> qw422016.N().S(`>editor</option>
<option`) <option`)
//line views/admin.qtpl:92 //line views/admin.qtpl:139
if u.Group == "trusted" { if u.Group == "trusted" {
//line views/admin.qtpl:92 //line views/admin.qtpl:139
qw422016.N().S(` selected`) qw422016.N().S(` selected`)
//line views/admin.qtpl:92 //line views/admin.qtpl:139
} }
//line views/admin.qtpl:92 //line views/admin.qtpl:139
qw422016.N().S(`>trusted</option> qw422016.N().S(`>trusted</option>
<option`) <option`)
//line views/admin.qtpl:93 //line views/admin.qtpl:140
if u.Group == "moderator" { if u.Group == "moderator" {
//line views/admin.qtpl:93 //line views/admin.qtpl:140
qw422016.N().S(` selected`) qw422016.N().S(` selected`)
//line views/admin.qtpl:93 //line views/admin.qtpl:140
} }
//line views/admin.qtpl:93 //line views/admin.qtpl:140
qw422016.N().S(`>moderator</option> qw422016.N().S(`>moderator</option>
<option`) <option`)
//line views/admin.qtpl:94 //line views/admin.qtpl:141
if u.Group == "admin" { if u.Group == "admin" {
//line views/admin.qtpl:94 //line views/admin.qtpl:141
qw422016.N().S(` selected`) qw422016.N().S(` selected`)
//line views/admin.qtpl:94 //line views/admin.qtpl:141
} }
//line views/admin.qtpl:94 //line views/admin.qtpl:141
qw422016.N().S(`>admin</option> qw422016.N().S(`>admin</option>
</select> </select>
</div> </div>
@ -276,31 +416,31 @@ func StreamAdminUsersUserHTML(qw422016 *qt422016.Writer, u *user.User) {
</main> </main>
</div> </div>
`) `)
//line views/admin.qtpl:103 //line views/admin.qtpl:150
} }
//line views/admin.qtpl:103 //line views/admin.qtpl:150
func WriteAdminUsersUserHTML(qq422016 qtio422016.Writer, u *user.User) { func WriteAdminUsersUserHTML(qq422016 qtio422016.Writer, u *user.User) {
//line views/admin.qtpl:103 //line views/admin.qtpl:150
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/admin.qtpl:103 //line views/admin.qtpl:150
StreamAdminUsersUserHTML(qw422016, u) StreamAdminUsersUserHTML(qw422016, u)
//line views/admin.qtpl:103 //line views/admin.qtpl:150
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line views/admin.qtpl:103 //line views/admin.qtpl:150
} }
//line views/admin.qtpl:103 //line views/admin.qtpl:150
func AdminUsersUserHTML(u *user.User) string { func AdminUsersUserHTML(u *user.User) string {
//line views/admin.qtpl:103 //line views/admin.qtpl:150
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line views/admin.qtpl:103 //line views/admin.qtpl:150
WriteAdminUsersUserHTML(qb422016, u) WriteAdminUsersUserHTML(qb422016, u)
//line views/admin.qtpl:103 //line views/admin.qtpl:150
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/admin.qtpl:103 //line views/admin.qtpl:150
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/admin.qtpl:103 //line views/admin.qtpl:150
return qs422016 return qs422016
//line views/admin.qtpl:103 //line views/admin.qtpl:150
} }

View File

@ -23,6 +23,7 @@ func initAdmin() {
http.HandleFunc("/admin/reindex-users/", handlerAdminReindexUsers) http.HandleFunc("/admin/reindex-users/", handlerAdminReindexUsers)
http.HandleFunc("/admin/users/", handlerAdminUsers) http.HandleFunc("/admin/users/", handlerAdminUsers)
http.HandleFunc("/admin/user/new", handlerAdminUserNew)
} }
} }
@ -124,7 +125,41 @@ func handlerAdminUsers(w http.ResponseWriter, r *http.Request) {
} }
} }
} }
}
util.HTTP404Page(w, "404 page not found") util.HTTP404Page(w, "404 page not found")
} }
func handlerAdminUserNew(w http.ResponseWriter, r *http.Request) {
util.PrepareRq(r)
if user.CanProceed(r, "admin") {
if r.Method == http.MethodGet {
// New user form
html := views.AdminUserNewHTML(util.NewFormData())
html = views.BaseHTML("New user", html, user.FromRequest(r))
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
io.WriteString(w, html)
return
} else if r.Method == http.MethodPost {
// Create a user
f := util.FormDataFromRequest(r, []string{"name", "password", "group"})
err := user.Register(f.Get("name"), f.Get("password"), f.Get("group"), true)
if err != nil {
html := views.AdminUserNewHTML(f.WithError(err))
html = views.BaseHTML("New user", html, user.FromRequest(r))
w.WriteHeader(http.StatusBadRequest)
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
io.WriteString(w, html)
} else {
http.Redirect(w, r, "/admin/users/", http.StatusSeeOther)
}
return
}
}
util.HTTP404Page(w, "404 page not found")
} }