Skip to content

Commit

Permalink
storage: persist API server URL alongisde Account details (#14)
Browse files Browse the repository at this point in the history
This commit adds the functionality that stores the acme-dns API URL alongisde of the rest of the account information. The account information is dependant of the API server in question, so at least for me it makes sense.

The new functionality allows the storage to be self sufficient for all the required data points. While the API server URL can often be deducted from the account URL, it's not guaranteed.

This commit also adds a test to ensure backwards compatibility with old storage format and to mitigate potential regressions in the backwards compatibility in the future.
  • Loading branch information
joohoi authored Jan 5, 2021
1 parent 41bdb34 commit 7454267
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
3 changes: 3 additions & 0 deletions account.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ type Account struct {
SubDomain string `json:"subdomain"`
Username string `json:"username"`
Password string `json:"password"`
// ServerURL contains the URL of the acme-dns server the Account was registered with
// (may be empty for Account instances registered before this field was added).
ServerURL string `json:"server_url"`
}
2 changes: 2 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ func (c Client) RegisterAccount(allowFrom []string) (Account, error) {
return Account{}, fmt.Errorf("Failed to unmarshal account: %w", err)
}

acct.ServerURL = c.baseURL

return acct, nil
}

Expand Down
2 changes: 2 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ func TestRegisterAccount(t *testing.T) {
t.Errorf("expected err %#v, got %#v\n", tc.ExpectedErr, err)
}
} else if tc.ExpectedErr == nil && err == nil {
// Needed to be able to assert equivalence, as the server addr is dynamic
tc.ExpectedAccount.ServerURL = acct.ServerURL
if !reflect.DeepEqual(acct, *tc.ExpectedAccount) {
t.Errorf("expected account %v, got %v\n", tc.ExpectedAccount, acct)
}
Expand Down
71 changes: 71 additions & 0 deletions storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,18 @@ var testAccounts = map[string]Account{
SubDomain: "tossed.lettuceencrypt.org",
Username: "cpu",
Password: "hunter2",
ServerURL: "https://auth.acme-dns.io",
},
"threeletter.agency": {
FullDomain: "threeletter.agency",
SubDomain: "jobs.threeletter.agency",
Username: "spooky.mulder",
Password: "trustno1",
ServerURL: "https://example.org",
},
}

var testLegacyAccount = map[string]Account{
"threeletter.agency": {
FullDomain: "threeletter.agency",
SubDomain: "jobs.threeletter.agency",
Expand Down Expand Up @@ -79,6 +90,66 @@ func TestNewFileStorage(t *testing.T) {
}
}

func TestNewFileStorageWithLegacyData(t *testing.T) {
mode := os.FileMode(0600)

var (
legacyAcct, testAcct Account
found bool
)

testData, err := json.Marshal(testLegacyAccount)
if err != nil {
t.Fatalf("unexpected error marshaling testAccounts: %v", err)
}

f, err := ioutil.TempFile("", "legacy.account")
if err != nil {
t.Errorf("unexpected error creating tempfile: %v", err)
}

defer func() { _ = f.Close() }()

_, err = f.Write(testData)
if err != nil {
t.Errorf("unexpected error writing to tempfile: %v", err)
}

storage := NewFileStorage(f.Name(), mode)

fs, ok := storage.(fileStorage)
if !ok {
t.Fatalf("expected fileStorage instance from NewFileStorage, got %T", storage)
}

if fs.accounts == nil {
t.Fatalf("expected accounts to be not-nil, was nil")
}

if len(fs.accounts) != 1 {
t.Fatalf("expected a single account in the map, got %d", len(fs.accounts))
}

if legacyAcct, found = fs.accounts["threeletter.agency"]; !found {
t.Fatalf("expected to find account but was unable to")
}

if legacyAcct.ServerURL != "" {
t.Errorf("expected empty Server string from legacy account, but got %s", legacyAcct.ServerURL)
}

if testAcct, found = testAccounts["threeletter.agency"]; !found {
t.Fatalf("expected to find test account for threeletter.agency, but was unable to")
}

// set the missing value for legacy account to be able to evaluate equivalence
legacyAcct.ServerURL = testAcct.ServerURL

if !reflect.DeepEqual(legacyAcct, testAcct) {
t.Errorf("expected equivalent test and legacy accounts")
}
}

func TestFileStorageSave(t *testing.T) {
f, err := ioutil.TempFile("", "acmedns.account")

Expand Down

0 comments on commit 7454267

Please sign in to comment.