Gestion des rôles

This commit is contained in:
William Bouzourène 2025-01-02 15:29:55 +01:00
parent 9efdf085f3
commit 9da9cd4f61
6 changed files with 725 additions and 8 deletions

210
controllers/roles.go Normal file
View file

@ -0,0 +1,210 @@
package controllers
import (
"errors"
"fmt"
"git.readonly.ch/bouzoure/popvaud-people/helpers"
"git.readonly.ch/bouzoure/popvaud-people/models"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
)
func Roles(c *fiber.Ctx) error {
db, err := helpers.GetDatabase()
if err != nil {
return err
}
var roles []models.Role
result := db.Order("name collate nocase asc").Find(&roles)
if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) {
return err
}
return c.Render("roles", fiber.Map{
"PageTitle": "Rôles",
"Roles": roles,
})
}
func RoleShow(c *fiber.Ctx) error {
id := c.Params("id")
db, err := helpers.GetDatabase()
if err != nil {
return err
}
var role models.Role
result := db.Find(&role, "id = ?", id)
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Not found")
}
if result.Error != nil {
return err
}
title := fmt.Sprintf(
"%s | Rôles",
role.Name,
)
return c.Render("role", fiber.Map{
"PageTitle": title,
"Role": role,
})
}
func RoleAdd(c *fiber.Ctx) error {
var role models.Role
var errors []string
db, err := helpers.GetDatabase()
if err != nil {
return err
}
if c.Method() == "POST" {
// Role name
role.Name = c.FormValue("name")
if len(role.Name) > 100 || len(role.Name) < 1 {
errors = append(errors, "Le nom doit contentir entre 1 et 100 caractères")
}
// Member permissions
role.ShowMember = (c.FormValue("show_member") == "on")
role.CreateMember = (c.FormValue("create_member") == "on")
role.EditMember = (c.FormValue("edit_member") == "on")
role.ShowArchivedMember = (c.FormValue("show_archived_member") == "on")
role.ArchiveMember = (c.FormValue("archive_member") == "on")
role.RestoreMember = (c.FormValue("restore_member") == "on")
role.PurgeMember = (c.FormValue("purge_member") == "on")
role.ConvertMemberToContact = (c.FormValue("convert_member_to_contact") == "on")
role.ExportMember = (c.FormValue("export_member") == "on")
// Contact permissions
role.ShowContact = (c.FormValue("show_contact") == "on")
role.CreateContact = (c.FormValue("create_contact") == "on")
role.EditContact = (c.FormValue("edit_contact") == "on")
role.ShowArchivedContact = (c.FormValue("show_archived_contact") == "on")
role.ArchiveContact = (c.FormValue("archive_contact") == "on")
role.RestoreContact = (c.FormValue("restore_contact") == "on")
role.PurgeContact = (c.FormValue("purge_contact") == "on")
role.ConvertContactToMember = (c.FormValue("convert_contact_to_member") == "on")
role.ExportContact = (c.FormValue("export_contact") == "on")
if len(errors) == 0 {
result := db.Create(&role)
if result.Error != nil {
return result.Error
} else {
c.Redirect(fmt.Sprintf(
"/admin/roles/%d",
role.ID,
))
}
}
}
return c.Render("role_form", fiber.Map{
"PageTitle": "Ajouter un rôle",
"role": role,
"Errors": errors,
})
}
func RoleEdit(c *fiber.Ctx) error {
id := c.Params("id")
db, err := helpers.GetDatabase()
if err != nil {
return err
}
var role models.Role
result := db.Find(&role, "id = ?", id)
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "Not found")
}
if result.Error != nil {
return err
}
title := fmt.Sprintf(
"%s | Modifier rôle",
role.Name,
)
var errors []string
if c.Method() == "POST" {
// Role name
role.Name = c.FormValue("name")
if len(role.Name) > 100 || len(role.Name) < 1 {
errors = append(errors, "Le nom doit contentir entre 1 et 100 caractères")
}
// Member permissions
role.ShowMember = (c.FormValue("show_member") == "on")
role.CreateMember = (c.FormValue("create_member") == "on")
role.EditMember = (c.FormValue("edit_member") == "on")
role.ShowArchivedMember = (c.FormValue("show_archived_member") == "on")
role.ArchiveMember = (c.FormValue("archive_member") == "on")
role.RestoreMember = (c.FormValue("restore_member") == "on")
role.PurgeMember = (c.FormValue("purge_member") == "on")
role.ConvertMemberToContact = (c.FormValue("convert_member_to_contact") == "on")
role.ExportMember = (c.FormValue("export_member") == "on")
// Contact permissions
role.ShowContact = (c.FormValue("show_contact") == "on")
role.CreateContact = (c.FormValue("create_contact") == "on")
role.EditContact = (c.FormValue("edit_contact") == "on")
role.ShowArchivedContact = (c.FormValue("show_archived_contact") == "on")
role.ArchiveContact = (c.FormValue("archive_contact") == "on")
role.RestoreContact = (c.FormValue("restore_contact") == "on")
role.PurgeContact = (c.FormValue("purge_contact") == "on")
role.ConvertContactToMember = (c.FormValue("convert_contact_to_member") == "on")
role.ExportContact = (c.FormValue("export_contact") == "on")
if len(errors) == 0 {
result := db.Save(&role)
if result.Error != nil {
return result.Error
} else {
c.Redirect(fmt.Sprintf(
"/admin/roles/%d",
role.ID,
))
}
}
}
return c.Render("role_form", fiber.Map{
"PageTitle": title,
"Role": role,
"Errors": errors,
})
}
func RoleDelete(c *fiber.Ctx) error {
id := c.Params("id")
db, err := helpers.GetDatabase()
if err != nil {
return err
}
result := db.Delete(&models.Role{}, id)
if result.Error != nil {
return err
}
return c.Redirect("/admin/roles")
}

