6 Commits 00cca5afcc ... 84dc991642

Author SHA1 Message Date
  Adam 84dc991642 simplify render functions 4 years ago
  Adam df2b87dc9c add logging in 4 years ago
  Adam 060971fafc add manage command 4 years ago
  Adam 1ba05ec187 show login page 4 years ago
  Adam 865dd5bb21 update dependecy: gott 4 years ago
  Adam cdcca02e96 add log-in links to header 4 years ago
10 changed files with 403 additions and 122 deletions
  1. 23 0
      accounts/common.go
  2. 188 0
      accounts/login.go
  3. 127 0
      db/db.go
  4. 5 0
      front/capnproto.go
  5. 38 121
      front/html.go
  6. 1 0
      front/renderer.go
  7. 3 1
      go.mod
  8. 9 0
      go.sum
  9. 9 0
      libamuse/account.go
  10. 0 0
      libamuse/common.go

+ 23 - 0
accounts/common.go

@@ -0,0 +1,23 @@
+package accounts
+
+type User struct {
+	Username string
+	IsAdmin  bool
+}
+
+func (u User) IsEmpty() bool {
+	emptyUser := User{}
+	return u == emptyUser
+}
+
+type AuthError struct {
+	Err error
+}
+
+func (e AuthError) Error() string {
+	return "Auth error: " + e.Err.Error()
+}
+
+func (e AuthError) Unwrap() error {
+	return e.Err
+}

+ 188 - 0
accounts/login.go

