initial commit
This commit is contained in:
commit
f48fa210bb
49 changed files with 4058 additions and 0 deletions
77
pkg/otp/otp.go
Normal file
77
pkg/otp/otp.go
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (C) 2022 Marius Schellenberger
|
||||
|
||||
package otp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"html/template"
|
||||
"image/png"
|
||||
|
||||
"github.com/pquerna/otp"
|
||||
"github.com/pquerna/otp/totp"
|
||||
)
|
||||
|
||||
const size = 200
|
||||
|
||||
func base64Image(key *otp.Key) (data template.URL, err error) {
|
||||
var buf bytes.Buffer
|
||||
img, err := key.Image(size, size)
|
||||
if err != nil {
|
||||
err = errors.New("otp: " + err.Error())
|
||||
return
|
||||
}
|
||||
err = png.Encode(&buf, img)
|
||||
if err != nil {
|
||||
err = errors.New("otp: " + err.Error())
|
||||
return
|
||||
}
|
||||
data = template.URL("data:image/png;base64," + base64.StdEncoding.EncodeToString(buf.Bytes()))
|
||||
return
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
Username string
|
||||
Image template.URL
|
||||
Secret string
|
||||
URL string
|
||||
}
|
||||
|
||||
func New(username, issuer string) (req Request, err error) {
|
||||
key, err := totp.Generate(totp.GenerateOpts{
|
||||
Issuer: issuer,
|
||||
AccountName: username,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
data, err := base64Image(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return Request{
|
||||
Username: username,
|
||||
Image: data,
|
||||
Secret: key.Secret(),
|
||||
URL: key.URL(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func Validate(pin, secret string) bool {
|
||||
if secret == "" {
|
||||
return true
|
||||
}
|
||||
return totp.Validate(pin, secret)
|
||||
}
|
||||
|
||||
func ImageSecretFromURL(url string) (data template.URL, secret string, err error) {
|
||||
key, err := otp.NewKeyFromURL(url)
|
||||
if err != nil {
|
||||
err = errors.New("otp: " + err.Error())
|
||||
return
|
||||
}
|
||||
secret = key.Secret()
|
||||
data, err = base64Image(key)
|
||||
return
|
||||
}
|
||||
25
pkg/otp/otp_test.go
Normal file
25
pkg/otp/otp_test.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (C) 2022 Marius Schellenberger
|
||||
|
||||
package otp
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
_, err := New("admin", "example.com")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageSecretFromURL(t *testing.T) {
|
||||
r, _ := New("admin", "example.com")
|
||||
_, secret, err := ImageSecretFromURL(r.URL)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if secret != r.Secret {
|
||||
t.Error("secret is not equal")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue