Ability to create account for members

This commit is contained in:
William Bouzourène 2026-03-18 19:17:25 +01:00
parent 07db65f63f
commit 2e332b8f3e
Signed by: bouzoure
GPG key ID: 423440D735B56BE2
5 changed files with 138 additions and 16 deletions

View file

@ -762,7 +762,7 @@ func ContactEdit(c *fiber.Ctx) error {
if len(data.Email) > 0 { if len(data.Email) > 0 {
var personEmail []models.Person var personEmail []models.Person
result := db.Find(&personEmail, "LOWER(email) = LOWER(?)", data.Email) result := db.Find(&personEmail, "LOWER(email) = LOWER(?) AND id <> ?", data.Email, person.ID)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
} }

View file

@ -8,11 +8,13 @@ import (
"time" "time"
"git.readonly.ch/bouzoure/pop-camarades/helpers" "git.readonly.ch/bouzoure/pop-camarades/helpers"
"git.readonly.ch/bouzoure/pop-camarades/helpers/authelia"
"git.readonly.ch/bouzoure/pop-camarades/helpers/database" "git.readonly.ch/bouzoure/pop-camarades/helpers/database"
"git.readonly.ch/bouzoure/pop-camarades/models" "git.readonly.ch/bouzoure/pop-camarades/models"
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/google/uuid"
) )
type PersonValidation struct { type PersonValidation struct {
@ -636,6 +638,16 @@ func MemberAdd(c *fiber.Ctx) error {
} }
} }
if c.FormValue("account-enabled") == "on" {
personAccount := models.PersonAccount{
PersonID: person.ID,
UUID: uuid.New(),
Enabled: true,
Groups: strings.Join(authelia.GetPersonGroups(person.ID), "|||"),
}
db.Create(&personAccount)
}
c.Redirect(fmt.Sprintf( c.Redirect(fmt.Sprintf(
"/members/%d", "/members/%d",
person.ID, person.ID,
@ -714,6 +726,9 @@ func MemberEdit(c *fiber.Ctx) error {
person.ID, person.ID,
) )
var personAccount models.PersonAccount
db.Find(&personAccount, "person_id = ?", person.ID)
var errors []string var errors []string
if c.Method() == "POST" { if c.Method() == "POST" {
data := PersonValidation{ data := PersonValidation{
@ -765,7 +780,7 @@ func MemberEdit(c *fiber.Ctx) error {
if len(data.Email) > 0 { if len(data.Email) > 0 {
var personEmail []models.Person var personEmail []models.Person
result := db.Find(&personEmail, "LOWER(email) = LOWER(?)", data.Email) result := db.Find(&personEmail, "LOWER(email) = LOWER(?) AND id <> ?", data.Email, person.ID)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
} }
@ -906,6 +921,33 @@ func MemberEdit(c *fiber.Ctx) error {
return result.Error return result.Error
} }
if c.FormValue("account-enabled") == "on" && personAccount.ID <= 0 {
personAccount = models.PersonAccount{
PersonID: person.ID,
UUID: uuid.New(),
Enabled: true,
Groups: strings.Join(authelia.GetPersonGroups(person.ID), "|||"),
}
db.Create(&personAccount)
} else if c.FormValue("account-enabled") == "on" && personAccount.ID > 0 {
personAccount.Enabled = true
personAccount.Groups = strings.Join(authelia.GetPersonGroups(person.ID), "|||")
if personAccount.AccountCreated {
personAccount.UpdateNeeded = true
}
db.Save(&personAccount)
} else if c.FormValue("account-enabled") != "on" && personAccount.ID > 0 {
personAccount.Enabled = false
if personAccount.AccountCreated {
personAccount.UpdateNeeded = true
}
db.Save(&personAccount)
}
c.Redirect(fmt.Sprintf( c.Redirect(fmt.Sprintf(
"/members/%d", "/members/%d",
person.ID, person.ID,
@ -919,6 +961,7 @@ func MemberEdit(c *fiber.Ctx) error {
"Sections": sections, "Sections": sections,
"Fields": fields, "Fields": fields,
"FieldValues": fieldValues, "FieldValues": fieldValues,
"PersonAccount": personAccount,
"Errors": errors, "Errors": errors,
}) })
} }

View file

@ -0,0 +1,57 @@
package authelia
import (
"fmt"
"strings"
"git.readonly.ch/bouzoure/pop-camarades/helpers"
"git.readonly.ch/bouzoure/pop-camarades/models"
)
func GetPersonGroups(userid uint) []string {
var groups []string
db, err := helpers.GetDatabase()
if err != nil {
return groups
}
var person models.Person
db.Preload("Section").Find(&person, "id = ?", userid)
if person.SectionID <= 0 {
return groups
}
groups = append(groups, fmt.Sprintf(
"section_%s",
strings.ReplaceAll(person.Section.ShortName, " ", "_"),
))
if person.Section.ParentSectionID == nil {
return groups
}
parentID := person.Section.ParentSectionID
for {
var section models.Section
db.Preload("parent_section").Find(&section, "id = ?", parentID)
if section.ID <= 0 {
return groups
}
groups = append(groups, fmt.Sprintf(
"section_%s",
strings.ReplaceAll(section.ShortName, " ", "_"),
))
if section.ParentSectionID != nil {
parentID = person.Section.ParentSectionID
} else {
break
}
}
return groups
}

View file

@ -1,7 +1,7 @@
package models package models
import ( import (
"time" "database/sql"
"github.com/google/uuid" "github.com/google/uuid"
"gorm.io/gorm" "gorm.io/gorm"
@ -30,13 +30,9 @@ type PersonAccount struct {
Person Person Person Person
UUID uuid.UUID `gorm:"unique"` UUID uuid.UUID `gorm:"unique"`
Enabled bool Enabled bool
Email string `gorm:"unique"`
GivenName string
FamilyName string
DisplayName string
Groups string Groups string
InitialPassword string InitialPassword string
InvitationSent time.Time InvitationSent sql.NullTime
AccountReady bool AccountReady bool
AccountCreated bool AccountCreated bool
UpdateNeeded bool UpdateNeeded bool

View file

@ -18,13 +18,13 @@
{% if Person.ID %} {% if Person.ID %}
{% if Person.IsMember %} {% if Person.IsMember %}
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="/admin/members/{{ Person.ID }}"> <a href="/members/{{ Person.ID }}">
{{ Person.LastName }} {{ Person.FirstName }} {{ Person.LastName }} {{ Person.FirstName }}
</a> </a>
</li> </li>
{% else %} {% else %}
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="/admin/contacts/{{ Person.ID }}"> <a href="/contacts/{{ Person.ID }}">
{{ Person.LastName }} {{ Person.FirstName }} {{ Person.LastName }} {{ Person.FirstName }}
</a> </a>
</li> </li>
@ -345,6 +345,32 @@
</div> </div>
{% endfor %} {% endfor %}
{% if Person.IsMember or MembersPage %}
<div class="mt-4 mb-3">
<span class="h4"> Compte POP Vaud </span>
</div>
<div class="mb-1">
<input
type="checkbox"
class="form-check-input me-2"
id="account-enabled"
name="account-enabled"
autocomplete="off"
{% if PersonAccount.Enabled %}
checked
{% endif %}
/>
<label
for="account-enabled"
class="form-label"
>
Dispose d'un accès SSO <b class="text-danger">(test, ne pas toucher, MERCI)</b>
</label>
</div>
{% endif %}
<div class="my-5"> <div class="my-5">
<button class="btn btn-outline-primary" type="submit"> <button class="btn btn-outline-primary" type="submit">
<i class="me-1 bi-floppy"></i> <i class="me-1 bi-floppy"></i>