hackathon/db/user.go

83 lines
2.1 KiB
Go

package db
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
"github.com/hhhapz/codequest/models"
"golang.org/x/oauth2"
)
func (db *DB) Users(ctx context.Context) ([]*models.User, error) {
return models.Users(ctx, db.DB)
}
func (db *DB) User(ctx context.Context, email string) (*models.User, error) {
return models.UserByEmail(ctx, db.DB, email)
}
func (db *DB) UpdateUser(ctx context.Context, user *models.User) error {
if err := user.Upsert(ctx, db.DB); err != nil {
return fmt.Errorf("could not upsert user: %w", err)
}
return nil
}
func (db *DB) DeleteUser(ctx context.Context, user *models.User) error {
if err := user.Delete(ctx, db.DB); err != nil {
return fmt.Errorf("could not delete user: %w", err)
}
return nil
}
const (
userinfoEndpoint = "https://www.googleapis.com/oauth2/v2/userinfo?access_token="
emailDomain = "@jisedu.or.id"
)
func (db *DB) ConsumeToken(ctx context.Context, token *oauth2.Token) (*models.Token, bool, error) {
endpoint := userinfoEndpoint + token.AccessToken
client := http.Client{Timeout: time.Second * 5}
res, err := client.Get(endpoint)
if err != nil {
return nil, false, fmt.Errorf("could not get userinfo: %w", err)
}
defer res.Body.Close()
user := &models.User{
CreatedAt: models.NewTime(time.Now()),
}
if err := json.NewDecoder(res.Body).Decode(&user); err != nil {
return nil, false, fmt.Errorf("could not decode userinfo json: %w", err)
}
if u, err := db.User(ctx, user.Email); err == nil {
var tk *models.Token
if tk, err = db.CreateToken(ctx, u); err != nil {
return nil, false, fmt.Errorf("could not create user token: %w", err)
}
return tk, true, nil
}
if !strings.HasSuffix(user.Email, emailDomain) {
return nil, true, fmt.Errorf("invalid registration email %q: must end with %q", user.Email, emailDomain)
}
err = db.UpdateUser(ctx, user)
if err != nil {
return nil, false, fmt.Errorf("could not create user: %w", err)
}
tk, err := db.CreateToken(ctx, user)
if err != nil {
return nil, false, fmt.Errorf("could not create user token: %w", err)
}
return tk, true, nil
}