2018-12-11 02:59:03 +10:00
|
|
|
// Copyright 2015 Matthew Holt
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package certmagic
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2022-03-08 05:26:52 +10:00
|
|
|
"context"
|
2024-04-19 05:42:33 +10:00
|
|
|
"io/fs"
|
2019-01-22 04:31:57 +10:00
|
|
|
"os"
|
2018-12-11 02:59:03 +10:00
|
|
|
"path/filepath"
|
2020-07-28 08:50:41 +10:00
|
|
|
"reflect"
|
2018-12-11 02:59:03 +10:00
|
|
|
"strings"
|
2022-08-02 15:04:11 +10:00
|
|
|
"sync"
|
2018-12-11 02:59:03 +10:00
|
|
|
"testing"
|
|
|
|
"time"
|
2024-06-04 13:55:10 +10:00
|
|
|
|
|
|
|
"go.uber.org/zap"
|
2018-12-11 02:59:03 +10:00
|
|
|
)
|
|
|
|
|
2024-04-19 05:42:33 +10:00
|
|
|
// memoryStorage is an in-memory storage implementation with known contents *and* fixed iteration order for List.
|
|
|
|
type memoryStorage struct {
|
|
|
|
contents []memoryStorageItem
|
|
|
|
}
|
|
|
|
|
|
|
|
type memoryStorageItem struct {
|
|
|
|
key string
|
|
|
|
data []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *memoryStorage) lookup(_ context.Context, key string) *memoryStorageItem {
|
|
|
|
for _, item := range m.contents {
|
|
|
|
if item.key == key {
|
|
|
|
return &item
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func (m *memoryStorage) Delete(ctx context.Context, key string) error {
|
|
|
|
for i, item := range m.contents {
|
|
|
|
if item.key == key {
|
|
|
|
m.contents = append(m.contents[:i], m.contents[i+1:]...)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fs.ErrNotExist
|
|
|
|
}
|
|
|
|
func (m *memoryStorage) Store(ctx context.Context, key string, value []byte) error {
|
|
|
|
m.contents = append(m.contents, memoryStorageItem{key: key, data: value})
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func (m *memoryStorage) Exists(ctx context.Context, key string) bool {
|
|
|
|
return m.lookup(ctx, key) != nil
|
|
|
|
}
|
|
|
|
func (m *memoryStorage) List(ctx context.Context, path string, recursive bool) ([]string, error) {
|
|
|
|
if recursive {
|
|
|
|
panic("unimplemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
result := []string{}
|
|
|
|
nextitem:
|
|
|
|
for _, item := range m.contents {
|
|
|
|
if !strings.HasPrefix(item.key, path+"/") {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
name := strings.TrimPrefix(item.key, path+"/")
|
|
|
|
if i := strings.Index(name, "/"); i >= 0 {
|
|
|
|
name = name[:i]
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, existing := range result {
|
|
|
|
if existing == name {
|
|
|
|
continue nextitem
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result = append(result, name)
|
|
|
|
}
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
func (m *memoryStorage) Load(ctx context.Context, key string) ([]byte, error) {
|
|
|
|
if item := m.lookup(ctx, key); item != nil {
|
|
|
|
return item.data, nil
|
|
|
|
}
|
|
|
|
return nil, fs.ErrNotExist
|
|
|
|
}
|
|
|
|
func (m *memoryStorage) Stat(ctx context.Context, key string) (KeyInfo, error) {
|
|
|
|
if item := m.lookup(ctx, key); item != nil {
|
|
|
|
return KeyInfo{Key: key, Size: int64(len(item.data))}, nil
|
|
|
|
}
|
|
|
|
return KeyInfo{}, fs.ErrNotExist
|
|
|
|
}
|
|
|
|
func (m *memoryStorage) Lock(ctx context.Context, name string) error { panic("unimplemented") }
|
|
|
|
func (m *memoryStorage) Unlock(ctx context.Context, name string) error { panic("unimplemented") }
|
|
|
|
|
|
|
|
var _ Storage = (*memoryStorage)(nil)
|
|
|
|
|
|
|
|
type recordingStorage struct {
|
|
|
|
Storage
|
|
|
|
calls []recordedCall
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *recordingStorage) Delete(ctx context.Context, key string) error {
|
|
|
|
r.record("Delete", key)
|
|
|
|
return r.Storage.Delete(ctx, key)
|
|
|
|
}
|
|
|
|
func (r *recordingStorage) Exists(ctx context.Context, key string) bool {
|
|
|
|
r.record("Exists", key)
|
|
|
|
return r.Storage.Exists(ctx, key)
|
|
|
|
}
|
|
|
|
func (r *recordingStorage) List(ctx context.Context, path string, recursive bool) ([]string, error) {
|
|
|
|
r.record("List", path, recursive)
|
|
|
|
return r.Storage.List(ctx, path, recursive)
|
|
|
|
}
|
|
|
|
func (r *recordingStorage) Load(ctx context.Context, key string) ([]byte, error) {
|
|
|
|
r.record("Load", key)
|
|
|
|
return r.Storage.Load(ctx, key)
|
|
|
|
}
|
|
|
|
func (r *recordingStorage) Lock(ctx context.Context, name string) error {
|
|
|
|
r.record("Lock", name)
|
|
|
|
return r.Storage.Lock(ctx, name)
|
|
|
|
}
|
|
|
|
func (r *recordingStorage) Stat(ctx context.Context, key string) (KeyInfo, error) {
|
|
|
|
r.record("Stat", key)
|
|
|
|
return r.Storage.Stat(ctx, key)
|
|
|
|
}
|
|
|
|
func (r *recordingStorage) Store(ctx context.Context, key string, value []byte) error {
|
|
|
|
r.record("Store", key)
|
|
|
|
return r.Storage.Store(ctx, key, value)
|
|
|
|
}
|
|
|
|
func (r *recordingStorage) Unlock(ctx context.Context, name string) error {
|
|
|
|
r.record("Unlock", name)
|
|
|
|
return r.Storage.Unlock(ctx, name)
|
|
|
|
}
|
|
|
|
|
|
|
|
type recordedCall struct {
|
|
|
|
name string
|
|
|
|
args []interface{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *recordingStorage) record(name string, args ...interface{}) {
|
|
|
|
r.calls = append(r.calls, recordedCall{name: name, args: args})
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ Storage = (*recordingStorage)(nil)
|
|
|
|
|
2020-07-28 08:50:41 +10:00
|
|
|
func TestNewAccount(t *testing.T) {
|
2024-06-04 13:55:10 +10:00
|
|
|
am := &ACMEIssuer{CA: dummyCA, Logger: zap.NewNop(), mu: new(sync.Mutex)}
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testConfig := &Config{
|
2020-11-17 03:53:41 +10:00
|
|
|
Issuers: []Issuer{am},
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
Storage: &FileStorage{Path: "./_testdata_tmp"},
|
2022-09-27 02:19:28 +10:00
|
|
|
Logger: defaultTestLogger,
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
certCache: new(Cache),
|
|
|
|
}
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
am.config = testConfig
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
|
2018-12-11 02:59:03 +10:00
|
|
|
email := "me@foobar.com"
|
2020-07-28 08:50:41 +10:00
|
|
|
account, err := am.newAccount(email)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2020-07-28 08:50:41 +10:00
|
|
|
t.Fatalf("Error creating account: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
2020-07-28 08:50:41 +10:00
|
|
|
if account.PrivateKey == nil {
|
2018-12-11 02:59:03 +10:00
|
|
|
t.Error("Private key is nil")
|
|
|
|
}
|
2020-07-28 08:50:41 +10:00
|
|
|
if account.Contact[0] != "mailto:"+email {
|
|
|
|
t.Errorf("Expected email to be %s, but was %s", email, account.Contact[0])
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
2020-07-28 08:50:41 +10:00
|
|
|
if account.Status != "" {
|
|
|
|
t.Error("New account already has a status; it shouldn't")
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-28 08:50:41 +10:00
|
|
|
func TestSaveAccount(t *testing.T) {
|
2022-03-08 05:26:52 +10:00
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-06-04 13:55:10 +10:00
|
|
|
am := &ACMEIssuer{CA: dummyCA, Logger: zap.NewNop(), mu: new(sync.Mutex)}
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testConfig := &Config{
|
2020-11-17 03:53:41 +10:00
|
|
|
Issuers: []Issuer{am},
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
Storage: &FileStorage{Path: "./_testdata1_tmp"},
|
2022-09-27 02:19:28 +10:00
|
|
|
Logger: defaultTestLogger,
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
certCache: new(Cache),
|
|
|
|
}
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
am.config = testConfig
|
|
|
|
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testStorageDir := testConfig.Storage.(*FileStorage).Path
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
defer func() {
|
|
|
|
err := os.RemoveAll(testStorageDir)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not remove temporary storage directory (%s): %v", testStorageDir, err)
|
|
|
|
}
|
|
|
|
}()
|
2018-12-11 02:59:03 +10:00
|
|
|
|
|
|
|
email := "me@foobar.com"
|
2020-07-28 08:50:41 +10:00
|
|
|
account, err := am.newAccount(email)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2020-07-28 08:50:41 +10:00
|
|
|
t.Fatalf("Error creating account: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
|
|
|
|
2022-03-08 05:26:52 +10:00
|
|
|
err = am.saveAccount(ctx, am.CA, account)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2020-07-28 08:50:41 +10:00
|
|
|
t.Fatalf("Error saving account: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
2022-03-08 05:26:52 +10:00
|
|
|
_, err = am.getAccount(ctx, am.CA, email)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2020-07-28 08:50:41 +10:00
|
|
|
t.Errorf("Cannot access account data, error: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-28 08:50:41 +10:00
|
|
|
func TestGetAccountDoesNotAlreadyExist(t *testing.T) {
|
2022-03-08 05:26:52 +10:00
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-06-04 13:55:10 +10:00
|
|
|
am := &ACMEIssuer{CA: dummyCA, Logger: zap.NewNop(), mu: new(sync.Mutex)}
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testConfig := &Config{
|
2020-11-17 03:53:41 +10:00
|
|
|
Issuers: []Issuer{am},
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
Storage: &FileStorage{Path: "./_testdata_tmp"},
|
2022-09-27 02:19:28 +10:00
|
|
|
Logger: defaultTestLogger,
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
certCache: new(Cache),
|
|
|
|
}
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
am.config = testConfig
|
2018-12-11 02:59:03 +10:00
|
|
|
|
2022-03-08 05:26:52 +10:00
|
|
|
account, err := am.getAccount(ctx, am.CA, "account_does_not_exist@foobar.com")
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2020-07-28 08:50:41 +10:00
|
|
|
t.Fatalf("Error getting account: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
|
|
|
|
2020-07-28 08:50:41 +10:00
|
|
|
if account.PrivateKey == nil {
|
|
|
|
t.Error("Expected account to have a private key, but it was nil")
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-28 08:50:41 +10:00
|
|
|
func TestGetAccountAlreadyExists(t *testing.T) {
|
2022-03-08 05:26:52 +10:00
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-06-04 13:55:10 +10:00
|
|
|
am := &ACMEIssuer{CA: dummyCA, Logger: zap.NewNop(), mu: new(sync.Mutex)}
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testConfig := &Config{
|
2020-11-17 03:53:41 +10:00
|
|
|
Issuers: []Issuer{am},
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
Storage: &FileStorage{Path: "./_testdata2_tmp"},
|
2022-09-27 02:19:28 +10:00
|
|
|
Logger: defaultTestLogger,
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
certCache: new(Cache),
|
|
|
|
}
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
am.config = testConfig
|
|
|
|
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testStorageDir := testConfig.Storage.(*FileStorage).Path
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
defer func() {
|
|
|
|
err := os.RemoveAll(testStorageDir)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not remove temporary storage directory (%s): %v", testStorageDir, err)
|
|
|
|
}
|
|
|
|
}()
|
2018-12-11 02:59:03 +10:00
|
|
|
|
|
|
|
email := "me@foobar.com"
|
|
|
|
|
|
|
|
// Set up test
|
2020-07-28 08:50:41 +10:00
|
|
|
account, err := am.newAccount(email)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2020-07-28 08:50:41 +10:00
|
|
|
t.Fatalf("Error creating account: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
2022-03-08 05:26:52 +10:00
|
|
|
err = am.saveAccount(ctx, am.CA, account)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2020-07-28 08:50:41 +10:00
|
|
|
t.Fatalf("Error saving account: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
|
|
|
|
2020-07-28 08:50:41 +10:00
|
|
|
// Expect to load account from disk
|
2022-03-08 05:26:52 +10:00
|
|
|
loadedAccount, err := am.getAccount(ctx, am.CA, email)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2020-07-28 08:50:41 +10:00
|
|
|
t.Fatalf("Error getting account: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Assert keys are the same
|
2020-07-28 08:50:41 +10:00
|
|
|
if !privateKeysSame(account.PrivateKey, loadedAccount.PrivateKey) {
|
2018-12-11 02:59:03 +10:00
|
|
|
t.Error("Expected private key to be the same after loading, but it wasn't")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assert emails are the same
|
2020-07-28 08:50:41 +10:00
|
|
|
if !reflect.DeepEqual(account.Contact, loadedAccount.Contact) {
|
|
|
|
t.Errorf("Expected contacts to be equal, but was '%s' before and '%s' after loading", account.Contact, loadedAccount.Contact)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-19 05:42:33 +10:00
|
|
|
func TestGetAccountAlreadyExistsSkipsBroken(t *testing.T) {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-06-04 13:55:10 +10:00
|
|
|
am := &ACMEIssuer{CA: dummyCA, Logger: zap.NewNop(), mu: new(sync.Mutex)}
|
2024-04-19 05:42:33 +10:00
|
|
|
testConfig := &Config{
|
|
|
|
Issuers: []Issuer{am},
|
|
|
|
Storage: &memoryStorage{},
|
|
|
|
Logger: defaultTestLogger,
|
|
|
|
certCache: new(Cache),
|
|
|
|
}
|
|
|
|
am.config = testConfig
|
|
|
|
|
|
|
|
email := "me@foobar.com"
|
|
|
|
|
|
|
|
// Create a "corrupted" account
|
|
|
|
am.config.Storage.Store(ctx, am.storageKeyUserReg(am.CA, "notmeatall@foobar.com"), []byte("this is not a valid account"))
|
|
|
|
|
|
|
|
// Create the actual account
|
|
|
|
account, err := am.newAccount(email)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error creating account: %v", err)
|
|
|
|
}
|
|
|
|
err = am.saveAccount(ctx, am.CA, account)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error saving account: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Expect to load account from disk
|
|
|
|
keyBytes, err := PEMEncodePrivateKey(account.PrivateKey)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error encoding private key: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
loadedAccount, err := am.GetAccount(ctx, keyBytes)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error getting account: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assert keys are the same
|
|
|
|
if !privateKeysSame(account.PrivateKey, loadedAccount.PrivateKey) {
|
|
|
|
t.Error("Expected private key to be the same after loading, but it wasn't")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assert emails are the same
|
|
|
|
if !reflect.DeepEqual(account.Contact, loadedAccount.Contact) {
|
|
|
|
t.Errorf("Expected contacts to be equal, but was '%s' before and '%s' after loading", account.Contact, loadedAccount.Contact)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetAccountWithEmailAlreadyExists(t *testing.T) {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-06-04 13:55:10 +10:00
|
|
|
am := &ACMEIssuer{CA: dummyCA, Logger: zap.NewNop(), mu: new(sync.Mutex)}
|
2024-04-19 05:42:33 +10:00
|
|
|
testConfig := &Config{
|
|
|
|
Issuers: []Issuer{am},
|
|
|
|
Storage: &recordingStorage{Storage: &memoryStorage{}},
|
|
|
|
Logger: defaultTestLogger,
|
|
|
|
certCache: new(Cache),
|
|
|
|
}
|
|
|
|
am.config = testConfig
|
|
|
|
|
|
|
|
email := "me@foobar.com"
|
|
|
|
|
|
|
|
// Set up test
|
|
|
|
account, err := am.newAccount(email)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error creating account: %v", err)
|
|
|
|
}
|
|
|
|
err = am.saveAccount(ctx, am.CA, account)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error saving account: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the expected email:
|
|
|
|
am.Email = email
|
|
|
|
err = am.setEmail(ctx, true)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("setEmail error: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Expect to load account from disk
|
|
|
|
keyBytes, err := PEMEncodePrivateKey(account.PrivateKey)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error encoding private key: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
loadedAccount, err := am.GetAccount(ctx, keyBytes)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error getting account: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assert keys are the same
|
|
|
|
if !privateKeysSame(account.PrivateKey, loadedAccount.PrivateKey) {
|
|
|
|
t.Error("Expected private key to be the same after loading, but it wasn't")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assert emails are the same
|
|
|
|
if !reflect.DeepEqual(account.Contact, loadedAccount.Contact) {
|
|
|
|
t.Errorf("Expected contacts to be equal, but was '%s' before and '%s' after loading", account.Contact, loadedAccount.Contact)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assert that this was found without listing all accounts
|
|
|
|
rs := testConfig.Storage.(*recordingStorage)
|
|
|
|
for _, call := range rs.calls {
|
|
|
|
if call.name == "List" {
|
|
|
|
t.Error("Unexpected List call")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-22 04:31:57 +10:00
|
|
|
func TestGetEmailFromPackageDefault(t *testing.T) {
|
2022-03-08 05:26:52 +10:00
|
|
|
ctx := context.Background()
|
|
|
|
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
DefaultACME.Email = "tEsT2@foo.com"
|
2019-01-22 04:31:57 +10:00
|
|
|
defer func() {
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
DefaultACME.Email = ""
|
2021-04-13 03:57:11 +10:00
|
|
|
discoveredEmail = ""
|
2019-01-22 04:31:57 +10:00
|
|
|
}()
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
|
2024-06-04 13:55:10 +10:00
|
|
|
am := &ACMEIssuer{CA: dummyCA, Logger: zap.NewNop(), mu: new(sync.Mutex)}
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testConfig := &Config{
|
2020-11-17 03:53:41 +10:00
|
|
|
Issuers: []Issuer{am},
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
Storage: &FileStorage{Path: "./_testdata2_tmp"},
|
2022-09-27 02:19:28 +10:00
|
|
|
Logger: defaultTestLogger,
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
certCache: new(Cache),
|
|
|
|
}
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
am.config = testConfig
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
|
2022-07-06 08:56:22 +10:00
|
|
|
err := am.setEmail(ctx, true)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2019-01-22 04:31:57 +10:00
|
|
|
t.Fatalf("getEmail error: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
lowerEmail := strings.ToLower(DefaultACME.Email)
|
2022-08-02 15:04:11 +10:00
|
|
|
if am.getEmail() != lowerEmail {
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
t.Errorf("Did not get correct email from memory; expected '%s' but got '%s'", lowerEmail, am.Email)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
2019-01-22 04:31:57 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetEmailFromUserInput(t *testing.T) {
|
2022-03-08 05:26:52 +10:00
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-06-04 13:55:10 +10:00
|
|
|
am := &ACMEIssuer{CA: dummyCA, Logger: zap.NewNop(), mu: new(sync.Mutex)}
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testConfig := &Config{
|
2020-11-17 03:53:41 +10:00
|
|
|
Issuers: []Issuer{am},
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
Storage: &FileStorage{Path: "./_testdata3_tmp"},
|
2022-09-27 02:19:28 +10:00
|
|
|
Logger: defaultTestLogger,
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
certCache: new(Cache),
|
|
|
|
}
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
am.config = testConfig
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
|
|
|
|
// let's not clutter up the output
|
2019-01-22 04:31:57 +10:00
|
|
|
origStdout := os.Stdout
|
|
|
|
os.Stdout = nil
|
|
|
|
agreementTestURL = "(none - testing)"
|
|
|
|
defer func() {
|
|
|
|
os.Stdout = origStdout
|
|
|
|
agreementTestURL = ""
|
|
|
|
}()
|
2018-12-11 02:59:03 +10:00
|
|
|
|
2019-01-22 04:31:57 +10:00
|
|
|
email := "test3@foo.com"
|
|
|
|
stdin = bytes.NewBufferString(email + "\n")
|
2022-07-06 08:56:22 +10:00
|
|
|
err := am.setEmail(ctx, true)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2019-01-22 04:31:57 +10:00
|
|
|
t.Fatalf("getEmail error: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
2022-08-02 15:04:11 +10:00
|
|
|
if am.email != email {
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
t.Errorf("Did not get correct email from user input prompt; expected '%s' but got '%s'", email, am.Email)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
2022-08-02 15:04:11 +10:00
|
|
|
if !am.isAgreed() {
|
|
|
|
t.Error("Expect Config.agreed to be true, but got false")
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
2019-01-22 04:31:57 +10:00
|
|
|
}
|
2018-12-11 02:59:03 +10:00
|
|
|
|
2019-01-22 04:31:57 +10:00
|
|
|
func TestGetEmailFromRecent(t *testing.T) {
|
2022-03-08 05:26:52 +10:00
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-06-04 13:55:10 +10:00
|
|
|
am := &ACMEIssuer{CA: dummyCA, Logger: zap.NewNop(), mu: new(sync.Mutex)}
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testConfig := &Config{
|
2020-11-17 03:53:41 +10:00
|
|
|
Issuers: []Issuer{am},
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
Storage: &FileStorage{Path: "./_testdata4_tmp"},
|
2022-09-27 02:19:28 +10:00
|
|
|
Logger: defaultTestLogger,
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
certCache: new(Cache),
|
|
|
|
}
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
am.config = testConfig
|
|
|
|
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
testStorageDir := testConfig.Storage.(*FileStorage).Path
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
defer func() {
|
|
|
|
err := os.RemoveAll(testStorageDir)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not remove temporary storage directory (%s): %v", testStorageDir, err)
|
|
|
|
}
|
|
|
|
}()
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
DefaultACME.Email = ""
|
2021-04-13 03:57:11 +10:00
|
|
|
discoveredEmail = ""
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
|
2018-12-11 02:59:03 +10:00
|
|
|
for i, eml := range []string{
|
|
|
|
"test4-1@foo.com",
|
|
|
|
"test4-2@foo.com",
|
|
|
|
"TEST4-3@foo.com", // test case insensitivity
|
|
|
|
} {
|
2020-07-28 08:50:41 +10:00
|
|
|
account, err := am.newAccount(eml)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error creating user %d: %v", i, err)
|
|
|
|
}
|
2022-03-08 05:26:52 +10:00
|
|
|
err = am.saveAccount(ctx, am.CA, account)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error saving user %d: %v", i, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change modified time so they're all different and the test becomes more deterministic
|
Significant refactoring to improve correctness and flexibility (#39)
* Significant refactor
This refactoring expands the capabilities of the library for advanced
use cases, as well as improving the overall architecture, including
possible memory leak fixes if used over a long period with many certs
loaded into memory. This refactor enables using different configs
depending on the certificate.
The public API has changed slightly, however, and arguably it is
slightly less convenient/elegant. I have never quite found the perfect
design for this package, and this certainly isn't it, but I think it's
better than what we had before.
There is still work to be done, but this is a good step forward. I've
decoupled Storage from Cache, and made it easier and more correct for
Configs (and Storage values) to be short-lived. Cache is the only value
that should be long-lived.
Note that CertMagic no longer automatically takes care of storage (i.e.
it used to delete old OCSP staples, but now it doesn't). The functions
to do this are still there and even exported, and now we expect the
application to call the cleanup functions when it wants to.
* Fix little oopsies
* Create Manager abstraction so obtain/renew isn't limited to ACME
2019-04-21 02:44:55 +10:00
|
|
|
fs := testConfig.Storage.(*FileStorage)
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
userFolder := filepath.Join(fs.Path, am.storageKeyUserPrefix(am.CA, eml))
|
2018-12-11 02:59:03 +10:00
|
|
|
f, err := os.Stat(userFolder)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not access user folder for '%s': %v", eml, err)
|
|
|
|
}
|
|
|
|
chTime := f.ModTime().Add(time.Duration(i) * time.Hour) // 1 second isn't always enough spacing!
|
|
|
|
if err := os.Chtimes(userFolder, chTime, chTime); err != nil {
|
|
|
|
t.Fatalf("Could not change user folder mod time for '%s': %v", eml, err)
|
|
|
|
}
|
|
|
|
}
|
2022-07-06 08:56:22 +10:00
|
|
|
err := am.setEmail(ctx, true)
|
2018-12-11 02:59:03 +10:00
|
|
|
if err != nil {
|
2019-01-22 04:31:57 +10:00
|
|
|
t.Fatalf("getEmail error: %v", err)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
2022-08-02 15:04:11 +10:00
|
|
|
if am.getEmail() != "test4-3@foo.com" {
|
Major refactor to improve performance, correctness, and extensibility
Breaking changes; thank goodness we're not 1.0 yet 😅 - read on!
This change completely separates ACME-specific code from the rest of the
certificate management process, allowing pluggable sources for certs
that aren't ACME.
Notably, most of Config was spliced into ACMEManager. Similarly, there's
now Default and DefaultACME.
Storage structure had to be reconfigured. Certificates are no longer in
the acme/ subfolder since they can be obtained by ways other than ACME!
Certificates moved to a new certificates/ subfolder. The subfolders in
that folder use the path of the ACME endpoint instead of just the host,
so that also changed. Be aware that unless you move your certs over,
CertMagic will not find them and will attempt to get new ones. That is
usually fine for most users, but for extremely large deployments, you
will want to move them over first.
Old certs path:
acme/acme-staging-v02.api.letsencrypt.org/...
New certs path:
certificates/acme-staging-v02.api.letsencrypt.org-directory/...
That's all for significant storage changes!
But this refactor also vastly improves performance, especially at scale,
and makes CertMagic way more resilient to errors. Retries are done on
the staging endpoint by default, so they won't count against your rate
limit. If your hardware can handle it, I'm now pretty confident that you
can give CertMagic a million domain names and it will gracefully manage
them, as fast as it can within internal and external rate limits, even
in the presence of errors. Errors will of course slow some things down,
but you should be good to go if you're monitoring logs and can fix any
misconfigurations or other external errors!
Several other mostly-minor enhancements fix bugs, especially at scale.
For example, duplicated renewal tasks (that continuously fail) will not
pile up on each other: only one will operate, under exponential backoff.
Closes #50 and fixes #55
2020-02-22 07:32:57 +10:00
|
|
|
t.Errorf("Did not get correct email from storage; expected '%s' but got '%s'", "test4-3@foo.com", am.Email)
|
2018-12-11 02:59:03 +10:00
|
|
|
}
|
|
|
|
}
|
2021-10-28 06:15:09 +10:00
|
|
|
|
|
|
|
// agreementTestURL is set during tests to skip requiring
|
|
|
|
// setting up an entire ACME CA endpoint.
|
|
|
|
var agreementTestURL string
|