diff --git a/README.md b/README.md index e38af1f..2fd7c51 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,15 @@ Example input JSON format: -d '{"Name":"Alice","Password":"Lewis","ToModify":"Bill","Command":"admin"}' {"Status":"ok"} +### Purge + +Purge deletes all delegates for an encryption key. + +Example input JSON format: + + $ curl --cacert cert/server.crt https://localhost:8080/purge \ + -d '{"Name":"Alice","Password":"Lewis"}' + {"Status":"ok"} ### Web interface diff --git a/client/client.go b/client/client.go index 22609ae..2b843bc 100644 --- a/client/client.go +++ b/client/client.go @@ -144,6 +144,21 @@ func (c *RemoteServer) Delegate(req core.DelegateRequest) (*core.ResponseData, e return unmarshalResponseData(respBytes) } +// Purge issues a purge request to the remote server +func (c *RemoteServer) Purge(req core.DelegateRequest) (*core.ResponseData, error) { + reqBytes, err := json.Marshal(req) + if err != nil { + return nil, err + } + + respBytes, err := c.doAction("purge", reqBytes) + if err != nil { + return nil, err + } + + return unmarshalResponseData(respBytes) +} + // Modify issues a modify request to the remote server func (c *RemoteServer) Modify(req core.ModifyRequest) (*core.ResponseData, error) { reqBytes, err := json.Marshal(req) diff --git a/core/core.go b/core/core.go index 4d91719..2a5ab3c 100644 --- a/core/core.go +++ b/core/core.go @@ -36,6 +36,11 @@ type SummaryRequest struct { Password string } +type PurgeRequest struct { + Name string + Password string +} + type DelegateRequest struct { Name string Password string @@ -251,6 +256,37 @@ func Summary(jsonIn []byte) ([]byte, error) { return jsonSummary() } +// Purge processes a delegation purge request. +func Purge(jsonIn []byte) ([]byte, error) { + var s PurgeRequest + var err error + + defer func() { + if err != nil { + log.Printf("core.purge failed: user=%s %v", s.Name, err) + } else { + log.Printf("core.purge success: user=%s", s.Name) + } + }() + + if err = json.Unmarshal(jsonIn, &s); err != nil { + return jsonStatusError(err) + } + + if records.NumRecords() == 0 { + err = errors.New("vault has not been created") + return jsonStatusError(err) + } + + // Validate the Name and Password as valid and admin + if err = validateUser(s.Name, s.Password, true); err != nil { + return jsonStatusError(err) + } + + cache.FlushCache() + return jsonStatusOk() +} + // Delegate processes a delegation request. func Delegate(jsonIn []byte) ([]byte, error) { var s DelegateRequest diff --git a/core/core_test.go b/core/core_test.go index fb5f7ec..e665d18 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -7,8 +7,8 @@ package core import ( "bytes" "encoding/json" - "reflect" "os" + "reflect" "sort" "testing" @@ -161,6 +161,58 @@ func TestSummary(t *testing.T) { if dataLive.Type != passvault.DefaultRecordType { t.Fatalf("Error in summary of account, record missing") } + + var s1 SummaryData + delegations := cache.GetSummary() + if len(delegations) == 0 { + t.Fatal("no delegations active") + } + + // check for summary of initialized vault without non-admin members after purge + respJson, err = Purge(createJson) + if err != nil { + t.Fatalf("Error in purging, %v", err) + } + err = json.Unmarshal(respJson, &s1) + if err != nil { + t.Fatalf("Error in purging, %v", err) + } + if s.Status != "ok" { + t.Fatalf("Error in purging, %v", s.Status) + } + + respJson, err = Summary(createJson) + if err != nil { + t.Fatalf("Error in summary of account with no vault, %v", err) + } + err = json.Unmarshal(respJson, &s1) + if err != nil { + t.Fatalf("Error in summary of account with no vault, %v", err) + } + if s.Status != "ok" { + t.Fatalf("Error in summary of account with no vault, %v", s.Status) + } + + data, ok = s1.All["Alice"] + if !ok { + t.Fatalf("Error in summary of account, record missing") + } + if data.Admin != true { + t.Fatalf("Error in summary of account, record missing") + } + if data.Type != passvault.DefaultRecordType { + t.Fatalf("Error in summary of account, record missing") + } + + _, ok = s1.All["Bob"] + if !ok { + t.Fatal("Bob was removed from the list of users") + } + + delegations = cache.GetSummary() + if len(delegations) != 0 { + t.Fatalf("purge failed to clear delegations (%d delegations remain)", len(delegations)) + } } func TestPassword(t *testing.T) { diff --git a/redoctober.go b/redoctober.go index defb717..d2b9d3a 100644 --- a/redoctober.go +++ b/redoctober.go @@ -29,6 +29,7 @@ import ( var functions = map[string]func([]byte) ([]byte, error){ "/create": core.Create, "/summary": core.Summary, + "/purge": core.Purge, "/delegate": core.Delegate, "/password": core.Password, "/encrypt": core.Encrypt,