@@ -0,0 +1,188 @@
+package accounts
+
+// https://golangcode.com/argon2-password-hashing/
+
+import (
+	"notabug.org/apiote/amuse/db"
+
+	"bytes"
+	"database/sql"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"strings"
+	"crypto/rand"
+	"encoding/hex"
+
+	"github.com/pquerna/otp/totp"
+	"golang.org/x/crypto/argon2"
+	"notabug.org/apiote/gott"
+)
+
+type AuthData struct {
+	username   string
+	password   string
+	passRepeat string
+	sfa        string
+	remember   bool
+}
+
+type AuthResult struct {
+	row              *sql.Rows
+	passwordHash     string
+	sfaSecret        string
+	recoveryCodesRaw string
+	recoveryCodes    []string
+	token            string
+}
+
+type Argon struct {
+	password string
+	argon    string
+	parts    []string
+	memory   uint32
+	time     uint32
+	threads  uint8
+	salt     []byte
+	hash     []byte
+	keyLen   uint32
+}
+
+func findUser(args ...interface{}) (interface{}, error) {
+	authData := args[0].(*AuthData)
+	authResult := args[1].(*AuthResult)
+	row, err := db.GetUser(authData.username)
+	authResult.row = row
+	if empty, ok := err.(db.EmptyError); ok {
+		err = AuthError{Err: empty}
+	}
+	return gott.Tuple(args), err
+}
+
+func unmarshalUser(args ...interface{}) (interface{}, error) {
+	authResult := args[1].(*AuthResult)
+	err := authResult.row.Scan(&authResult.passwordHash, &authResult.sfaSecret,
+		&authResult.recoveryCodesRaw)
+	authResult.row.Close()
+	authResult.recoveryCodes = strings.Split(authResult.recoveryCodesRaw, ",")
+	return gott.Tuple(args), err
+}
+
+func splitArgon(args ...interface{}) interface{} {
+	argon := args[0].(*Argon)
+	argon.parts = strings.Split(argon.argon, "$")
+	return gott.Tuple(args)
+}
+
+func decodeArgonParams(args ...interface{}) (interface{}, error) {
+	argon := args[0].(*Argon)
+	_, err := fmt.Sscanf(argon.parts[3], "m=%d,t=%d,p=%d", &argon.memory,
+		&argon.time, &argon.threads)
+	return gott.Tuple(args), err
+}
+
+func decodeSalt(args ...interface{}) (interface{}, error) {
+	argon := args[0].(*Argon)
+	salt, err := base64.RawStdEncoding.DecodeString(argon.parts[4])
+	argon.salt = salt
+	return gott.Tuple(args), err
+}
+
+func decodeHash(args ...interface{}) (interface{}, error) {
+	argon := args[0].(*Argon)
+	hash, err := base64.RawStdEncoding.DecodeString(argon.parts[5])
+	argon.hash = hash
+	argon.keyLen = uint32(len(hash))
+	return gott.Tuple(args), err
+}
+
+func compareArgon(args ...interface{}) (interface{}, error) {
+	argon := args[0].(*Argon)
+	comparisonHash := argon2.IDKey([]byte(argon.password), argon.salt, argon.time,
+		argon.memory, argon.threads, argon.keyLen)
+	if bytes.Compare(comparisonHash, argon.hash) != 0 {
+		return gott.Tuple(args), AuthError{Err: errors.New("Password does not match")}
+	} else {
+		return gott.Tuple(args), nil
+	}
+}
+
+func checkPassword(args ...interface{}) (interface{}, error) {
+	authData := args[0].(*AuthData)
+	authResult := args[1].(*AuthResult)
+	_, err := gott.
+		NewResult(gott.Tuple{&Argon{argon: authResult.passwordHash,
+			password: authData.password}}).
+		Map(splitArgon).
+		Bind(decodeArgonParams).
+		Bind(decodeSalt).
+		Bind(decodeHash).
+		Bind(compareArgon).
+		Finish()
+	return gott.Tuple(args), err
+}
+
+func checkSfa(args ...interface{}) (interface{}, error) {
+	authData := args[0].(*AuthData)
+	authResult := args[1].(*AuthResult)
+	if authResult.sfaSecret == "" {
+		return gott.Tuple(args), nil
+	}
+
+	for i, code := range authResult.recoveryCodes {
+		if authData.sfa == code {
+			authResult.recoveryCodes = append(authResult.recoveryCodes[:i],
+				authResult.recoveryCodes[i+1:]...)
+			authResult.recoveryCodesRaw = strings.Join(authResult.recoveryCodes, ",")
+			return gott.Tuple(args), nil
+		}
+	}
+
+	if totp.Validate(authData.sfa, authResult.sfaSecret) {
+		return gott.Tuple(args), nil
+	}
+
+	return gott.Tuple(args), AuthError{Err: errors.New("Wrong TOTP token")}
+}
+
+func updateSfa(args ...interface{}) (interface{}, error) {
+	authData := args[0].(*AuthData)
+	authResult := args[1].(*AuthResult)
+	err := db.UpdateRecoveryCodes(authData.username, authResult.recoveryCodesRaw)
+	return gott.Tuple(args), err
+}
+
+func createToken(args ...interface{}) (interface{}, error) {
+	authResult := args[1].(*AuthResult)
+	sessionIdRaw := make([]byte, 128) 
+	rand.Read(sessionIdRaw)
+	sessionId := hex.EncodeToString(sessionIdRaw)
+	authResult.token = sessionId
+	return gott.Tuple(args), nil
+}
+
+func createSession(args ...interface{}) (interface{}, error) {
+	authData := args[0].(*AuthData)
+	authResult := args[1].(*AuthResult)
+	err := db.CreateSession(authData.username, authResult.token)
+	return gott.Tuple(args), err
+}
+
+func Login(username, password, sfa string, remember bool) (string, error) {
+	r, err := gott.
+		NewResult(gott.Tuple{&AuthData{username: username, password: password,
+			sfa: sfa, remember: remember}, &AuthResult{}}).
+		Bind(findUser).
+		//Clear old sessions
+		Bind(unmarshalUser).
+		Bind(checkPassword).
+		Bind(checkSfa).
+		Bind(updateSfa).
+		Bind(createToken).
+		Bind(createSession).
+		Finish()
+	if err != nil {
+		return "", err
+	}
+	return r.(gott.Tuple)[1].(*AuthResult).token, err
+}

+ 127 - 0
db/db.go

