Skip to content
run.go 4.32 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.

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

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