Implement permissions in members controllers

This commit is contained in:
William Bouzourène 2025-01-17 15:59:35 +01:00
parent 625d777a8b
commit 8c94b2567e
2 changed files with 272 additions and 59 deletions

View file

@ -27,6 +27,32 @@ type PersonValidation struct {
} }
func Members(c *fiber.Ctx) error { func Members(c *fiber.Ctx) error {
userid, err := helpers.GetSessionUserId(c)
if err != nil {
return err
}
allowedSections, err := helpers.PermissionsGetSections(
userid, "show_member",
)
if err != nil {
return err
}
allowedSectionsArchived, err := helpers.PermissionsGetSections(
userid, "show_archived_member",
)
if err != nil {
return err
}
permShow := (len(allowedSections) > 0)
permShowArchived := (len(allowedSectionsArchived) > 0)
if !permShow && !permShowArchived {
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
}
db, err := helpers.GetDatabase() db, err := helpers.GetDatabase()
if err != nil { if err != nil {
return err return err
@ -36,7 +62,7 @@ func Members(c *fiber.Ctx) error {
result := db.Order( result := db.Order(
"last_name collate nocase asc, first_name collate nocase asc", "last_name collate nocase asc, first_name collate nocase asc",
).Preload("Section").Find( ).Preload("Section").Find(
&people, "is_member = ?", true, &people, "is_member = ? AND section_id IN ?", true, allowedSections,
) )
if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) { if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) {
@ -47,6 +73,8 @@ func Members(c *fiber.Ctx) error {
"PageTitle": "Membres", "PageTitle": "Membres",
"MembersPage": true, "MembersPage": true,
"People": people, "People": people,
"PermShow": permShow,
"PermShowArchived": permShowArchived,
}) })
} }
@ -63,12 +91,33 @@ func MemberShow(c *fiber.Ctx) error {
&person, "id = ? AND is_member", id, true, &person, "id = ? AND is_member", id, true,
) )
if result.Error != nil {
return result.Error
}
if result.RowsAffected < 1 { if result.RowsAffected < 1 {
return fiber.NewError(fiber.StatusNotFound, "Not found") return fiber.NewError(fiber.StatusNotFound, "Not found")
} }
if result.Error != nil { userid, err := helpers.GetSessionUserId(c)
return result.Error if err != nil {
return err
}
persmissionName := "show_member"
if person.DeletedAt.Valid {
persmissionName = "show_archived_member"
}
allow, err := helpers.PermissionsCheckSection(
userid, persmissionName, person.SectionID,
)
if err != nil {
return err
}
if !allow {
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
} }
title := fmt.Sprintf( title := fmt.Sprintf(
@ -91,17 +140,41 @@ func MemberShow(c *fiber.Ctx) error {
person.ID, person.ID,
) )
permEdit, _ := helpers.PermissionsGetSections(userid, "edit_member")
permConvert, _ := helpers.PermissionsGetSections(userid, "convert_member_to_contact")
permArchive, _ := helpers.PermissionsGetSections(userid, "archive_member")
permRestore, _ := helpers.PermissionsGetSections(userid, "restore_member")
permPurge, _ := helpers.PermissionsGetSections(userid, "purge_member")
return c.Render("person", fiber.Map{ return c.Render("person", fiber.Map{
"PageTitle": title, "PageTitle": title,
"Person": person, "Person": person,
"Fields": fields, "Fields": fields,
"FieldValues": fieldValues, "FieldValues": fieldValues,
"PermEdit": permEdit,
"PermConvert": permConvert,
"PermArchive": permArchive,
"PermRestore": permRestore,
"PermPurge": permPurge,
}) })
} }
func MemberAdd(c *fiber.Ctx) error { func MemberAdd(c *fiber.Ctx) error {
var person models.Person userid, err := helpers.GetSessionUserId(c)
var errors []string if err != nil {
return err
}
allowedSections, err := helpers.PermissionsGetSections(
userid, "create_member",
)
if err != nil {
return err
}
if len(allowedSections) < 1 {
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
}
db, err := helpers.GetDatabase() db, err := helpers.GetDatabase()
if err != nil { if err != nil {
@ -122,6 +195,8 @@ func MemberAdd(c *fiber.Ctx) error {
&fields, "person_type = ?", "member", &fields, "person_type = ?", "member",
) )
var person models.Person
var errors []string
if c.Method() == "POST" { if c.Method() == "POST" {
data := PersonValidation{ data := PersonValidation{
LastName: c.FormValue("last_name"), LastName: c.FormValue("last_name"),
@ -320,12 +395,28 @@ func MemberEdit(c *fiber.Ctx) error {
var person models.Person var person models.Person
result := db.Find(&person, "id = ?", id) result := db.Find(&person, "id = ?", id)
if errors.Is(result.Error, gorm.ErrRecordNotFound) { if result.Error != nil {
return result.Error
}
if result.RowsAffected < 1 {
return fiber.NewError(fiber.StatusNotFound, "Not found") return fiber.NewError(fiber.StatusNotFound, "Not found")
} }
if result.Error != nil { userid, err := helpers.GetSessionUserId(c)
return result.Error if err != nil {
return err
}
allow, err := helpers.PermissionsCheckSection(
userid, "edit_member", person.SectionID,
)
if err != nil {
return err
}
if !allow {
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
} }
title := fmt.Sprintf( title := fmt.Sprintf(
@ -562,12 +653,28 @@ func MemberConvert(c *fiber.Ctx) error {
var person models.Person var person models.Person
result := db.Find(&person, "id = ?", id) result := db.Find(&person, "id = ?", id)
if errors.Is(result.Error, gorm.ErrRecordNotFound) { if result.Error != nil {
return result.Error
}
if result.RowsAffected < 1 {
return fiber.NewError(fiber.StatusNotFound, "Not found") return fiber.NewError(fiber.StatusNotFound, "Not found")
} }
if result.Error != nil { userid, err := helpers.GetSessionUserId(c)
return result.Error if err != nil {
return err
}
allow, err := helpers.PermissionsCheckSection(
userid, "convert_member_to_contact", person.SectionID,
)
if err != nil {
return err
}
if !allow {
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
} }
person.IsContact = true person.IsContact = true
@ -592,7 +699,34 @@ func MemberArchive(c *fiber.Ctx) error {
return err return err
} }
result := db.Delete(&models.Person{}, id) var person models.Person
result := db.Find(&person, "id = ?", id)
if result.Error != nil {
return result.Error
}
if result.RowsAffected < 1 {
return fiber.NewError(fiber.StatusNotFound, "Not found")
}
userid, err := helpers.GetSessionUserId(c)
if err != nil {
return err
}
allow, err := helpers.PermissionsCheckSection(
userid, "archive_member", person.SectionID,
)
if err != nil {
return err
}
if !allow {
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
}
result = db.Delete(&person)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
} }
@ -611,9 +745,37 @@ func MemberRestore(c *fiber.Ctx) error {
return err return err
} }
result := db.Unscoped().Model(&models.Person{}).Where( var person models.Person
"id = ?", id, result := db.Unscoped().Find(
).Update("DeletedAt", nil) &person, "id = ? AND deleted_at IS NOT NULL", id,
)
if result.Error != nil {
return result.Error
}
if result.RowsAffected < 1 {
return fiber.NewError(fiber.StatusNotFound, "Not found")
}
userid, err := helpers.GetSessionUserId(c)
if err != nil {
return err
}
allow, err := helpers.PermissionsCheckSection(
userid, "restore_member", person.SectionID,
)
if err != nil {
return err
}
if !allow {
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
}
person.DeletedAt.Valid = false
result = db.Save(&person)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
@ -633,7 +795,36 @@ func MemberPurge(c *fiber.Ctx) error {
return err return err
} }
result := db.Unscoped().Delete( var person models.Person
result := db.Unscoped().Find(
&person, "id = ?", id,
)
if result.Error != nil {
return result.Error
}
if result.RowsAffected < 1 {
return fiber.NewError(fiber.StatusNotFound, "Not found")
}
userid, err := helpers.GetSessionUserId(c)
if err != nil {
return err
}
allow, err := helpers.PermissionsCheckSection(
userid, "purge_member", person.SectionID,
)
if err != nil {
return err
}
if !allow {
return fiber.NewError(fiber.StatusForbidden, "Forbidden")
}
result = db.Unscoped().Delete(
&models.FieldValue{}, "person_id = ?", id, &models.FieldValue{}, "person_id = ?", id,
) )

View file

@ -260,13 +260,19 @@
<div class="my-5"> <div class="my-5">
{% if Person.IsMember %} {% if Person.IsMember %}
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
{% if !Person.DeletedAt.Valid %} {% if !Person.DeletedAt.Valid %}
{% if PermEdit %}
<a class="btn btn-md btn-primary" href="/members/{{ Person.ID }}/edit"> <a class="btn btn-md btn-primary" href="/members/{{ Person.ID }}/edit">
<i class="bi-pencil-square"></i> <i class="bi-pencil-square"></i>
Modifier Modifier
</a> </a>
{% endif %}
{% if PermConvert %}
<form <form
action="/members/{{ Person.ID }}/convert" action="/members/{{ Person.ID }}/convert"
method="post" method="post"
@ -278,9 +284,12 @@
</button> </button>
</form> </form>
{% endif %} {% endif %}
{% endif %}
</div> </div>
<div class="col-md-6 text-md-end mt-2 mt-md-0"> <div class="col-md-6 text-md-end mt-2 mt-md-0">
{% if Person.DeletedAt.Valid %} {% if Person.DeletedAt.Valid %}
{% if PermRestore %}
<form <form
action="/members/{{ Person.ID }}/restore" action="/members/{{ Person.ID }}/restore"
method="post" method="post"
@ -291,7 +300,11 @@
Restaurer Restaurer
</button> </button>
</form> </form>
{% endif %}
{% else %} {% else %}
{% if PermArchive %}
<form <form
action="/members/{{ Person.ID }}/archive" action="/members/{{ Person.ID }}/archive"
method="post" method="post"
@ -303,6 +316,10 @@
</button> </button>
</form> </form>
{% endif %} {% endif %}
{% endif %}
{% if PermPurge %}
<form <form
action="/members/{{ Person.ID }}/purge" action="/members/{{ Person.ID }}/purge"
method="post" method="post"
@ -313,9 +330,13 @@
Supprimer Supprimer
</button> </button>
</form> </form>
{% endif %}
</div> </div>
</div> </div>
{% else %} {% else %}
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
{% if !Person.DeletedAt.Valid %} {% if !Person.DeletedAt.Valid %}
@ -371,6 +392,7 @@
</form> </form>
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div> </div>