@@ -0,0 +1,127 @@
+package db
+
+import (
+	"notabug.org/apiote/amuse/utils"
+
+	"database/sql"
+	"errors"
+	"fmt"
+	"os"
+
+	_ "github.com/mattn/go-sqlite3"
+)
+
+type EmptyError struct {
+	message string
+}
+
+func (e EmptyError) Error() string {
+	return e.message
+}
+
+func Migrate() error {
+	// todo migrations
+	db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db")
+	if err != nil {
+		return err
+	}
+	defer db.Close()
+
+	_, err = db.Exec(`create table cache(uri text primary key, etag text, date date, response blob, last_hit date)`)
+	if err != nil {
+		return err
+	}
+	_, err = db.Exec(`create table users(username text primary key, password text, sfa text, avatar blob, is_admin bool, recovery_codes text)`)
+	if err != nil {
+		return err
+	}
+	_, err = db.Exec(`create table sessions(id text primary key, username text, created datetime, foreign key(username) references users(username))`)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func MakeAdmin(username string) error {
+	db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db")
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "DB open err\n")
+		return err
+	}
+	defer db.Close()
+	_, err = db.Exec("update users set is_admin = 1 where username = ?", username)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Update err %v\n", err)
+		return err
+	}
+	rows, err := db.Query(`select is_admin from users where username = ?`, username)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Select err %v\n", err)
+		return err
+	}
+	defer rows.Close()
+
+	if !rows.Next() {
+		fmt.Fprintf(os.Stderr, "User %s does not exist\n", username)
+		return errors.New("User does not exist")
+	}
+	var isAdmin bool
+	err = rows.Scan(&isAdmin)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Scan err %v\n", err)
+		return err
+	}
+	fmt.Println(isAdmin)
+	return nil
+}
+
+func GetUser(username string) (*sql.Rows, error) {
+	db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db")
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "DB open err\n")
+		return nil, err
+	}
+	defer db.Close()
+	rows, err := db.Query(`select password, sfa, recovery_codes from users where username = ?`, username)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Select err %v\n", err)
+		return nil, err
+	}
+	if !rows.Next() {
+		return nil, EmptyError{message: "User does not exist"}
+	}
+	return rows, nil
+}
+
+func UpdateRecoveryCodes(username, recoveryCodes string) error {
+	db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db")
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "DB open err\n")
+		return err
+	}
+	defer db.Close()
+	
+	_, err = db.Exec(`update users set recovery_codes = ? where username = ?`, recoveryCodes, username)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func CreateSession(username, sessionId string) error {
+	db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db")
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "DB open err\n")
+		return err
+	}
+	defer db.Close()
+	
+	_, err = db.Exec(`insert into sessions values(?, ?, datetime('now'))`, sessionId, username)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}

+ 5 - 0
front/capnproto.go

