diff --git a/internal/httpd/server.go b/internal/httpd/server.go index 50156bbd..3f317ea7 100644 --- a/internal/httpd/server.go +++ b/internal/httpd/server.go @@ -1787,6 +1787,8 @@ func (s *httpdServer) setupWebAdminRoutes() { Post(webAdminEventRulePath+"/run/{name}", runOnDemandRule) router.With(s.checkPerm(dataprovider.PermAdminManageRoles), s.refreshCookie). Get(webAdminRolesPath, s.handleWebGetRoles) + router.With(s.checkPerm(dataprovider.PermAdminManageRoles), compressor.Handler, s.refreshCookie). + Get(webAdminRolesPath+jsonAPISuffix, getAllRoles) router.With(s.checkPerm(dataprovider.PermAdminManageRoles), s.refreshCookie). Get(webAdminRolePath, s.handleWebAddRoleGet) router.With(s.checkPerm(dataprovider.PermAdminManageRoles)).Post(webAdminRolePath, s.handleWebAddRolePost) diff --git a/internal/httpd/webadmin.go b/internal/httpd/webadmin.go index e976ef7f..0a4bfb52 100644 --- a/internal/httpd/webadmin.go +++ b/internal/httpd/webadmin.go @@ -102,8 +102,6 @@ const ( pageStatusTitle = "Status" pageEventRulesTitle = "Event rules" pageEventActionsTitle = "Event actions" - pageRolesTitle = "Roles" - pageChangePwdTitle = "Change password" pageMaintenanceTitle = "Maintenance" pageDefenderTitle = "Auto Blocklist" pageIPListsTitle = "IP Lists" @@ -169,11 +167,6 @@ type adminsPage struct { Admins []dataprovider.Admin } -type rolesPage struct { - basePage - Roles []dataprovider.Role -} - type eventRulesPage struct { basePage Rules []dataprovider.EventRule @@ -518,7 +511,7 @@ func loadAdminTemplates(templatesPath string) { filepath.Join(templatesPath, templateCommonDir, templateResetPassword), } rolesPaths := []string{ - filepath.Join(templatesPath, templateCommonDir, templateCommonCSS), + filepath.Join(templatesPath, templateCommonDir, templateCommonBase), filepath.Join(templatesPath, templateAdminDir, templateBase), filepath.Join(templatesPath, templateAdminDir, templateRoles), } @@ -839,7 +832,7 @@ func (s *httpdServer) renderProfilePage(w http.ResponseWriter, r *http.Request, func (s *httpdServer) renderChangePasswordPage(w http.ResponseWriter, r *http.Request, err *util.I18nError) { data := changePasswordPage{ - basePage: s.getBasePageData(pageChangePwdTitle, webChangeAdminPwdPath, r), + basePage: s.getBasePageData(util.I18nChangePwdTitle, webChangeAdminPwdPath, r), Error: err, } @@ -3856,7 +3849,7 @@ func (s *httpdServer) handleWebUpdateEventRulePost(w http.ResponseWriter, r *htt } func (s *httpdServer) getWebRoles(w http.ResponseWriter, r *http.Request, limit int, minimal bool) ([]dataprovider.Role, error) { - roles := make([]dataprovider.Role, 0, limit) + roles := make([]dataprovider.Role, 0, 10) for { res, err := dataprovider.GetRoles(limit, len(roles), dataprovider.OrderASC, minimal) if err != nil { @@ -3871,16 +3864,27 @@ func (s *httpdServer) getWebRoles(w http.ResponseWriter, r *http.Request, limit return roles, nil } +func getAllRoles(w http.ResponseWriter, r *http.Request) { + r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize) + roles := make([]dataprovider.Role, 0, 10) + for { + res, err := dataprovider.GetRoles(defaultQueryLimit, len(roles), dataprovider.OrderASC, false) + if err != nil { + sendAPIResponse(w, r, err, getI18NErrorString(err, util.I18nError500Message), http.StatusInternalServerError) + return + } + roles = append(roles, res...) + if len(res) < defaultQueryLimit { + break + } + } + render.JSON(w, r, roles) +} + func (s *httpdServer) handleWebGetRoles(w http.ResponseWriter, r *http.Request) { r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize) - roles, err := s.getWebRoles(w, r, 10, false) - if err != nil { - return - } - data := rolesPage{ - basePage: s.getBasePageData(pageRolesTitle, webAdminRolesPath, r), - Roles: roles, - } + data := s.getBasePageData(util.I18nRolesTitle, webAdminRolesPath, r) + renderAdminTemplate(w, templateRoles, data) } diff --git a/internal/util/i18n.go b/internal/util/i18n.go index 747a0e64..1e1cc9a0 100644 --- a/internal/util/i18n.go +++ b/internal/util/i18n.go @@ -59,6 +59,7 @@ const ( I18nOAuth2Title = "title.oauth2_success" I18nOAuth2ErrorTitle = "title.oauth2_error" I18nSessionsTitle = "title.connections" + I18nRolesTitle = "title.roles" I18nErrorSetupInstallCode = "setup.install_code_mismatch" I18nInvalidAuth = "general.invalid_auth_request" I18nError429Message = "general.error429" diff --git a/static/locales/en/translation.json b/static/locales/en/translation.json index 6de42e43..f322fbb5 100644 --- a/static/locales/en/translation.json +++ b/static/locales/en/translation.json @@ -221,7 +221,9 @@ "backup_ok": "Backup successfully restored", "configs_saved": "Configurations has been successfully updated", "protocol": "Protocol", - "refresh": "Refresh" + "refresh": "Refresh", + "members": "Members", + "members_summary": "Users: {{users}}. Admins: {{admins}}" }, "fs": { "view_file": "View file \"{{- path}}\"", @@ -493,9 +495,7 @@ "template_no_user": "No valid user defined, unable to complete the requested action" }, "group": { - "view_manage": "View and manage groups", - "members": "Members", - "members_summary": "Users: {{users}}. Admins: {{admins}}" + "view_manage": "View and manage groups" }, "virtual_folders": { "view_manage": "View and manage virtual folders", @@ -686,5 +686,8 @@ "upload_info": "$t(connections.upload). Size: {{- size}}. Speed: {{- speed}}", "download_info": "$t(connections.download). Size: {{- size}}. Speed: {{- speed}}", "client": "Client: {{- val}}" + }, + "role": { + "view_manage": "View and manage roles" } } \ No newline at end of file diff --git a/static/locales/it/translation.json b/static/locales/it/translation.json index aa8c3f6f..23b0abbd 100644 --- a/static/locales/it/translation.json +++ b/static/locales/it/translation.json @@ -221,7 +221,9 @@ "backup_ok": "Backup ripristinato correttamente", "configs_saved": "Configurazioni aggiornate", "protocol": "Protocollo", - "refresh": "Aggiorna" + "refresh": "Aggiorna", + "members": "Membri", + "members_summary": "Utenti: {{users}}. Amministratori: {{admins}}" }, "fs": { "view_file": "Visualizza file \"{{- path}}\"", @@ -493,9 +495,7 @@ "template_no_user": "Nessun utente valido definito. Impossibile completare l'azione richiesta" }, "group": { - "view_manage": "Visualizza e gestisci gruppi", - "members": "Membri", - "members_summary": "Utenti: {{users}}. Amministratori: {{admins}}" + "view_manage": "Visualizza e gestisci gruppi" }, "virtual_folders": { "view_manage": "Visualizza e gestisci cartelle virtuali", @@ -686,5 +686,8 @@ "upload_info": "$t(connections.upload). Dimensione: {{- size}}. Velocità: {{- speed}}", "download_info": "$t(connections.download). Dimensione: {{- size}}. Velocità: {{- speed}}", "client": "Client: {{- val}}" + }, + "role": { + "view_manage": "Visualizza e gestisci ruoli" } } \ No newline at end of file diff --git a/templates/webadmin/base.html b/templates/webadmin/base.html index 649f259f..f6ec3274 100644 --- a/templates/webadmin/base.html +++ b/templates/webadmin/base.html @@ -191,30 +191,6 @@ explicit grant from the SFTPGo Team (support@sftpgo.com). {{- end}} -{{- if .LoggedUser.HasPermission "manage_admins"}} -
-{{- end}} -{{- if .LoggedUser.HasPermission "manage_roles"}} - -{{- end}} {{- if or (.LoggedUser.HasPermission "manage_system") (.LoggedUser.HasPermission "view_status") (and .HasSearcher (.LoggedUser.HasPermission "view_events"))}} {{- end}} +{{- if .LoggedUser.HasPermission "manage_admins"}} + +{{- end}} +{{- if .LoggedUser.HasPermission "manage_roles"}} + +{{- end}} {{- end}} \ No newline at end of file diff --git a/templates/webadmin/folders.html b/templates/webadmin/folders.html index 75678d7e..b5e597d8 100644 --- a/templates/webadmin/folders.html +++ b/templates/webadmin/folders.html @@ -286,19 +286,19 @@ explicit grant from the SFTPGo Team (support@sftpgo.com). //{{- if .LoggedUser.HasPermission "manage_folders"}} numActions++; actions+=`` //{{- end}} //{{- if .LoggedUser.HasPermission "manage_system"}} numActions++; actions+=`` //{{- end}} //{{- if .LoggedUser.HasPermission "manage_folders"}} numActions++; actions+=`` //{{- end}} if (numActions > 0){ @@ -377,7 +377,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com). } function handleRowActions() { - const editButtons = document.querySelectorAll('[data-share-table-action="edit_row"]'); + const editButtons = document.querySelectorAll('[data-table-action="edit_row"]'); editButtons.forEach(d => { let el = $(d); el.off("click"); @@ -388,7 +388,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com). }); }); - const templateButtons = document.querySelectorAll('[data-share-table-action="template_row"]'); + const templateButtons = document.querySelectorAll('[data-table-action="template_row"]'); templateButtons.forEach(d => { let el = $(d); el.off("click"); @@ -399,7 +399,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com). }); }); - const deleteButtons = document.querySelectorAll('[data-share-table-action="delete_row"]'); + const deleteButtons = document.querySelectorAll('[data-table-action="delete_row"]'); deleteButtons.forEach(d => { let el = $(d); el.off("click"); diff --git a/templates/webadmin/groups.html b/templates/webadmin/groups.html index e39dc5d5..fa88196f 100644 --- a/templates/webadmin/groups.html +++ b/templates/webadmin/groups.html @@ -47,7 +47,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).