86 lines
2.1 KiB
Go
86 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, error) {
|
|
endpoint := userinfoEndpoint + token.AccessToken
|
|
|
|
var cancel context.CancelFunc
|
|
ctx, cancel = context.WithTimeout(ctx, time.Second*5)
|
|
defer cancel()
|
|
|
|
r, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not create request: %w", err)
|
|
}
|
|
|
|
res, err := http.DefaultClient.Do(r)
|
|
if err != nil {
|
|
return nil, 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, fmt.Errorf("could not decode userinfo json: %w", err)
|
|
}
|
|
|
|
// register new user
|
|
if _, err := db.User(ctx, user.Email); err != nil {
|
|
if !strings.HasSuffix(user.Email, emailDomain) {
|
|
return nil, models.NewUserError("invalid registration email: %s", user.Email)
|
|
}
|
|
|
|
err = db.UpdateUser(ctx, user)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not create user: %w", err)
|
|
}
|
|
}
|
|
|
|
// gen new token
|
|
tk, err := db.CreateToken(ctx, user)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not create user token: %w", err)
|
|
}
|
|
return tk, nil
|
|
}
|