added allowedOrigins

This commit is contained in:
Caleb Gardner
2024-11-08 14:23:42 -06:00
parent 98adb3da39
commit 94633293f5
3 changed files with 27 additions and 17 deletions
+4 -1
View File
@@ -17,7 +17,10 @@ This is a purposefully "simple" application backend made specifically for _my_ a
crash: true, // crash reports crash: true, // crash reports
management: false, // managing management: false, // managing
// further permissions can be added as needed // further permissions can be added as needed
} },
allowedOrigins:[
"http://foo.bar" // Request with this origin header is considered to be under this key.
]
} }
``` ```
+21 -14
View File
@@ -3,6 +3,7 @@ package backend
import ( import (
"errors" "errors"
"fmt" "fmt"
"log"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@@ -16,10 +17,11 @@ var (
) )
type ApiKey struct { type ApiKey struct {
Perm map[string]bool `json:"perm" bson:"perm"` Perm map[string]bool `json:"perm" bson:"perm"`
ID string `json:"id" bson:"_id" valkey:",key"` ID string `json:"id" bson:"_id" valkey:",key"`
AppID string `json:"appID" bson:"appID"` AppID string `json:"appID" bson:"appID"`
Death int64 `json:"death" bson:"death"` Death int64 `json:"death" bson:"death"`
AllowedOrigins []string `json:"allowedOrigins" bson:"allowedOrigins"`
} }
func (k ApiKey) GetID() string { func (k ApiKey) GetID() string {
@@ -38,12 +40,6 @@ func (b *Backend) ParseHeader(r *http.Request) (*ParsedHeader, error) {
out := &ParsedHeader{} out := &ParsedHeader{}
key := r.Header.Get("X-API-Key") key := r.Header.Get("X-API-Key")
//TODO: Remove legacy code
if key == "" {
key = r.URL.Query().Get("key")
}
token := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
if key != "" { if key != "" {
apiKey, err := b.keyTable.Get(r.Context(), key) apiKey, err := b.keyTable.Get(r.Context(), key)
if err == ErrNotFound { if err == ErrNotFound {
@@ -55,7 +51,20 @@ func (b *Backend) ParseHeader(r *http.Request) (*ParsedHeader, error) {
return nil, ErrApiKeyUnauthorized return nil, ErrApiKeyUnauthorized
} }
out.Key = apiKey out.Key = apiKey
} else {
fmt.Println(r.Header.Get("origin"))
keys, err := b.keyTable.Find(r.Context(), map[string]any{"allowedOrigins": r.Header.Get("origin")})
if err == ErrNotFound {
return nil, ErrApiKeyUnauthorized
} else if err != nil {
return nil, err
}
if keys[0].Death > 0 && time.Unix(keys[0].Death, 0).Before(time.Now()) {
return nil, ErrApiKeyUnauthorized
}
out.Key = &keys[0]
} }
token := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
if token != "" && b.userTable != nil { if token != "" && b.userTable != nil {
t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) { t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
return b.jwtPub, nil return b.jwtPub, nil
@@ -104,14 +113,14 @@ func (b *Backend) VerifyHeader(w http.ResponseWriter, r *http.Request, keyPerm s
hdr, err := b.ParseHeader(r) hdr, err := b.ParseHeader(r)
if hdr == nil || hdr.Key == nil { if hdr == nil || hdr.Key == nil {
if err == ErrApiKeyUnauthorized { if err == ErrApiKeyUnauthorized {
fmt.Println("yo1")
ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application not authorized") ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application not authorized")
return nil, nil return nil, nil
} }
ReturnError(w, http.StatusInternalServerError, "internal", "Server error") ReturnError(w, http.StatusUnauthorized, "noKey", "No API Key provided")
return nil, err return nil, err
} }
if err != nil && !errors.Is(err, ErrTokenUnauthorized) { if err != nil && !errors.Is(err, ErrTokenUnauthorized) {
log.Println("error parsing header:", err)
ReturnError(w, http.StatusInternalServerError, "internal", "Server error") ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
return nil, err return nil, err
} }
@@ -119,13 +128,11 @@ func (b *Backend) VerifyHeader(w http.ResponseWriter, r *http.Request, keyPerm s
if allowManagementKey { if allowManagementKey {
return hdr, nil return hdr, nil
} else { } else {
fmt.Println("yo2")
ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application not authorized") ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application not authorized")
return nil, nil return nil, nil
} }
} }
if _, ok := b.apps[hdr.Key.AppID]; !ok { if _, ok := b.apps[hdr.Key.AppID]; !ok {
fmt.Println("yo3")
ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application not authorized") ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application not authorized")
return nil, errors.New("server misconfigured, appID present in DB, but App not added to backend") return nil, errors.New("server misconfigured, appID present in DB, but App not added to backend")
} }
+2 -2
View File
@@ -125,7 +125,7 @@ func setupBackend(mux *http.ServeMux) {
log.Println("error reading darkstorm user private key:", err) log.Println("error reading darkstorm user private key:", err)
goto here goto here
} }
back.AddUserAuth(db.NewMongoTable[backend.User](mongoClient.Database("darkstorm").Collection("users")), pub, priv) back.AddUserAuth(db.NewMongoTable[backend.User](mongoClient.Database("darkstorm").Collection("users")), priv, pub)
} else { } else {
back.AddCorsAddress("*") back.AddCorsAddress("*")
} }
@@ -180,7 +180,7 @@ func mainHandle(w http.ResponseWriter, r *http.Request) {
const loginScreen = ` const loginScreen = `
<script src="https://unpkg.com/htmx-ext-json-enc@2.0.1/json-enc.js"></script> <script src="https://unpkg.com/htmx-ext-json-enc@2.0.1/json-enc.js"></script>
<form id="loginForm" hx-ext='json-enc' hx-post="https://api.darkstorm.tech/users/login"> <form id="loginForm" onsubmit="login(event)">
<label for="username">Username:</label> <label for="username">Username:</label>
<input name="username" id="usernameInput"></input> <input name="username" id="usernameInput"></input>
<label for="password">Password:</label> <label for="password">Password:</label>