canape/backend/models/users.go

173 lines
4.2 KiB
Go

package models
import (
"database/sql"
"errors"
"fmt"
"github.com/jmoiron/sqlx"
"github.com/jmoiron/sqlx/types"
"github.com/odwrtw/polochon/lib/papi"
)
const (
addUserQuery = `INSERT INTO
users (name, hash, admin, polochon_id, token)
VALUES ($1, $2, $3, $4, $5)
RETURNING id;`
getUserQuery = `SELECT * FROM users WHERE name=$1;`
getUserByIDQuery = `SELECT * FROM users WHERE id=$1;`
updateUserQuery = `UPDATE users SET
name=:name, hash=:hash, admin=:admin, activated=:activated,
rawconfig=:rawconfig, polochon_id=:polochon_id, token=:token,
polochon_activated=:polochon_activated
WHERE id=:id
RETURNING *;`
deleteUserQuery = `DELETE FROM users WHERE id=:id;`
getAllUsersQuery = `SELECT * FROM users order by created_at;`
getPolochonUsersQuery = `SELECT * FROM users WHERE polochon_id = $1;`
)
const (
// UserRole represents the user's role
UserRole = "user"
// AdminRole represents the admin's role
AdminRole = "admin"
)
// ErrUnknownUser returned when a user does'nt exist
var ErrUnknownUser = fmt.Errorf("users: user does'nt exist")
// User represents an user
type User struct {
BaseModel
Name string `json:"name"`
Hash string `json:"-"`
Admin bool `json:"admin"`
RawConfig types.JSONText `json:"raw_config"`
Token string `json:"token"`
Activated bool `json:"activated"`
PolochonID sql.NullString `json:"polochon_id" db:"polochon_id"`
PolochonActivated bool `json:"polochon_activated" db:"polochon_activated"`
Polochon *Polochon `json:"polochon"`
}
// NewPapiClient creates a new papi client for the given user
func (u *User) NewPapiClient(db *sqlx.DB) (*papi.Client, error) {
polochon, err := u.GetPolochon(db)
if err != nil {
return nil, err
}
client, err := papi.New(polochon.URL)
if err != nil {
return nil, errors.New("error getting papi client")
}
if u.Token != "" {
client.SetToken(u.Token)
}
return client, nil
}
// GetUser returns user with specified name
func GetUser(q sqlx.Queryer, name string) (*User, error) {
u := &User{}
err := q.QueryRowx(getUserQuery, name).StructScan(u)
if err != nil {
if err == sql.ErrNoRows {
return nil, ErrUnknownUser
}
return nil, err
}
return u, nil
}
// GetUserByID returns user using its id
func GetUserByID(q sqlx.Queryer, id string) (*User, error) {
u := &User{}
err := q.QueryRowx(getUserByIDQuery, id).StructScan(u)
if err != nil {
if err == sql.ErrNoRows {
return nil, ErrUnknownUser
}
return nil, err
}
return u, nil
}
// GetAllUsers returns all the users
func GetAllUsers(db *sqlx.DB) ([]*User, error) {
users := []*User{}
err := db.Select(&users, getAllUsersQuery)
if err != nil {
return nil, err
}
return users, nil
}
// GetPolochonUsers returns all the users of a polochon
func GetPolochonUsers(db *sqlx.DB, id string) ([]*User, error) {
users := []*User{}
err := db.Select(&users, getPolochonUsersQuery, id)
if err != nil {
return nil, err
}
return users, nil
}
// Add user to database or raises an error
func (u *User) Add(q sqlx.Queryer) error {
var id string
err := q.QueryRowx(addUserQuery, u.Name, u.Hash, u.Admin, u.PolochonID, u.Token).Scan(&id)
if err != nil {
return err
}
u.ID = id
return nil
}
// Update user on database or raise an error
func (u *User) Update(ex *sqlx.DB) error {
rows, err := ex.NamedQuery(updateUserQuery, u)
if err != nil {
return err
}
for rows.Next() {
if err := rows.StructScan(u); err != nil {
return err
}
}
return nil
}
// Delete user from database or raise an error
func (u *User) Delete(ex *sqlx.DB) error {
_, err := ex.NamedExec(deleteUserQuery, u)
return err
}
// HasRole checks if a user as a role
func (u *User) HasRole(role string) bool {
if role == AdminRole && !u.Admin {
return false
}
return true
}
// IsAdmin checks if a user is admin
func (u *User) IsAdmin() bool {
return u.HasRole(AdminRole)
}
// IsActivated checks if a user is activated
func (u *User) IsActivated() bool {
return u.Activated
}
// GetPolochon returns the user's polochon
func (u *User) GetPolochon(db *sqlx.DB) (*Polochon, error) {
return GetPolochonByID(db, u.PolochonID.String)
}