Add education toggle to user admin settings
This commit is contained in:
parent
168b210c5b
commit
045a2c2379
|
@ -112,7 +112,7 @@ func TestUserSettings(t *testing.T) {
|
||||||
func TestAdmin(t *testing.T) {
|
func TestAdmin(t *testing.T) {
|
||||||
AssertRegexMatch(t, BuildAdminAtomFeed(), RegexAdminAtomFeed, nil)
|
AssertRegexMatch(t, BuildAdminAtomFeed(), RegexAdminAtomFeed, nil)
|
||||||
AssertRegexMatch(t, BuildAdminApprovalQueue(), RegexAdminApprovalQueue, nil)
|
AssertRegexMatch(t, BuildAdminApprovalQueue(), RegexAdminApprovalQueue, nil)
|
||||||
AssertRegexMatch(t, BuildAdminSetUserStatus(), RegexAdminSetUserStatus, nil)
|
AssertRegexMatch(t, BuildAdminSetUserOptions(), RegexAdminSetUserOptions, nil)
|
||||||
AssertRegexMatch(t, BuildAdminNukeUser(), RegexAdminNukeUser, nil)
|
AssertRegexMatch(t, BuildAdminNukeUser(), RegexAdminNukeUser, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,11 +245,11 @@ func BuildAdminApprovalQueue() string {
|
||||||
return Url("/admin/approvals", nil)
|
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()
|
defer CatchPanic()
|
||||||
return Url("/admin/setuserstatus", nil)
|
return Url("/admin/setuseroptions", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexAdminNukeUser = regexp.MustCompile(`^/admin/nukeuser$`)
|
var RegexAdminNukeUser = regexp.MustCompile(`^/admin/nukeuser$`)
|
||||||
|
|
|
@ -73,22 +73,33 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="relative w-100">
|
<div class="relative w-100">
|
||||||
<div class="bg--card cover absolute w-100 h-100 br2"></div>
|
<div class="bg--card cover absolute w-100 h-100 br2"></div>
|
||||||
<div class="mt3">
|
<form id="admin_set_options_form" method="POST" action="{{ .AdminSetOptionsUrl }}">
|
||||||
<div>User status:</div>
|
{{ csrftoken .Session }}
|
||||||
<form id="admin_set_status_form" method="POST" action="{{ .AdminSetStatusUrl }}">
|
<input type="hidden" name="user_id" value="{{ .ProfileUser.ID }}" />
|
||||||
{{ csrftoken .Session }}
|
<input type="hidden" name="username" value="{{ .ProfileUser.Username }}" />
|
||||||
<input type="hidden" name="user_id" value="{{ .ProfileUser.ID }}" />
|
<div class="mt3">
|
||||||
<input type="hidden" name="username" value="{{ .ProfileUser.Username }}" />
|
<div>User status:</div>
|
||||||
<select name="status">
|
<select name="status">
|
||||||
<option value="inactive" {{ if eq .ProfileUser.Status 1 }}selected{{ end }}>Brand new</option>
|
<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="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="approved" {{ if eq .ProfileUser.Status 3 }}selected{{ end }}>Admin approved</option>
|
||||||
<option value="banned" {{ if eq .ProfileUser.Status 4 }}selected{{ end }}>Banned</option>
|
<option value="banned" {{ if eq .ProfileUser.Status 4 }}selected{{ end }}>Banned</option>
|
||||||
</select>
|
</select>
|
||||||
<input type="submit" value="Set" />
|
|
||||||
<div class="c--dim f7">Only sets status. Doesn't delete anything.</div>
|
<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 class="mt3">
|
||||||
<div>Danger zone:</div>
|
<div>Danger zone:</div>
|
||||||
<form id="admin_nuke_form" method="POST" action="{{ .AdminNukeUrl }}">
|
<form id="admin_nuke_form" method="POST" action="{{ .AdminNukeUrl }}">
|
||||||
|
@ -110,7 +121,7 @@
|
||||||
panelEl.style.display = "none";
|
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) {
|
if (!adminUnlocked) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler {
|
||||||
hmnOnly.GET(hmnurl.RegexAdminAtomFeed, AdminAtomFeed)
|
hmnOnly.GET(hmnurl.RegexAdminAtomFeed, AdminAtomFeed)
|
||||||
hmnOnly.GET(hmnurl.RegexAdminApprovalQueue, adminsOnly(AdminApprovalQueue))
|
hmnOnly.GET(hmnurl.RegexAdminApprovalQueue, adminsOnly(AdminApprovalQueue))
|
||||||
hmnOnly.POST(hmnurl.RegexAdminApprovalQueue, adminsOnly(csrfMiddleware(AdminApprovalQueueSubmit)))
|
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.POST(hmnurl.RegexAdminNukeUser, adminsOnly(csrfMiddleware(UserProfileAdminNuke)))
|
||||||
|
|
||||||
hmnOnly.GET(hmnurl.RegexFeed, Feed)
|
hmnOnly.GET(hmnurl.RegexFeed, Feed)
|
||||||
|
|
|
@ -36,8 +36,8 @@ type UserProfileTemplateData struct {
|
||||||
CanAddProject bool
|
CanAddProject bool
|
||||||
NewProjectUrl string
|
NewProjectUrl string
|
||||||
|
|
||||||
AdminSetStatusUrl string
|
AdminSetOptionsUrl string
|
||||||
AdminNukeUrl string
|
AdminNukeUrl string
|
||||||
|
|
||||||
SnippetEdit templates.SnippetEdit
|
SnippetEdit templates.SnippetEdit
|
||||||
}
|
}
|
||||||
|
@ -194,8 +194,8 @@ func UserProfile(c *RequestContext) ResponseData {
|
||||||
CanAddProject: numPersonalProjects < maxPersonalProjects,
|
CanAddProject: numPersonalProjects < maxPersonalProjects,
|
||||||
NewProjectUrl: hmnurl.BuildProjectNew(),
|
NewProjectUrl: hmnurl.BuildProjectNew(),
|
||||||
|
|
||||||
AdminSetStatusUrl: hmnurl.BuildAdminSetUserStatus(),
|
AdminSetOptionsUrl: hmnurl.BuildAdminSetUserOptions(),
|
||||||
AdminNukeUrl: hmnurl.BuildAdminNukeUser(),
|
AdminNukeUrl: hmnurl.BuildAdminNukeUser(),
|
||||||
|
|
||||||
SnippetEdit: snippetEdit,
|
SnippetEdit: snippetEdit,
|
||||||
}, c.Perf)
|
}, c.Perf)
|
||||||
|
@ -479,7 +479,7 @@ func UserSettingsSave(c *RequestContext) ResponseData {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserProfileAdminSetStatus(c *RequestContext) ResponseData {
|
func UserProfileAdminSetOptions(c *RequestContext) ResponseData {
|
||||||
c.Req.ParseForm()
|
c.Req.ParseForm()
|
||||||
|
|
||||||
userIdStr := c.Req.Form.Get("user_id")
|
userIdStr := c.Req.Form.Get("user_id")
|
||||||
|
@ -503,17 +503,31 @@ func UserProfileAdminSetStatus(c *RequestContext) ResponseData {
|
||||||
return c.RejectRequest("No legal user status provided")
|
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,
|
_, err = c.Conn.Exec(c,
|
||||||
`
|
`
|
||||||
UPDATE hmn_user
|
UPDATE hmn_user
|
||||||
SET status = $1
|
SET status = $2, education_role = $3
|
||||||
WHERE id = $2
|
WHERE id = $1
|
||||||
`,
|
`,
|
||||||
desiredStatus,
|
|
||||||
userId,
|
userId,
|
||||||
|
desiredStatus,
|
||||||
|
desiredEduRole,
|
||||||
)
|
)
|
||||||
if err != nil {
|
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 {
|
if desiredStatus == models.UserStatusBanned {
|
||||||
err = auth.DeleteSessionForUser(c, c.Conn, c.Req.Form.Get("username"))
|
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 := 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
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue