101 lines
2.2 KiB
Go
101 lines
2.2 KiB
Go
package auth
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"local/dndex/storage"
|
|
"local/dndex/storage/entity"
|
|
"net/http"
|
|
|
|
"github.com/google/uuid"
|
|
"gopkg.in/mgo.v2/bson"
|
|
)
|
|
|
|
func GeneratePlain(g storage.RateLimitedGraph, r *http.Request) (string, error) {
|
|
token, _, err := generateToken(g, r)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return token.Obfuscate()
|
|
}
|
|
|
|
func Generate(g storage.RateLimitedGraph, r *http.Request, salt string) (string, error) {
|
|
token, key, err := generateToken(g, r)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return token.Encode(salt + key)
|
|
}
|
|
|
|
func generateToken(g storage.RateLimitedGraph, r *http.Request) (Token, string, error) {
|
|
namespaceRequested := readRequestedNamespace(r)
|
|
if namespaceRequested == "" {
|
|
return Token{}, "", errors.New("no namespace found")
|
|
}
|
|
key, err := getKeyForNamespace(r.Context(), g, namespaceRequested)
|
|
if err != nil {
|
|
return Token{}, "", err
|
|
}
|
|
token, err := makeTokenForNamespace(r.Context(), g, namespaceRequested)
|
|
if err != nil {
|
|
return Token{}, "", err
|
|
}
|
|
return token, key, nil
|
|
}
|
|
|
|
func readRequestedNamespace(r *http.Request) string {
|
|
return readRequested(r, UserKey)
|
|
}
|
|
|
|
func readRequested(r *http.Request, key string) string {
|
|
switch r.Header.Get("Content-Type") {
|
|
case "application/json":
|
|
b, _ := ioutil.ReadAll(r.Body)
|
|
r.Body = struct {
|
|
io.Reader
|
|
io.Closer
|
|
}{
|
|
Reader: bytes.NewReader(b),
|
|
Closer: r.Body,
|
|
}
|
|
m := bson.M{}
|
|
json.Unmarshal(b, &m)
|
|
v, ok := m[key]
|
|
if !ok {
|
|
return ""
|
|
}
|
|
return fmt.Sprint(v)
|
|
default:
|
|
return r.FormValue(key)
|
|
}
|
|
}
|
|
|
|
func getKeyForNamespace(ctx context.Context, g storage.RateLimitedGraph, namespace string) (string, error) {
|
|
namespaceOne, err := g.Get(ctx, toAuthNamespace(namespace), UserKey)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return namespaceOne.Title, nil
|
|
}
|
|
|
|
func makeTokenForNamespace(ctx context.Context, g storage.RateLimitedGraph, namespace string) (Token, error) {
|
|
token := Token{
|
|
Namespace: namespace,
|
|
ID: uuid.New().String(),
|
|
}
|
|
obf, err := token.Obfuscate()
|
|
if err != nil {
|
|
return Token{}, err
|
|
}
|
|
one := entity.One{
|
|
ID: token.ID,
|
|
Title: obf,
|
|
}
|
|
return token, g.Insert(ctx, toAuthNamespace(namespace), one)
|
|
}
|