@@ -48,3 +48,8 @@ func (CapnprotoRenderer) RenderAbout(languages []language.Tag) string {
 func (CapnprotoRenderer) RenderErrorPage(code int, languages []language.Tag) string {
 func (CapnprotoRenderer) RenderErrorPage(code int, languages []language.Tag) string {
 	return TODO("implement CapnprotoRenderer.RenderErrorPage").(string)
 	return TODO("implement CapnprotoRenderer.RenderErrorPage").(string)
 }
 }
+
+func (CapnprotoRenderer) RenderLogin(languages []language.Tag, err error) string {
+	// todo throw Wrong Accept
+	return TODO("implement CapnprotoRenderer.RenderLogin").(string)
+}

+ 38 - 121
front/html.go

@@ -1,10 +1,11 @@
 package front
 package front
 
 
 import (
 import (
+	"notabug.org/apiote/amuse/accounts"
 	"notabug.org/apiote/amuse/i18n"
 	"notabug.org/apiote/amuse/i18n"
 	"notabug.org/apiote/amuse/tmdb"
 	"notabug.org/apiote/amuse/tmdb"
-	"notabug.org/apiote/amuse/wikidata"
 	"notabug.org/apiote/amuse/utils"
 	"notabug.org/apiote/amuse/utils"
+	"notabug.org/apiote/amuse/wikidata"
 
 
 	"bytes"
 	"bytes"
 	"golang.org/x/text/language"
 	"golang.org/x/text/language"
@@ -16,6 +17,10 @@ import (
 type RenderData struct {
 type RenderData struct {
 	Data    interface{}
 	Data    interface{}
 	Strings i18n.Translation
 	Strings i18n.Translation
+	State   struct {
+		Error error
+		User  accounts.User
+	}
 }
 }
 
 
 func (d RenderData) LetAmuse0() string {
 func (d RenderData) LetAmuse0() string {
@@ -44,15 +49,17 @@ func (d RenderData) GetErrorData(code int, kind string) string {
 
 
 type HtmlRenderer struct{}
 type HtmlRenderer struct{}
 
 
-func (HtmlRenderer) RenderFilm(film *tmdb.Film, languages []language.Tag) string {
+func render(languages []language.Tag, data RenderData, file string) string {
 	i18n.LoadServerLangs()
 	i18n.LoadServerLangs()
 	language := i18n.Match(languages)
 	language := i18n.Match(languages)
 	strings, err := i18n.LoadStrings(language)
 	strings, err := i18n.LoadStrings(language)
 	if err != nil {
 	if err != nil {
 		// todo return http:500
 		// todo return http:500
 	}
 	}
-	data := RenderData{film, strings}
-	t, _ := template.ParseFiles(utils.DataHome + "/templates/film.html")
+
+	data.Strings = strings
+
+	t, _ := template.ParseFiles(utils.DataHome + "/templates/" + file + ".html")
 	b := bytes.NewBuffer([]byte{})
 	b := bytes.NewBuffer([]byte{})
 	err = t.Execute(b, data)
 	err = t.Execute(b, data)
 	if err != nil {
 	if err != nil {
@@ -61,146 +68,56 @@ func (HtmlRenderer) RenderFilm(film *tmdb.Film, languages []language.Tag) string
 	return b.String()
 	return b.String()
 }
 }
 
 
-func (HtmlRenderer) RenderSearch(tmdbResults *tmdb.SearchResults, inventaireResults *wikidata.SearchResults, languages []language.Tag) string {
-	i18n.LoadServerLangs()
-	language := i18n.Match(languages)
-	strings, err := i18n.LoadStrings(language)
-	if err != nil {
-		// todo return http:500
-	}
+func (HtmlRenderer) RenderFilm(film *tmdb.Film, languages []language.Tag) string {
+	data := RenderData{Data: film}
+	return render(languages, data, "film")
+}
 
 
+func (HtmlRenderer) RenderSearch(tmdbResults *tmdb.SearchResults, inventaireResults *wikidata.SearchResults, languages []language.Tag) string {
 	results := struct {
 	results := struct {
 		T *tmdb.SearchResults
 		T *tmdb.SearchResults
 		I *wikidata.SearchResults
 		I *wikidata.SearchResults
 	}{tmdbResults, inventaireResults}
 	}{tmdbResults, inventaireResults}
-
-	data := RenderData{results, strings}
-	t, _ := template.ParseFiles(utils.DataHome + "/templates/search.html")
-	b := bytes.NewBuffer([]byte{})
-	err = t.Execute(b, data)
-	if err != nil {
-		// todo return http:500
-	}
-	return b.String()
+	data := RenderData{Data: results}
+	return render(languages, data, "search")
 }
 }
 
 
 func (HtmlRenderer) RenderIndex(randomComedy string, languages []language.Tag) string {
 func (HtmlRenderer) RenderIndex(randomComedy string, languages []language.Tag) string {
-	i18n.LoadServerLangs()
-	language := i18n.Match(languages)
-	strings, err := i18n.LoadStrings(language)
-	if err != nil {
-		// todo return http:500
-	}
-	data := RenderData{randomComedy, strings}
-	t, _ := template.ParseFiles(utils.DataHome + "/templates/index.html")
-	b := bytes.NewBuffer([]byte{})
-	err = t.Execute(b, data)
-	if err != nil {
-		// todo return http:500
-	}
-	return b.String()
+	data := RenderData{Data: randomComedy}
+	return render(languages, data, "index")
 }
 }
 
 
-func (HtmlRenderer) RenderTvSerie(serie *tmdb.TvSerie, languages []language.Tag) string {
-	i18n.LoadServerLangs()
-	language := i18n.Match(languages)
-	strings, err := i18n.LoadStrings(language)
-	if err != nil {
-		// todo return http:500
-	}
-	data := RenderData{serie, strings}
-	t, _ := template.ParseFiles(utils.DataHome + "/templates/serie.html")
-	b := bytes.NewBuffer([]byte{})
-	err = t.Execute(b, data)
-	if err != nil {
-		// todo return http:500
-	}
-	return b.String()
+func (HtmlRenderer) RenderTvSerie(tvSerie *tmdb.TvSerie, languages []language.Tag) string {
+	data := RenderData{Data: tvSerie}
+	return render(languages, data, "tvserie")
 }
 }
 
 
 func (HtmlRenderer) RenderPerson(person *tmdb.Person, languages []language.Tag) string {
 func (HtmlRenderer) RenderPerson(person *tmdb.Person, languages []language.Tag) string {
-	i18n.LoadServerLangs()
-	language := i18n.Match(languages)
-	strings, err := i18n.LoadStrings(language)
-	if err != nil {
-		// todo return http:500
-	}
-	data := RenderData{person, strings}
-	t, _ := template.ParseFiles(utils.DataHome + "/templates/person.html")
-	b := bytes.NewBuffer([]byte{})
-	err = t.Execute(b, data)
-	if err != nil {
-		// todo return http:500
-	}
-	return b.String()
+	data := RenderData{Data: person}
+	return render(languages, data, "person")
 }
 }
 
 
 func (HtmlRenderer) RenderBook(book wikidata.Book, languages []language.Tag) string {
 func (HtmlRenderer) RenderBook(book wikidata.Book, languages []language.Tag) string {
-	i18n.LoadServerLangs()
-	language := i18n.Match(languages)
-	strings, err := i18n.LoadStrings(language)
-	if err != nil {
-		// todo return http:500
-	}
-	data := RenderData{book, strings}
-	t, _ := template.ParseFiles(utils.DataHome + "/templates/book.html")
-	b := bytes.NewBuffer([]byte{})
-	err = t.Execute(b, data)
-	if err != nil {
-		// todo return http:500
-	}
-	return b.String()
+	data := RenderData{Data: book}
+	return render(languages, data, "book")
 }
 }
 
 
 func (HtmlRenderer) RenderBookSerie(bookSerie wikidata.BookSerie, languages []language.Tag) string {
 func (HtmlRenderer) RenderBookSerie(bookSerie wikidata.BookSerie, languages []language.Tag) string {
-	i18n.LoadServerLangs()
-	language := i18n.Match(languages)
-	strings, err := i18n.LoadStrings(language)
-	if err != nil {
-		// todo return http:500
-	}
-	data := RenderData{bookSerie, strings}
-	t, _ := template.ParseFiles(utils.DataHome + "/templates/bookserie.html")
-	b := bytes.NewBuffer([]byte{})
-	err = t.Execute(b, data)
-	if err != nil {
-		// todo return http:500
-	}
-	return b.String()
+	data := RenderData{Data: bookSerie}
+	return render(languages, data, "bookserie")
 }
 }
 
 
 func (HtmlRenderer) RenderAbout(languages []language.Tag) string {
 func (HtmlRenderer) RenderAbout(languages []language.Tag) string {
-	i18n.LoadServerLangs()
-	language := i18n.Match(languages)
-	strings, err := i18n.LoadStrings(language)
-	if err != nil {
-		// todo return http:500
-	}
-	i18n.RenderAsciiDoc(strings.About["doc"])
-	data := RenderData{nil, strings}
-	t, _ := template.ParseFiles(utils.DataHome + "/templates/about.html")
-	b := bytes.NewBuffer([]byte{})
-	err = t.Execute(b, data)
-	if err != nil {
-		// todo return http:500
-	}
-	return b.String()
+	data := RenderData{}
+	return render(languages, data, "about")
 }
 }
 
 
 func (HtmlRenderer) RenderErrorPage(code int, languages []language.Tag) string {
 func (HtmlRenderer) RenderErrorPage(code int, languages []language.Tag) string {
-	i18n.LoadServerLangs()
-	language := i18n.Match(languages)
-	strings, err := i18n.LoadStrings(language)
-	if err != nil {
-		// todo return http:500
-	}
-	i18n.RenderAsciiDoc(strings.About["doc"])
-	data := RenderData{code, strings}
-	t, _ := template.ParseFiles(utils.DataHome + "/templates/error.html")
-	b := bytes.NewBuffer([]byte{})
-	err = t.Execute(b, data)
-	if err != nil {
-		// todo return http:500
-	}
-	return b.String()
+	data := RenderData{Data: code}
+	return render(languages, data, "error")
+}
+
+func (HtmlRenderer) RenderLogin(languages []language.Tag, authError error) string {
+	data := RenderData{}
+	return render(languages, data, "login")
 }
 }

+ 1 - 0
front/renderer.go

@@ -25,6 +25,7 @@ type Renderer interface {
 	RenderBookSerie(wikidata.BookSerie, []language.Tag) string
 	RenderBookSerie(wikidata.BookSerie, []language.Tag) string
 	RenderAbout([]language.Tag) string
 	RenderAbout([]language.Tag) string
 	RenderErrorPage(int, []language.Tag) string
 	RenderErrorPage(int, []language.Tag) string
+	RenderLogin([]language.Tag, error) string
 }
 }
 
 
 func NewRenderer(mimetype string) (Renderer, error) {
 func NewRenderer(mimetype string) (Renderer, error) {

+ 3 - 1
go.mod

@@ -12,12 +12,14 @@ require (
 	github.com/mattn/go-sqlite3 v2.0.2+incompatible
 	github.com/mattn/go-sqlite3 v2.0.2+incompatible
 	github.com/onsi/ginkgo v1.10.3 // indirect
 	github.com/onsi/ginkgo v1.10.3 // indirect
 	github.com/onsi/gomega v1.7.1 // indirect
 	github.com/onsi/gomega v1.7.1 // indirect
+	github.com/pquerna/otp v1.2.0
 	github.com/sirupsen/logrus v1.4.2 // indirect
 	github.com/sirupsen/logrus v1.4.2 // indirect
 	github.com/stretchr/testify v1.4.0 // indirect
 	github.com/stretchr/testify v1.4.0 // indirect
+	golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
 	golang.org/x/net v0.0.0-20191116160921-f9c825593386 // indirect
 	golang.org/x/net v0.0.0-20191116160921-f9c825593386 // indirect
 	golang.org/x/text v0.3.0
 	golang.org/x/text v0.3.0
 	golang.org/x/tools v0.0.0-20191204011308-9611592c72f6 // indirect
 	golang.org/x/tools v0.0.0-20191204011308-9611592c72f6 // indirect
 	gopkg.in/yaml.v2 v2.2.7 // indirect
 	gopkg.in/yaml.v2 v2.2.7 // indirect
-	notabug.org/apiote/gott v1.0.1
+	notabug.org/apiote/gott v1.1.0
 	zombiezen.com/go/capnproto2 v2.17.0+incompatible
 	zombiezen.com/go/capnproto2 v2.17.0+incompatible
 )
 )

+ 9 - 0
go.sum

@@ -1,5 +1,7 @@
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
+github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
 github.com/bytesparadise/libasciidoc v0.2.0 h1:W+Yh4cXehuQvFA+Ncs4tIgwBXiH8ie+KhHmMXkBhIcc=
 github.com/bytesparadise/libasciidoc v0.2.0 h1:W+Yh4cXehuQvFA+Ncs4tIgwBXiH8ie+KhHmMXkBhIcc=
 github.com/bytesparadise/libasciidoc v0.2.0/go.mod h1:CZX8GIEkxy/LHrDZjPbNrE16RQFDrnG6hBjnjXcD34Y=
 github.com/bytesparadise/libasciidoc v0.2.0/go.mod h1:CZX8GIEkxy/LHrDZjPbNrE16RQFDrnG6hBjnjXcD34Y=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -21,6 +23,7 @@ github.com/knakk/rdf v0.0.0-20190304171630-8521bf4c5042 h1:Vzdm5hdlLdpJOKK+hKtkV
 github.com/knakk/rdf v0.0.0-20190304171630-8521bf4c5042/go.mod h1:fYE0718xXI13XMYLc6iHtvXudfyCGMsZ9hxSM1Ommpg=
 github.com/knakk/rdf v0.0.0-20190304171630-8521bf4c5042/go.mod h1:fYE0718xXI13XMYLc6iHtvXudfyCGMsZ9hxSM1Ommpg=
 github.com/knakk/sparql v0.0.0-20190415133729-e66682c662f6 h1:/9NsggFoqFNblbAcHDeeAX9tiYnT6TteCUS80zanCGA=
 github.com/knakk/sparql v0.0.0-20190415133729-e66682c662f6 h1:/9NsggFoqFNblbAcHDeeAX9tiYnT6TteCUS80zanCGA=
 github.com/knakk/sparql v0.0.0-20190415133729-e66682c662f6/go.mod h1:vxUbHrxs7JHQF6LITj9Rp9yf2bqyz+5JZzPZkEkS3MA=
 github.com/knakk/sparql v0.0.0-20190415133729-e66682c662f6/go.mod h1:vxUbHrxs7JHQF6LITj9Rp9yf2bqyz+5JZzPZkEkS3MA=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kuangchanglang/graceful v1.0.0 h1:EPcA4vV75CkLi9+tW1+cd6KpfULYRTxTm1MO8USa49k=
 github.com/kuangchanglang/graceful v1.0.0 h1:EPcA4vV75CkLi9+tW1+cd6KpfULYRTxTm1MO8USa49k=
 github.com/kuangchanglang/graceful v1.0.0/go.mod h1:fQkb+p3PRjvdiAsa65Qv78lm9CsYc4M+yhiuU1rOVtg=
 github.com/kuangchanglang/graceful v1.0.0/go.mod h1:fQkb+p3PRjvdiAsa65Qv78lm9CsYc4M+yhiuU1rOVtg=
@@ -35,13 +38,17 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
+github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
 github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -70,5 +77,7 @@ gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
 gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 notabug.org/apiote/gott v1.0.1 h1:yfq2z3WM0lYFSu6xFvh1sWBKgg6yaXwF9/2wqJiKky8=
 notabug.org/apiote/gott v1.0.1 h1:yfq2z3WM0lYFSu6xFvh1sWBKgg6yaXwF9/2wqJiKky8=
 notabug.org/apiote/gott v1.0.1/go.mod h1:Z9hFvCdzZkFSegBkLa6n0X6AuUiw2BwgG4MFLgBMjD4=
 notabug.org/apiote/gott v1.0.1/go.mod h1:Z9hFvCdzZkFSegBkLa6n0X6AuUiw2BwgG4MFLgBMjD4=
+notabug.org/apiote/gott v1.1.0 h1:RGGbJo9ON5Qsk/lsw0oF1tiyFeogORINGILqizbdkC8=
+notabug.org/apiote/gott v1.1.0/go.mod h1:Z9hFvCdzZkFSegBkLa6n0X6AuUiw2BwgG4MFLgBMjD4=
 zombiezen.com/go/capnproto2 v2.17.0+incompatible h1:sIoKPFGNlM38Qh+PBLa9Wzg1j99oInS/Qlk+5N/CHa4=
 zombiezen.com/go/capnproto2 v2.17.0+incompatible h1:sIoKPFGNlM38Qh+PBLa9Wzg1j99oInS/Qlk+5N/CHa4=
 zombiezen.com/go/capnproto2 v2.17.0+incompatible/go.mod h1:XO5Pr2SbXgqZwn0m0Ru54QBqpOf4K5AYBO+8LAOBQEQ=
 zombiezen.com/go/capnproto2 v2.17.0+incompatible/go.mod h1:XO5Pr2SbXgqZwn0m0Ru54QBqpOf4K5AYBO+8LAOBQEQ=

+ 9 - 0
libamuse/account.go

@@ -0,0 +1,9 @@
+package libamuse
+
+import (
+	"notabug.org/apiote/amuse/accounts"
+)
+
+func VerifyAuthToken(token string) (accounts.User, error) {
+	return accounts.User{}, nil
+}

+ 0 - 0
libamuse/common.go


Some files were not shown because too many files changed in this diff