View file

@ -135,6 +135,15 @@ func main() {
app.Post("/admin/lists/:id<int;min(0)>/items/:itemid<int;min(0)>", controllers.ListItemEdit)
app.Post("/admin/lists/:id<int;min(0)>/items/:itemid<int;min(0)>/delete", controllers.ListItemDelete)
// Admin: Roles
app.Get("/admin/roles", controllers.Roles)
app.Get("/admin/roles/:id<int;min(0)>", controllers.RoleShow)
app.Get("/admin/roles/add", controllers.RoleAdd)
app.Post("/admin/roles/add", controllers.RoleAdd)
app.Get("/admin/roles/:id<int;min(0)>/edit", controllers.RoleEdit)
app.Post("/admin/roles/:id<int;min(0)>/edit", controllers.RoleEdit)
app.Post("/admin/roles/:id<int;min(0)>/delete", controllers.RoleDelete)
listenAddr := fmt.Sprintf(
"%s:%d",
config.App.ListenAddress,

View file

@ -4,12 +4,23 @@ import "gorm.io/gorm"
type Role struct {
gorm.Model
Name string
ShowPerson bool
CreatePerson bool
EditPerson bool
ShowArchivedPerson bool
ArchivePerson bool
RestorePerson bool
ExportData bool
Name string
ShowMember bool
CreateMember bool
EditMember bool
ShowArchivedMember bool
ArchiveMember bool
RestoreMember bool
PurgeMember bool
ConvertMemberToContact bool
ExportMember bool
ShowContact bool
CreateContact bool
EditContact bool
ShowArchivedContact bool
ArchiveContact bool
RestoreContact bool
PurgeContact bool
ConvertContactToMember bool
ExportContact bool
}

136
views/role.html Normal file
View file

@ -0,0 +1,136 @@
{% extends "layouts/main.html" %}
{% block main %}
<div class="container mt-4">
<div class="mb-4">
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/admin">Administration</a></li>
<li class="breadcrumb-item"><a href="/admin/roles">Rôles</a></li>
<li class="breadcrumb-item active">{{ Role.Name }}</li>
</ol>
</nav>
<hr>
</div>
<div class="mb-3">
<b>Nom</b><br>
{{ Role.Name }}
</div>
<div class="mb-4">
<div class="mb-3">
<b>Permissions - Membres</b>
</div>
<div style="max-width: 400px;">
<table class="table table-bordered">
<tbody>
<tr>
<td>Afficher membres</td>
<td>{% if Role.ShowMember %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Créer membres</td>
<td>{% if Role.CreateMember %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Modifier membres</td>
<td>{% if Role.EditMember %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Afficher membres archivés</td>
<td>{% if Role.ShowArchivedMember %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Archiver membres</td>
<td>{% if Role.ArchiveMember %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Restaurer membres</td>
<td>{% if Role.RestoreMember %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Purger membres (suppression définitive)</td>
<td>{% if Role.PurgeMember %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Convertir membres en contacts</td>
<td>{% if Role.ConvertMemberToContact %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Exporter membres (CSV)</td>
<td>{% if Role.ExportMember %}Oui{% else %}Non{% endif %}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="mb-4">
<div class="mb-3">
<b>Permissions - Contacts</b>
</div>
<div style="max-width: 400px;">
<table class="table table-bordered">
<tbody>
<tr>
<td>Afficher contacts</td>
<td>{% if Role.ShowContact %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Créer contacts</td>
<td>{% if Role.CreateContact %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Modifier contacts</td>
<td>{% if Role.EditContact %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Afficher contacts archivés</td>
<td>{% if Role.ShowArchivedContact %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Archiver contacts</td>
<td>{% if Role.ArchiveContact %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Restaurer contacts</td>
<td>{% if Role.RestoreContact %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Purger contacts (suppression définitive)</td>
<td>{% if Role.PurgeContact %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Convertir contacts en membres</td>
<td>{% if Role.ConvertContactToMember %}Oui{% else %}Non{% endif %}</td>
</tr>
<tr>
<td>Exporter contacts (CSV)</td>
<td>{% if Role.ExportContact %}Oui{% else %}Non{% endif %}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="mt-3">
<a class="btn btn-md btn-primary" href="/admin/roles/{{ Role.ID }}/edit">
<i class="feather" data-feather="edit-2"></i>
Modifier
</a>
<form
action="/admin/roles/{{ Role.ID }}/delete"
method="post"
class="d-inline p-0"
>
<button class="btn btn-md btn-danger areyousure" type="submit">
<i class="feather" data-feather="trash-2"></i>
Supprimer
</button>
</form>
</div>
</div>
{% endblock %}

300
views/role_form.html Normal file
View file

@ -0,0 +1,300 @@
{% extends "layouts/main.html" %}
{% block main %}
<div class="container mt-4">
<div class="mb-4">
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/admin">Administration</a></li>
<li class="breadcrumb-item"><a href="/admin/roles">Rôles</a></li>
{% if Role.ID %}
<li class="breadcrumb-item"><a href="/admin/roles/{{ Role.ID }}">{{ Role.Name }}</a></li>
<li class="breadcrumb-item active">Modifier</li>
{% else %}
<li class="breadcrumb-item active">Ajouter</li>
{% endif %}
</ol>
</nav>
<hr>
</div>
{% if Errors %}
<div class="alert alert-danger">
<ul class="m-0">
{% for Error in Errors %}
<li>{{ Error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<form id="role" method="post">
<div class="mb-3">
<label for="name" class="form-label">
Nom
</label>
<input
id="name"
class="form-control"
type="text"
name="name"
required
value="{{ Role.Name }}"
>
</div>
<div class="mb-3 mt-4">
<b>Permissions - Membres</b>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="show_member"
name="show_member"
{% if Role.ShowMember %}checked{% endif %}
>
<label for="show_member" class="form-label">
Afficher membres
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="create_member"
name="create_member"
{% if Role.CreateMember %}checked{% endif %}
>
<label for="create_member" class="form-label">
Créer membres
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="edit_member"
name="edit_member"
{% if Role.EditMember %}checked{% endif %}
>
<label for="edit_member" class="form-label">
Modifier membres
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="show_archived_member"
name="show_archived_member"
{% if Role.ShowArchivedMember %}checked{% endif %}
>
<label for="show_archived_member" class="form-label">
Afficher membres archivés
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="archive_member"
name="archive_member"
{% if Role.ArchiveMember %}checked{% endif %}
>
<label for="archive_member" class="form-label">
Archiver membres
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="restore_member"
name="restore_member"
{% if Role.RestoreMember %}checked{% endif %}
>
<label for="restore_member" class="form-label">
Restaurer membres
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="purge_member"
name="purge_member"
{% if Role.PurgeMember %}checked{% endif %}
>
<label for="purge_member" class="form-label">
Purger membres (suppression définitive)
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="convert_member_to_contact"
name="convert_member_to_contact"
{% if Role.ConvertMemberToContact %}checked{% endif %}
>
<label for="convert_member_to_contact" class="form-label">
Convertir membres en contacts
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="export_member"
name="export_member"
{% if Role.ExportMember %}checked{% endif %}
>
<label for="export_member" class="form-label">
Exporter membres (CSV)
</label>
</div>
<div class="mb-3 mt-4">
<b>Permissions - Contacts</b>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="show_contact"
name="show_contact"
{% if Role.ShowContact %}checked{% endif %}
>
<label for="show_contact" class="form-label">
Afficher contacts
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="create_contact"
name="create_contact"
{% if Role.CreateContact %}checked{% endif %}
>
<label for="create_contact" class="form-label">
Créer contacts
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="edit_contact"
name="edit_contact"
{% if Role.EditContact %}checked{% endif %}
>
<label for="edit_contact" class="form-label">
Modifier contacts
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="show_archived_contact"
name="show_archived_contact"
{% if Role.ShowArchivedContact %}checked{% endif %}
>
<label for="show_archived_contact" class="form-label">
Afficher contacts archivés
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="archive_contact"
name="archive_contact"
{% if Role.ArchiveContact %}checked{% endif %}
>
<label for="archive_contact" class="form-label">
Archiver contacts
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="restore_contact"
name="restore_contact"
{% if Role.RestoreContact %}checked{% endif %}
>
<label for="restore_contact" class="form-label">
Restaurer contacts
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="purge_contact"
name="purge_contact"
{% if Role.PurgeContact %}checked{% endif %}
>
<label for="purge_contact" class="form-label">
Purger contacts (suppression définitive)
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="convert_contact_to_member"
name="convert_contact_to_member"
{% if Role.ConvertContactToMember %}checked{% endif %}
>
<label for="convert_contact_to_member" class="form-label">
Convertir contacts en membres
</label>
</div>
<div class="mb-3">
<input
type="checkbox"
class="form-check-input me-2"
id="export_contact"
name="export_contact"
{% if Role.ExportContact %}checked{% endif %}
>
<label for="export_contact" class="form-label">
Exporter contacts (CSV)
</label>
</div>
<div class="mt-3">
<button class="btn btn-primary" type="submit">
<i class="me-1" data-feather="save"></i>
Enregistrer
</button>
</div>
</form>
</div>
{% endblock %}

51
views/roles.html Normal file
View file

@ -0,0 +1,51 @@
{% extends "layouts/main.html" %}
{% block main %}
<div class="container mt-4">
<div class="mb-4">
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/admin">Administration</a></li>
<li class="breadcrumb-item active">Rôles</li>
</ol>
</nav>
<hr>
</div>
{% if Roles %}
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Nom</th>
</tr>
</thead>
<tbody>
{% for Role in Roles %}
<tr>
<td>
<a href="/admin/roles/{{ Role.ID }}">
{{ Role.Name }}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="my-4">
Pas de rôle pour le moment
</div>
{% endif %}
<div class="mt-3">
<a class="btn btn-md btn-primary" href="/admin/roles/add">
<i class="feather" data-feather="plus"></i>
Ajouter
</a>
</div>
</div>
{% endblock %}