Skip to content
Snippets Groups Projects
accessToken.go 2.08 KiB
Newer Older
package dbModels

import (
	"database/sql"

	"github.com/jmoiron/sqlx"
	uuid "github.com/satori/go.uuid"
	"github.com/zachmann/mytoken/internal/db"
)

// AccessToken holds database information about an access token
type AccessToken struct {
	Token   string
Gabriel Zachmann's avatar
Gabriel Zachmann committed
	IP      string
	Comment string
Gabriel Zachmann's avatar
Gabriel Zachmann committed
	STID    uuid.UUID
Gabriel Zachmann's avatar
Gabriel Zachmann committed
	Scopes    []string
	Audiences []string
}

type accessToken struct {
	Token   string
Gabriel Zachmann's avatar
Gabriel Zachmann committed
	IP      string `db:"ip_created"`
	Comment sql.NullString
Gabriel Zachmann's avatar
Gabriel Zachmann committed
	STID    uuid.UUID `db:"ST_id"`
}
Gabriel Zachmann's avatar
Gabriel Zachmann committed
func (t *AccessToken) toDBObject() accessToken {
	return accessToken{
		Token:   t.Token,
		IP:      t.IP,
		Comment: db.NewNullString(t.Comment),
		STID:    t.STID,
	}
}

func (t *AccessToken) getDBAttributes(atID uint64) (attrs []accessTokenAttribute, err error) {
Gabriel Zachmann's avatar
Gabriel Zachmann committed
	var scopeAttrID uint64
	var audAttrID uint64
	if err = db.DB().QueryRow(`SELECT id FROM Attributes WHERE attribute=?`, "scope").Scan(&scopeAttrID); err != nil {
Gabriel Zachmann's avatar
Gabriel Zachmann committed
		return
	}
	if err = db.DB().QueryRow(`SELECT id FROM Attributes WHERE attribute=?`, "audience").Scan(&audAttrID); err != nil {
Gabriel Zachmann's avatar
Gabriel Zachmann committed
		return
	}
	for _, s := range t.Scopes {
		attrs = append(attrs, accessTokenAttribute{
Gabriel Zachmann's avatar
Gabriel Zachmann committed
			ATID:   atID,
			AttrID: scopeAttrID,
			Attr:   s,
		})
	}
	for _, a := range t.Audiences {
		attrs = append(attrs, accessTokenAttribute{
Gabriel Zachmann's avatar
Gabriel Zachmann committed
			ATID:   atID,
			AttrID: audAttrID,
			Attr:   a,
		})
	}
	return
// Store stores the AccessToken in the database as well as the relevant attributes
func (t *AccessToken) Store() error {
	return db.Transact(func(tx *sqlx.Tx) error {
Gabriel Zachmann's avatar
Gabriel Zachmann committed
		store := t.toDBObject()
		res, err := tx.NamedExec(`INSERT INTO AccessTokens (token, ip_created, comment, ST_id) VALUES (:token, :ip_created, :comment, :ST_id)`, store)
		if err != nil {
			return err
		}
Gabriel Zachmann's avatar
Gabriel Zachmann committed
		if len(t.Scopes) > 0 || len(t.Audiences) > 0 {
			atID, err := res.LastInsertId()
			if err != nil {
				return err
			}
			attrs, err := t.getDBAttributes(uint64(atID))
			if _, err = tx.NamedExec(`INSERT INTO AT_Attributes (AT_id, attribute_id, attribute) VALUES (:AT_id, :attribute_id, :attribute)`, attrs); err != nil {
Gabriel Zachmann's avatar
Gabriel Zachmann committed
				return err
			}
		}
		return nil
	})
}