From 2c9fdcb98e2cd26c70c2a8b096af99e597af1917 Mon Sep 17 00:00:00 2001 From: cblgh Date: Wed, 21 Apr 2021 13:52:44 +0200 Subject: [PATCH] update HTML UI to reflect role access restrictions * disable ui if user is unelevated * disable revoke button if unelevated and not own invite * improve styling of disabled elements * remove revoke if alias not made my current user --- web/handlers/admin/setup_test.go | 4 ++ web/handlers/http.go | 25 ++++++++ web/handlers/notices_test.go | 2 +- web/i18n/defaults/active.de.toml | 1 + web/i18n/defaults/active.en.toml | 1 + web/members/helper.go | 20 +++++- web/templates/admin/denied-keys.tmpl | 19 ++++-- web/templates/admin/invite-list.tmpl | 25 ++++++-- web/templates/admin/member-list.tmpl | 15 +++-- web/templates/admin/member.tmpl | 94 ++++++++++++++++------------ web/templates/admin/settings.tmpl | 12 ++++ web/templates/landing/index.tmpl | 4 +- web/templates/notice/list.tmpl | 4 +- web/templates/notice/show.tmpl | 4 +- 14 files changed, 167 insertions(+), 63 deletions(-) diff --git a/web/handlers/admin/setup_test.go b/web/handlers/admin/setup_test.go index c8bb2f8..eeac3fb 100644 --- a/web/handlers/admin/setup_test.go +++ b/web/handlers/admin/setup_test.go @@ -133,6 +133,10 @@ func newSession(t *testing.T) *testSession { testFuncs["urlToNotice"] = func(name string) string { return "" } testFuncs["language_count"] = func() int { return 1 } testFuncs["list_languages"] = func(*url.URL, string) string { return "" } + testFuncs["member_is_elevated"] = func() bool { return true } + testFuncs["member_is_admin"] = func() bool { return true } + testFuncs["member_can_invite"] = func() bool { return true } + testFuncs["list_languages"] = func(*url.URL, string) string { return "" } testFuncs["relative_time"] = func(when time.Time) string { return humanize.Time(when) } renderOpts := []render.Option{ diff --git a/web/handlers/http.go b/web/handlers/http.go index ed6fefd..5233860 100644 --- a/web/handlers/http.go +++ b/web/handlers/http.go @@ -123,6 +123,31 @@ func New( } }), + render.InjectTemplateFunc("member_can_invite", func(r *http.Request) interface{} { + return func() (bool, error) { + member := members.FromContext(r.Context()) + if member == nil { + return false, nil + } + + pm, err := dbs.Config.GetPrivacyMode(r.Context()) + if err != nil { + return false, err + } + + switch pm { + case roomdb.ModeOpen: + return true, nil + case roomdb.ModeCommunity: + return member.Role > roomdb.RoleUnknown && member.Role <= roomdb.RoleAdmin, nil + case roomdb.ModeRestricted: + return member.Role == roomdb.RoleAdmin || member.Role == roomdb.RoleModerator, nil + default: + return false, nil + } + } + }), + render.InjectTemplateFunc("language_count", func(r *http.Request) interface{} { return func() int { return len(locHelper.ListLanguages()) diff --git a/web/handlers/notices_test.go b/web/handlers/notices_test.go index 3208bf8..fc6ef27 100644 --- a/web/handlers/notices_test.go +++ b/web/handlers/notices_test.go @@ -109,7 +109,7 @@ func TestNoticesEditButtonVisible(t *testing.T) { } // have the database return okay for any user - testUser := roomdb.Member{ID: 23} + testUser := roomdb.Member{ID: 23, Role: roomdb.RoleAdmin} ts.AuthFallbackDB.CheckReturns(testUser.ID, nil) ts.MembersDB.GetByIDReturns(testUser, nil) diff --git a/web/i18n/defaults/active.de.toml b/web/i18n/defaults/active.de.toml index 6bfea8d..2490c94 100644 --- a/web/i18n/defaults/active.de.toml +++ b/web/i18n/defaults/active.de.toml @@ -117,6 +117,7 @@ AdminMemberDetailsRemove = "Mitglied entfernen" AdminMemberAdded = "Mitglied erfolgreich hinzugefügt." AdminMemberUpdated = "Mitglied aktualisiert." AdminMemberRemoved = "Mitglied entfernt." +AdminAddNewMemberTitle = "Add a new member" AdminAliasesRevoke = "Widerrufen" AdminAliasesRevokeConfirmTitle = "Alias ​​widerrufen" diff --git a/web/i18n/defaults/active.en.toml b/web/i18n/defaults/active.en.toml index cd222a3..40c7f2b 100644 --- a/web/i18n/defaults/active.en.toml +++ b/web/i18n/defaults/active.en.toml @@ -124,6 +124,7 @@ AdminMemberDetailsRemove = "Remove member" AdminMemberAdded = "Member added successfully." AdminMemberUpdated = "Member updated." AdminMemberRemoved = "Member removed." +AdminAddNewMemberTitle = "Add a new member" AdminAliasesRevoke = "Revoke" AdminAliasesRevokeConfirmTitle = "Revoke Alias" diff --git a/web/members/helper.go b/web/members/helper.go index 1e2bf98..8677d53 100644 --- a/web/members/helper.go +++ b/web/members/helper.go @@ -92,13 +92,15 @@ func ContextInjecter(mdb roomdb.MembersService, withPassword *auth.Handler, with } // TemplateHelpers returns functions to be used with the go.mindeco.de/http/render package. -// Each has to return a function twice because the first is evaluated with the request before it gets passed onto html/template's FuncMap. +// Each helper has to return a function twice because the first is evaluated with the request before it gets passed onto html/template's FuncMap. // -// {{ is_logged_in }} returns true or false depending if the user is logged in +// {{ is_logged_in }} returns true or false depending on if the user is logged in // // {{ member_has_role "string" }} returns a boolean which confrms wether the member has a certain role (RoleMemeber, RoleAdmin, etc) // // {{ member_is_admin }} is a shortcut for {{ member_has_role "RoleAdmin" }} +// +// {{ member_is_admin }} is a shortcut for {{ or member_has_role "RoleAdmin" member_has_role "RoleModerator"}} func TemplateHelpers() []render.Option { return []render.Option{ @@ -143,5 +145,19 @@ func TemplateHelpers() []render.Option { return member.Role == roomdb.RoleAdmin } }), + + // shorthand for is admin || mod (used for editing notices, managing users, managing aliases) + render.InjectTemplateFunc("member_is_elevated", func(r *http.Request) interface{} { + no := func() bool { return false } + + member := FromContext(r.Context()) + if member == nil { + return no + } + + return func() bool { + return member.Role == roomdb.RoleAdmin || member.Role == roomdb.RoleModerator + } + }), } } diff --git a/web/templates/admin/denied-keys.tmpl b/web/templates/admin/denied-keys.tmpl index 803b757..175bea9 100644 --- a/web/templates/admin/denied-keys.tmpl +++ b/web/templates/admin/denied-keys.tmpl @@ -22,21 +22,32 @@ {{ .csrfField }}
@@ -98,4 +109,4 @@ {{end}} {{end}} -{{end}} \ No newline at end of file +{{end}} diff --git a/web/templates/admin/invite-list.tmpl b/web/templates/admin/invite-list.tmpl index 928389a..7f60984 100644 --- a/web/templates/admin/invite-list.tmpl +++ b/web/templates/admin/invite-list.tmpl @@ -28,8 +28,15 @@ > {{ .csrfField }} @@ -44,6 +51,8 @@ {{range .Entries}} + {{ $user := is_logged_in }} + {{$hasCreatedInvite := eq $user.PubKey.Ref .CreatedBy.PubKey.Ref }} {{$creator := .CreatedBy.PubKey.Ref}} {{$creatorIsAlias := false}} {{range $index, $alias := .CreatedBy.Aliases}} @@ -67,10 +76,12 @@ {{end}} + {{ if or member_is_elevated $hasCreatedInvite }} {{i18n "AdminInviteRevoke"}} + {{ end }} @@ -84,10 +95,12 @@ >{{$creator}}, {{human_time .CreatedAt}} {{end}} - {{i18n "AdminInviteRevoke"}} + {{ if or member_is_elevated $hasCreatedInvite }} + {{i18n "AdminInviteRevoke"}} + {{ end }} {{end}} @@ -134,4 +147,4 @@ {{end}} {{end}} -{{end}} \ No newline at end of file +{{end}} diff --git a/web/templates/admin/member-list.tmpl b/web/templates/admin/member-list.tmpl index 44e7465..9fa5415 100644 --- a/web/templates/admin/member-list.tmpl +++ b/web/templates/admin/member-list.tmpl @@ -14,16 +14,23 @@ method="POST" > {{ .csrfField }} - +
+ class="w-8/12 self-stretch shadow rounded border border-transparent h-10 p-1 pl-4 font-mono truncate + text-purple-600 focus:outline-none focus:ring-2 focus:ring-purple-400 focus:border-transparent + {{ if member_is_elevated }} {{ else }} shadow ring-1 ring-gray-300 opacity-50 bg-gray-200 cursor-not-allowed {{ end }} + ">
@@ -106,4 +113,4 @@ {{end}} {{end}} -{{end}} \ No newline at end of file +{{end}} diff --git a/web/templates/admin/member.tmpl b/web/templates/admin/member.tmpl index b89301e..d3d923e 100644 --- a/web/templates/admin/member.tmpl +++ b/web/templates/admin/member.tmpl @@ -8,45 +8,55 @@

{{.Member.PubKey.Ref}}

-
- + {{ $user := is_logged_in }} + {{ $aliasBelongsToUser := eq $user.PubKey.Ref .Member.PubKey.Ref }} + {{ if member_is_elevated }} +
+ + {{range $.AllRoles}} + {{if eq . $.Member.Role}} + {{i18n .String}} + {{end}} + {{end}} + + +
+ {{range $.AllRoles}} + {{if ne . $.Member.Role}} +
+ {{$.csrfField}} + + +
+ {{else}} +
+
+ + + +
+ {{i18n .String}} +
+ {{end}} + {{end}} +
+
+ {{ else }} {{range $.AllRoles}} {{if eq . $.Member.Role}} - {{i18n .String}} - {{end}} +

{{i18n .String}}

+ {{end}} {{end}} -
- -
- {{range $.AllRoles}} - {{if ne . $.Member.Role}} -
- {{$.csrfField}} - - -
- {{else}} -
-
- - - -
- {{i18n .String}} -
- {{end}} - {{end}} -
-
+ {{ end }} {{$aliasCount := len .Member.Aliases}} {{if gt $aliasCount 0}} @@ -59,19 +69,23 @@ >{{.Name}} - ({{i18n "AdminMemberDetailsAliasRevoke"}}) + {{end}} {{end}} {{end}} + {{ if member_is_elevated }} {{i18n "AdminMemberDetailsRemove"}} + {{ end }} -{{end}} \ No newline at end of file +{{end}} diff --git a/web/templates/admin/settings.tmpl b/web/templates/admin/settings.tmpl index 3fb1171..388acb8 100644 --- a/web/templates/admin/settings.tmpl +++ b/web/templates/admin/settings.tmpl @@ -11,6 +11,7 @@ {{ i18n "RoomsSpecification" }}.

{{ i18n "SetPrivacyModeTitle" }}

+ {{ if member_is_admin }}
{{ i18n .CurrentMode.String }} @@ -44,6 +45,11 @@ {{end}}
+ {{ else }} + + {{ end }}
{{ i18n "ModeOpen" }}
{{ i18n "ExplanationOpen" }}
@@ -59,6 +65,7 @@ {{ i18n "ExplanationDefaultLanguage" }}

{{ i18n "SetDefaultLanguageTitle" }}

+ {{ if member_is_admin }}
{{ $.CurrentLanguage }} @@ -68,6 +75,11 @@ {{ list_languages $adminSetLanguageUrl "pl-10 pr-3 py-2 w-full text-left bg-white text-gray-700 hover:text-gray-900 hover:bg-gray-50 cursor-pointer" }}
+ {{ else }} + + {{ end }} diff --git a/web/templates/landing/index.tmpl b/web/templates/landing/index.tmpl index 40a67df..2896cae 100644 --- a/web/templates/landing/index.tmpl +++ b/web/templates/landing/index.tmpl @@ -9,11 +9,11 @@
- {{if is_logged_in}} + {{if and is_logged_in member_is_elevated }} {{i18n "NoticeEditTitle"}} {{end}} -{{end}} \ No newline at end of file +{{end}} diff --git a/web/templates/notice/list.tmpl b/web/templates/notice/list.tmpl index c73a1b8..55747f4 100644 --- a/web/templates/notice/list.tmpl +++ b/web/templates/notice/list.tmpl @@ -20,7 +20,7 @@ >{{.Language}} {{end}} - {{if is_logged_in}} + {{if and is_logged_in member_is_elevated }} {{end}} -{{end}} \ No newline at end of file +{{end}} diff --git a/web/templates/notice/show.tmpl b/web/templates/notice/show.tmpl index f512a66..09687e7 100644 --- a/web/templates/notice/show.tmpl +++ b/web/templates/notice/show.tmpl @@ -12,11 +12,11 @@
- {{if is_logged_in}} + {{if and is_logged_in member_is_elevated }}
{{i18n "NoticeEditTitle"}} {{end}} -{{end}} \ No newline at end of file +{{end}}