Incoming should be working, but I haven't tested it too much.
This commit is contained in:
parent
d302f39719
commit
309b836931
8 changed files with 259 additions and 98 deletions
74
auth/auth.go
74
auth/auth.go
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue