Newer
Older
package importer
import (
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt"
"regexp"
)
var uuid_re = regexp.MustCompile(`\A^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\z`)
func (app *App) Run(listing Listing) error {
// Check listing
for _, user := range listing {
if len(user.Email) == 0 || len(user.Fullname) == 0 || !uuid_re.MatchString(user.Uuid) {
return fmt.Errorf("Invalid user uuid:%q email:%q fullname:%q", user.Uuid, user.Email, user.Fullname)
}
}
// Send emails
for _, user := range listing {
err := func() error {
tx, err := app.Service.DB.Begin()
if err != nil {
return fmt.Errorf("Transaction error: %s", user.Uuid, err.Error())
}
userCount := 0
err = tx.QueryRowContext(app.Context, `SELECT COUNT(1) FROM users WHERE uuid=$1`, user.Uuid).Scan(&userCount)
if err != nil {
return fmt.Errorf("Error checking previous presence of user %s: %s", user.Uuid, err.Error())
}
if userCount == 1 {
// User is present, and has received an email already, skip
return fmt.Errorf("User already present")
}
if userCount != 0 {
return fmt.Errorf("Unique uuid violation for %s", user.Uuid)
}
userPrivateTokenRaw := make([]byte, 32)
n, err := rand.Read(userPrivateTokenRaw)
if err != nil {
return fmt.Errorf("Error making private token: %s", err)
}
if n != 32 {
return fmt.Errorf("Error making private token: %d != 32", n)
}
userPrivateToken := hex.EncodeToString(userPrivateTokenRaw)
userPublicTokenRaw := sha256.Sum256([]byte(userPrivateToken))
userPublicToken := hex.EncodeToString(userPublicTokenRaw[:])
_, err = tx.ExecContext(app.Context, `
INSERT INTO users(uuid, public_token, fullname, email, admin)
VALUES($1, $2, $3, $4, $5)
`, user.Uuid, userPublicToken, user.Fullname, user.Email, user.Admin)
if err != nil {
tx.Rollback()
return fmt.Errorf("Error inserting user: %s", err)
}
body := fmt.Sprintf(EMAIL_TOKEN_BODY, user.Fullname, userPrivateToken)
err = app.Service.Email.Send(user.Email, EMAIL_TOKEN_SUBJECT, body)
if err != nil {
return fmt.Errorf("Error sending email: %s", err)
}
err = tx.Commit()
if err != nil {
return fmt.Errorf("Error committing transation: %s", err)
}
return nil
}()
fmt.Fprintf(os.Stderr, "Email error for %s (%s): %s\n", user.Fullname, user.Uuid, err.Error())
} else {
fmt.Fprintf(os.Stdout, "Email sent for %s (%s)\n", user.Fullname, user.Uuid)
const EMAIL_TOKEN_SUBJECT = "AG Electrolab - Votre acces au vote en ligne"
Vous recevez ce mail car vous êtes membre actif de l'association Electrolab. De par les statuts de l'association, vous disposez du droit de vote à l'assemblée générale qui aura lieu le 19/06/2021 à 15h.
L'assemblée générale ayant lieu cette année à distance du fait des risques sanitaires liés à l'épidémie de Covid 19, le vote se fera par voie électronique.
Pour suivre la présentation, rendez-vous sur la chaine Twitch du lab : https://www.twitch.tv/electrolabhackerspace . Vous n'aurez pas besoin de compte Twitch pour suivre la présentation, par contre ce compte est nécessaire pour poser des questions dans le chat. Si vous le préférez, vous pouvez opter pour le chat de l'association : https://chat.electrolab.fr/electrolab/channels/ag2021
Des modérateurs seront présents pour lire les messages sur ces deux canaux et transmettre les questions aux intervenants.
Si vous avez un compte Twitch et que vous êtes abonné à la chaîne de l'Electrolab, vous serez prévenu par une notification au moment du lancement du live.
Sinon, rendez-vous à partir de 14h45, le live s’affichera dès l’accueil de notre chaîne.
Le présent courrier électronique contient un code unique qui vous permettra de voter sur les différents points de cette assemblée générale.
Ce code unique est personnel et ne permet de voter qu'une seule fois.
La procuration du vote se fait en transmettant le code unique à la personne à qui on cède son pouvoir.
Pour voter, rendez-vous à l'adresse suivante :
https://vote.electrolab.fr/events/Electrolab-AG-2021/votes?private_token=%s
Si vous avez des questions, n'hésitez pas à nous écrire à contact@electrolab.fr, ou sur le chat de l'association https://chat.electrolab.fr