Incoming should be working, but I haven't tested it too much.

This commit is contained in:
Ben 2025-08-01 00:44:37 -07:00
parent d302f39719
commit 309b836931
Signed by: webmaster
GPG key ID: A5FCBAF34E6E8B50
8 changed files with 259 additions and 98 deletions

View file

@ -4,8 +4,10 @@ package auth
reading from a config file and matching requests to the whitelist. */
import (
"encoding/json"
"errors"
"os"
"reflect"
)
/* Stores a map between a string (bearer token) and a list of unmarshaled JSONS */
@ -21,8 +23,10 @@ func SetupAuthConfig(filePath string) (err error) {
if err != nil {return}
// Unmarshal
unmarshaled := UnmarshalJSON(fileContents);
if unmarshaled == nil {return errors.New("Invalid JSON object in config file!");}
var unmarshaled any;
if err := json.Unmarshal(fileContents, &unmarshaled); err != nil {
return errors.New("Invalid JSON object in config file!");
}
// Check type assertion for base JSON object
if _, ok := unmarshaled.(map[string]any); !ok {
@ -56,12 +60,74 @@ func Authenticate(bearer string, requestJSON []byte) bool {
if _, ok := authConfig[bearer]; !ok {return false;}
// Unmarshal JSON
unmarshaledRequest := UnmarshalJSON(requestJSON);
var unmarshaledRequest any;
if err := json.Unmarshal(requestJSON, &unmarshaledRequest); err != nil {
return false;
}
// Check for any object
for _, jsonObject := range authConfig[bearer] {
if match(unmarshaledRequest, jsonObject) {return true}
if Match(unmarshaledRequest, jsonObject) {return true}
}
return false;
}
/* Meat and bones of determining if a request is allowed by a filter */
func Match(request any, filter any) bool {
// Check that the types are the same
if reflect.TypeOf(request) != reflect.TypeOf(filter) {return false}
// Can safely switch on type of one object at this point since they're equal
switch filter.(type) {
// Key-value pairs
case map[string]any:
// Check for every key that's in the filter
for key := range filter.(map[string]any) {
// that it's in the request
if _, ok := request.(map[string]any)[key]; !ok {return false}
// And recursively check that the value is equal
if !Match(request.(map[string]any)[key], filter.(map[string]any)[key]) {
return false;
}
}
return true;
/* Arrays attempt to match every item in the filter to ANY item in the
request. Duplicates in the filter are treated as one */
case []any:
// Check that for every item in the filter
for i := 0; i < len(filter.([]any)); i ++ {
foundMatch := false;
// That something matches in the request
for j := 0; j < len(request.([]any)); j ++ {
if Match(filter.([]any)[i], request.([]any)[j]) {
foundMatch = true;
break
}
}
// Cannot find a match for something in the filter
if !foundMatch {return false}
}
// And the other way around
for i := 0; i < len(filter.([]any)); i ++ {
foundMatch := false;
// That something matches in the request
for j := 0; j < len(request.([]any)); j ++ {
if Match(filter.([]any)[i], request.([]any)[j]) {
foundMatch = true;
break
}
}
// Cannot find a match for something in the filter
if !foundMatch {return false}
}
return true;
// Otherwise compare the objects directly using reflect
default: return reflect.DeepEqual(request, filter);
}
}