Skip to content
run.go 4.33 KiB
Newer Older
Lo^2's avatar
Lo^2 committed
package importer

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
Lo^2's avatar
Lo^2 committed
	"os"
Lo^2's avatar
Lo^2 committed
	"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 {

Lo^2's avatar
Lo^2 committed
		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, `
Lo^2's avatar
Lo^2 committed
			INSERT INTO users(uuid, public_token, fullname, email, admin)
			VALUES($1, $2, $3, $4, $5)
		`, user.Uuid, userPublicToken, user.Fullname, user.Email, user.Admin)
Lo^2's avatar
Lo^2 committed
			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)
			}
Lo^2's avatar
Lo^2 committed

Lo^2's avatar
Lo^2 committed
			err = tx.Commit()
			if err != nil {
				return fmt.Errorf("Error committing transation: %s", err)
			}

			return nil
		}()
Lo^2's avatar
Lo^2 committed

		if err != nil {
Lo^2's avatar
Lo^2 committed
			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)
Lo^2's avatar
Lo^2 committed
		}
	}
	return nil
}

Lo^2's avatar
Lo^2 committed
const EMAIL_TOKEN_SUBJECT = "AG Electrolab - Votre acces au vote en ligne"
Lo^2's avatar
Lo^2 committed

const EMAIL_TOKEN_BODY = `Bonjour %s,

Lo^2's avatar
Lo^2 committed
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.
Lo^2's avatar
Lo^2 committed

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.

Vous pourrez suivre la présentation à cette adresse: https://www.youtube.com/user/ElectrolabFr
Si vous vous inscrivez à la chaîne et que vous cliquez sur la cloche, vous serez prévenu au moment du lancement du live.
Sinon, rendez-vous à partir de 14h45, le live s’affichera dès l’accueil de notre chaîne en haut de la liste des vidéos.

Lo^2's avatar
Lo^2 committed
Pour intervenir ou poser des questions, il faudra soit écrire dans le chat de la page Youtube en lien ci-dessus, soit écrire dans le chat de l'association : https://chat.electrolab.fr/electrolab/channels/ag2021 (si par exemple vous n’avez pas de compte youtube ou si vous préférez passer par ce canal). Des modérateurs seront présents pour lire les messages sur ces deux canaux et transmettre les questions aux intervenants.
Lo^2's avatar
Lo^2 committed

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 :
Lo^2's avatar
Lo^2 committed
https://vote.electrolab.fr/events/Electrolab-AG-2021/votes?private_token=%s
Lo^2's avatar
Lo^2 committed

Lo^2's avatar
Lo^2 committed
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
Lo^2's avatar
Lo^2 committed

Lo^2's avatar
Lo^2 committed
Librement,
Lo^2's avatar
Lo^2 committed

Lo^2's avatar
Lo^2 committed
Le CA
Lo^2's avatar
Lo^2 committed
`