diff --git a/README.md b/README.md index 466d840..0e91fbd 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,12 @@ groot [-r | --register-client client_name] [-c | --check-registration token] [-u -u | --unsecured > runs groot without the security layer +-l | --list-clients +> lists all registered client names + +-d | --delete-client *client_name* +> deletes the client token with the given name + *without args* > runs groot with the security layer diff --git a/security/clients.go b/security/clients.go index 841e3c5..73ccca2 100644 --- a/security/clients.go +++ b/security/clients.go @@ -47,6 +47,18 @@ func IsAuthorizedClient(token string) (bool, error) { return true, nil } -func RemoveClient(token string) error { - return nil +func DeleteClient(name string) error { + return clientRegistry.delete([]byte(name)) +} + +func ListClients() ([]string, error) { + clients, err := clientRegistry.list() + if err != nil { + return []string{}, err + } + names := make([]string, len(clients)) + for i := 0; i < len(clients); i++ { + names[i] = string(clients[i]) + } + return names, nil } diff --git a/security/db_connector.go b/security/db_connector.go index 365e5b7..f08119d 100644 --- a/security/db_connector.go +++ b/security/db_connector.go @@ -13,6 +13,8 @@ package security import ( "fmt" "log" + "reflect" + "errors" "github.com/acm-uiuc/arbor/logger" "github.com/syndtr/goleveldb/leveldb" @@ -46,9 +48,43 @@ func (c *levelDBConnector) get(k []byte) ([]byte, error) { return v, err } -func (c *levelDBConnector) delete(k []byte) error { - err := c.store.Delete(k, nil) - return err +func (c *levelDBConnector) delete(v []byte) error { + var err error + iter := c.store.NewIterator(nil, nil) + found := false + for iter.Next() { + currVal := iter.Value() + if reflect.DeepEqual(currVal, v) { + err = c.store.Delete(iter.Key(), nil) + if err != nil { + fmt.Println(err) + logger.Log(logger.FATAL, err.Error()) + } + found = true + } + } + iter.Release() + err = iter.Error() + if err != nil { + return err + } else if found == false { + return errors.New("No such value") + } + return nil +} + +func (c *levelDBConnector) list() ([][]byte, error) { + iter := c.store.NewIterator(nil, nil) + values := make([][]byte, 0) + for iter.Next() { + v := iter.Value() + c := make([]byte, len(v)) + copy(c, v) + values = append(values, c) + } + iter.Release() + err := iter.Error() + return values, err } func (c *levelDBConnector) close() { diff --git a/server.go b/server.go index 6e6fe00..b3b3c1e 100644 --- a/server.go +++ b/server.go @@ -13,6 +13,7 @@ package arbor import ( "fmt" "os" + "strings" "github.com/acm-uiuc/arbor/logger" "github.com/acm-uiuc/arbor/security" @@ -40,6 +41,12 @@ const help = `Usage: executable [-r | --register-client client_name] [-c | --che // -u | --unsecured // runs arbor without the security layer // +// -l | --list-clients +// lists all registered client names +// +// -d | --delete-client client_name +// deletes the client token with the given name +// // without args // runs arbor with the security layer // @@ -50,6 +57,10 @@ func Boot(routes RouteCollection, port uint16) *server.ArborServer { RegisterClient(os.Args[2]) } else if len(os.Args) == 3 && (os.Args[1] == "--check-registration" || os.Args[1] == "-c") { CheckRegistration(os.Args[2]) + } else if len(os.Args) == 3 && (os.Args[1] == "--delete-client" || os.Args[1] == "-d") { + DeleteClient(os.Args[2]) + } else if len(os.Args) == 2 && (os.Args[1] == "--list-clients" || os.Args[1] == "-l") { + ListClients() } else if len(os.Args) == 2 && (os.Args[1] == "--unsecured" || os.Args[1] == "-u") { logger.Log(logger.WARN, "Starting Arbor in unsecured mode") srv = server.StartUnsecuredServer(routes.toServiceRoutes(), port) @@ -84,3 +95,25 @@ func CheckRegistration(token string) { fmt.Println(security.IsAuthorizedClient(token)) defer security.Shutdown() } + +func ListClients() { + security.Init() + names, _ := security.ListClients() + if len(names) == 0 { + logger.Log(logger.SPEC, "No registered clients") + } else { + logger.Log(logger.SPEC, "Known clients: \n- "+strings.Join(names, "\n- ")) + } + defer security.Shutdown() +} + +func DeleteClient(name string) { + security.Init() + err := security.DeleteClient(name) + if err != nil { + logger.Log(logger.ERR, err.Error()) + return + } + logger.Log(logger.SPEC, "Client "+name+" has been deleted.") + defer security.Shutdown() +}