Add education toggle to user admin settings

This commit is contained in:
Ben Visness 2022-09-10 16:52:02 -05:00
parent 168b210c5b
commit 045a2c2379
5 changed files with 50 additions and 25 deletions

View File

@ -112,7 +112,7 @@ func TestUserSettings(t *testing.T) {
func TestAdmin(t *testing.T) {
AssertRegexMatch(t, BuildAdminAtomFeed(), RegexAdminAtomFeed, nil)
AssertRegexMatch(t, BuildAdminApprovalQueue(), RegexAdminApprovalQueue, nil)
AssertRegexMatch(t, BuildAdminSetUserStatus(), RegexAdminSetUserStatus, nil)
AssertRegexMatch(t, BuildAdminSetUserOptions(), RegexAdminSetUserOptions, nil)
AssertRegexMatch(t, BuildAdminNukeUser(), RegexAdminNukeUser, nil)
}

View File

@ -245,11 +245,11 @@ func BuildAdminApprovalQueue() string {
return Url("/admin/approvals", nil)
}
var RegexAdminSetUserStatus = regexp.MustCompile(`^/admin/setuserstatus$`)
var RegexAdminSetUserOptions = regexp.MustCompile(`^/admin/setuseroptions$`)
func BuildAdminSetUserStatus() string {
func BuildAdminSetUserOptions() string {
defer CatchPanic()
return Url("/admin/setuserstatus", nil)
return Url("/admin/setuseroptions", nil)
}
var RegexAdminNukeUser = regexp.MustCompile(`^/admin/nukeuser$`)

View File

@ -73,22 +73,33 @@
</div>
<div class="relative w-100">
<div class="bg--card cover absolute w-100 h-100 br2"></div>
<div class="mt3">
<div>User status:</div>
<form id="admin_set_status_form" method="POST" action="{{ .AdminSetStatusUrl }}">
{{ csrftoken .Session }}
<input type="hidden" name="user_id" value="{{ .ProfileUser.ID }}" />
<input type="hidden" name="username" value="{{ .ProfileUser.Username }}" />
<form id="admin_set_options_form" method="POST" action="{{ .AdminSetOptionsUrl }}">
{{ csrftoken .Session }}
<input type="hidden" name="user_id" value="{{ .ProfileUser.ID }}" />
<input type="hidden" name="username" value="{{ .ProfileUser.Username }}" />
<div class="mt3">
<div>User status:</div>
<select name="status">
<option value="inactive" {{ if eq .ProfileUser.Status 1 }}selected{{ end }}>Brand new</option>
<option value="confirmed" {{ if eq .ProfileUser.Status 2 }}selected{{ end }}>Email confirmed</option>
<option value="approved" {{ if eq .ProfileUser.Status 3 }}selected{{ end }}>Admin approved</option>
<option value="banned" {{ if eq .ProfileUser.Status 4 }}selected{{ end }}>Banned</option>
</select>
<input type="submit" value="Set" />
<div class="c--dim f7">Only sets status. Doesn't delete anything.</div>
</form>
</div>
</div>
<div class="mt3">
<div>Education role:</div>
<select name="edu_role">
<option value="none" {{ if not .ProfileUser.IsEduTester }}selected{{ end }}>None</option>
<option value="beta" {{ if and .ProfileUser.IsEduTester (not .ProfileUser.IsEduAuthor) }}selected{{ end }}>Beta Tester</option>
<option value="author" {{ if .ProfileUser.IsEduAuthor }}selected{{ end }}>Author</option>
</select>
</div>
<div class="mt3">
<input type="submit" value="Save" />
</div>
</form>
<div class="mt3">
<div>Danger zone:</div>
<form id="admin_nuke_form" method="POST" action="{{ .AdminNukeUrl }}">
@ -110,7 +121,7 @@
panelEl.style.display = "none";
});
document.querySelector("#admin_set_status_form").addEventListener("submit", function(ev) {
document.querySelector("#admin_set_options_form").addEventListener("submit", function(ev) {
if (!adminUnlocked) {
ev.preventDefault();
}

View File

@ -81,7 +81,7 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler {
hmnOnly.GET(hmnurl.RegexAdminAtomFeed, AdminAtomFeed)
hmnOnly.GET(hmnurl.RegexAdminApprovalQueue, adminsOnly(AdminApprovalQueue))
hmnOnly.POST(hmnurl.RegexAdminApprovalQueue, adminsOnly(csrfMiddleware(AdminApprovalQueueSubmit)))
hmnOnly.POST(hmnurl.RegexAdminSetUserStatus, adminsOnly(csrfMiddleware(UserProfileAdminSetStatus)))
hmnOnly.POST(hmnurl.RegexAdminSetUserOptions, adminsOnly(csrfMiddleware(UserProfileAdminSetOptions)))
hmnOnly.POST(hmnurl.RegexAdminNukeUser, adminsOnly(csrfMiddleware(UserProfileAdminNuke)))
hmnOnly.GET(hmnurl.RegexFeed, Feed)

View File

@ -36,8 +36,8 @@ type UserProfileTemplateData struct {
CanAddProject bool
NewProjectUrl string
AdminSetStatusUrl string
AdminNukeUrl string
AdminSetOptionsUrl string
AdminNukeUrl string
SnippetEdit templates.SnippetEdit
}
@ -194,8 +194,8 @@ func UserProfile(c *RequestContext) ResponseData {
CanAddProject: numPersonalProjects < maxPersonalProjects,
NewProjectUrl: hmnurl.BuildProjectNew(),
AdminSetStatusUrl: hmnurl.BuildAdminSetUserStatus(),
AdminNukeUrl: hmnurl.BuildAdminNukeUser(),
AdminSetOptionsUrl: hmnurl.BuildAdminSetUserOptions(),
AdminNukeUrl: hmnurl.BuildAdminNukeUser(),
SnippetEdit: snippetEdit,
}, c.Perf)
@ -479,7 +479,7 @@ func UserSettingsSave(c *RequestContext) ResponseData {
return res
}
func UserProfileAdminSetStatus(c *RequestContext) ResponseData {
func UserProfileAdminSetOptions(c *RequestContext) ResponseData {
c.Req.ParseForm()
userIdStr := c.Req.Form.Get("user_id")
@ -503,17 +503,31 @@ func UserProfileAdminSetStatus(c *RequestContext) ResponseData {
return c.RejectRequest("No legal user status provided")
}
eduRole := c.Req.Form.Get("edu_role")
var desiredEduRole models.EduRole
switch eduRole {
case "none":
desiredEduRole = models.EduRoleNone
case "beta":
desiredEduRole = models.EduRoleBeta
case "author":
desiredEduRole = models.EduRoleAuthor
default:
return c.RejectRequest("the education role is bad and you should feel bad")
}
_, err = c.Conn.Exec(c,
`
UPDATE hmn_user
SET status = $1
WHERE id = $2
SET status = $2, education_role = $3
WHERE id = $1
`,
desiredStatus,
userId,
desiredStatus,
desiredEduRole,
)
if err != nil {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user status"))
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user admin settings"))
}
if desiredStatus == models.UserStatusBanned {
err = auth.DeleteSessionForUser(c, c.Conn, c.Req.Form.Get("username"))
@ -522,7 +536,7 @@ func UserProfileAdminSetStatus(c *RequestContext) ResponseData {
}
}
res := c.Redirect(hmnurl.BuildUserProfile(c.Req.Form.Get("username")), http.StatusSeeOther)
res.AddFutureNotice("success", "Successfully set status")
res.AddFutureNotice("success", "Successfully set admin options")
return res
}