123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- package libamuse
- import (
- "notabug.org/apiote/amuse/accounts"
- "bytes"
- "encoding/base32"
- "encoding/base64"
- "errors"
- "image"
- "strings"
- "github.com/chai2010/webp"
- "github.com/pquerna/otp"
- "github.com/pquerna/otp/totp"
- "notabug.org/apiote/gott"
- )
- func createSecret(args ...interface{}) (interface{}, error) {
- var (
- err error
- secretB []byte
- )
- result := args[1].(*Result)
- secret := args[4].(string)
- host := args[6].(string)
- if len(secret) > 0 {
- secretB, err = base32.StdEncoding.DecodeString(secret)
- }
- opts := totp.GenerateOpts{
- Issuer: host,
- AccountName: "nearly_headless_nick@" + host,
- Secret: secretB,
- }
- key, err := totp.Generate(opts)
- result.result = key
- return gott.Tuple(args), err
- }
- func createImage(args ...interface{}) (interface{}, error) {
- result := args[1].(*Result)
- secret := result.result.(*otp.Key)
- image, err := secret.Image(256, 256)
- result.result2 = image
- return gott.Tuple(args), err
- }
- func encodeWebp(args ...interface{}) (interface{}, error) {
- result := args[1].(*Result)
- image := result.result2.(image.Image)
- var buf bytes.Buffer
- err := webp.Encode(&buf, image, &webp.Options{Lossless: true})
- data := "data:image/webp;base64,"
- data += base64.StdEncoding.EncodeToString(buf.Bytes())
- result.result2 = data
- return gott.Tuple(args), err
- }
- func renderSignup(args ...interface{}) interface{} {
- result := args[1].(*Result)
- secret := result.result.(*otp.Key)
- qr := result.result2.(string)
- sfaEnabled := args[3].(bool)
- username := args[5].(string)
- var authError error
- if args[2] != nil {
- authError = args[2].(error)
- }
- result.page = result.renderer.RenderSignup(result.languages, authError, secret, sfaEnabled, username, qr)
- return gott.Tuple(args)
- }
- func ShowSignup(acceptLanguages, mimetype string, err error, sfaEnabled bool, sfaSecret, username, host string) (string, error) {
- r, err := gott.
- NewResult(gott.Tuple{&RequestData{language: acceptLanguages, mimetype: mimetype}, &Result{}, err, sfaEnabled, sfaSecret, username, host}).
- Bind(parseLanguage).
- Bind(createSecret).
- Bind(createImage).
- Bind(encodeWebp).
- Bind(createRenderer).
- Map(renderSignup).
- Finish()
- if err != nil {
- return "", err
- } else {
- return r.(gott.Tuple)[1].(*Result).page, nil
- }
- }
- func DoSignup(username, password, passwordConfirm string, sfaEnabled bool, sfaSecret, sfa string) (string, error) {
- if password != passwordConfirm {
- return "", accounts.AuthError{
- Err: errors.New("passwords_dont_match"),
- }
- }
- if sfaEnabled {
- if sfa == "" {
- return "", accounts.AuthError{
- Err: errors.New("sfa_not_confirmed"),
- }
- }
- sfa = strings.ReplaceAll(sfa, " ", "")
- if !totp.Validate(sfa, sfaSecret) {
- return "", accounts.AuthError{
- Err: errors.New("sfa_code_not_correct"),
- }
- }
- }
- if username == "" || password == "" || sfaSecret == "" {
- return "", accounts.AuthError{
- Err: errors.New("required_info_missing"),
- }
- }
- if !sfaEnabled {
- sfaSecret = ""
- }
- return accounts.Signup(username, password, sfaSecret)
- }
- func renderSignedup(args ...interface{}) interface{} {
- result := args[1].(*Result)
- recoveryCodes := args[2].(string)
- codes := []string{}
- if recoveryCodes != "" {
- codes = strings.Split(recoveryCodes, ",")
- }
- result.page = result.renderer.RenderSignedup(result.languages, codes)
- return gott.Tuple(args)
- }
- func ShowSignedup(acceptLanguages, mimetype, recoveryCodes string) (string, error) {
- r, err := gott.
- NewResult(gott.Tuple{&RequestData{language: acceptLanguages, mimetype: mimetype}, &Result{}, recoveryCodes}).
- Bind(parseLanguage).
- Bind(createRenderer).
- Map(renderSignedup).
- Finish()
- if err != nil {
- return "", err
- } else {
- return r.(gott.Tuple)[1].(*Result).page, nil
- }
- }
|