diff --git a/controllers/contacts.go b/controllers/contacts.go index 7698f3c..1d1ed38 100644 --- a/controllers/contacts.go +++ b/controllers/contacts.go @@ -762,7 +762,7 @@ func ContactEdit(c *fiber.Ctx) error { if len(data.Email) > 0 { 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 { return result.Error } diff --git a/controllers/members.go b/controllers/members.go index f46b307..569c3ad 100644 --- a/controllers/members.go +++ b/controllers/members.go @@ -8,11 +8,13 @@ import ( "time" "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/models" "github.com/charmbracelet/log" "github.com/go-playground/validator/v10" "github.com/gofiber/fiber/v2" + "github.com/google/uuid" ) 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( "/members/%d", person.ID, @@ -714,6 +726,9 @@ func MemberEdit(c *fiber.Ctx) error { person.ID, ) + var personAccount models.PersonAccount + db.Find(&personAccount, "person_id = ?", person.ID) + var errors []string if c.Method() == "POST" { data := PersonValidation{ @@ -765,7 +780,7 @@ func MemberEdit(c *fiber.Ctx) error { if len(data.Email) > 0 { 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 { return result.Error } @@ -906,6 +921,33 @@ func MemberEdit(c *fiber.Ctx) 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( "/members/%d", person.ID, @@ -914,12 +956,13 @@ func MemberEdit(c *fiber.Ctx) error { } return c.Render("person_form", fiber.Map{ - "PageTitle": title, - "Person": person, - "Sections": sections, - "Fields": fields, - "FieldValues": fieldValues, - "Errors": errors, + "PageTitle": title, + "Person": person, + "Sections": sections, + "Fields": fields, + "FieldValues": fieldValues, + "PersonAccount": personAccount, + "Errors": errors, }) } diff --git a/helpers/authelia/groups.go b/helpers/authelia/groups.go new file mode 100644 index 0000000..4620b13 --- /dev/null +++ b/helpers/authelia/groups.go @@ -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(§ion, "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 +} diff --git a/models/people.go b/models/people.go index 6086734..f711d97 100644 --- a/models/people.go +++ b/models/people.go @@ -1,7 +1,7 @@ package models import ( - "time" + "database/sql" "github.com/google/uuid" "gorm.io/gorm" @@ -30,13 +30,9 @@ type PersonAccount struct { Person Person UUID uuid.UUID `gorm:"unique"` Enabled bool - Email string `gorm:"unique"` - GivenName string - FamilyName string - DisplayName string Groups string InitialPassword string - InvitationSent time.Time + InvitationSent sql.NullTime AccountReady bool AccountCreated bool UpdateNeeded bool diff --git a/views/person_form.html b/views/person_form.html index b7c1081..eb81651 100644 --- a/views/person_form.html +++ b/views/person_form.html @@ -18,13 +18,13 @@ {% if Person.ID %} {% if Person.IsMember %} {% else %} @@ -345,6 +345,32 @@ {% endfor %} + + {% if Person.IsMember or MembersPage %} +
+ Compte POP Vaud +
+ +
+ + +
+ {% endif %} +