mirror of
https://github.com/woodchen-ink/certimate.git
synced 2025-07-18 17:31:55 +08:00
Handle concurrency issues in a simple way.
This commit is contained in:
parent
1dca6ecf8d
commit
7ab8517a93
@ -318,6 +318,12 @@ func getReg(client *lego.Client, sslProvider *SSLProviderConfig, user *ApplyUser
|
|||||||
|
|
||||||
repo := getAcmeAccountRepository()
|
repo := getAcmeAccountRepository()
|
||||||
|
|
||||||
|
resp, err := repo.GetByCAAndEmail(sslProvider.Provider, user.GetEmail())
|
||||||
|
if err == nil {
|
||||||
|
user.key = resp.Key
|
||||||
|
return resp.Resource, nil
|
||||||
|
}
|
||||||
|
|
||||||
if err := repo.Save(sslProvider.Provider, user.GetEmail(), user.getPrivateKeyString(), reg); err != nil {
|
if err := repo.Save(sslProvider.Provider, user.GetEmail(), user.getPrivateKeyString(), reg); err != nil {
|
||||||
return nil, fmt.Errorf("failed to save registration: %w", err)
|
return nil, fmt.Errorf("failed to save registration: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/registration"
|
"github.com/go-acme/lego/v4/registration"
|
||||||
"github.com/pocketbase/dbx"
|
"github.com/pocketbase/dbx"
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/usual2970/certimate/internal/domain"
|
"github.com/usual2970/certimate/internal/domain"
|
||||||
"github.com/usual2970/certimate/internal/utils/app"
|
"github.com/usual2970/certimate/internal/utils/app"
|
||||||
|
"golang.org/x/sync/singleflight"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AcmeAccountRepository struct{}
|
type AcmeAccountRepository struct{}
|
||||||
@ -14,25 +17,42 @@ func NewAcmeAccountRepository() *AcmeAccountRepository {
|
|||||||
return &AcmeAccountRepository{}
|
return &AcmeAccountRepository{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var g singleflight.Group
|
||||||
|
|
||||||
func (r *AcmeAccountRepository) GetByCAAndEmail(ca, email string) (*domain.AcmeAccount, error) {
|
func (r *AcmeAccountRepository) GetByCAAndEmail(ca, email string) (*domain.AcmeAccount, error) {
|
||||||
|
resp, err, _ := g.Do(fmt.Sprintf("acme_account_%s_%s", ca, email), func() (interface{}, error) {
|
||||||
resp, err := app.GetApp().Dao().FindFirstRecordByFilter("acme_accounts", "ca={:ca} && email={:email}", dbx.Params{"ca": ca, "email": email})
|
resp, err := app.GetApp().Dao().FindFirstRecordByFilter("acme_accounts", "ca={:ca} && email={:email}", dbx.Params{"ca": ca, "email": email})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return resp, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp == nil {
|
||||||
|
return nil, fmt.Errorf("acme account not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
record, ok := resp.(*models.Record)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("acme account not found")
|
||||||
|
}
|
||||||
|
|
||||||
resource := ®istration.Resource{}
|
resource := ®istration.Resource{}
|
||||||
if err := resp.UnmarshalJSONField("resource", resource); err != nil {
|
if err := record.UnmarshalJSONField("resource", resource); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &domain.AcmeAccount{
|
return &domain.AcmeAccount{
|
||||||
Id: resp.GetString("id"),
|
Id: record.GetString("id"),
|
||||||
Ca: resp.GetString("ca"),
|
Ca: record.GetString("ca"),
|
||||||
Email: resp.GetString("email"),
|
Email: record.GetString("email"),
|
||||||
Key: resp.GetString("key"),
|
Key: record.GetString("key"),
|
||||||
Resource: resource,
|
Resource: resource,
|
||||||
Created: resp.GetTime("created"),
|
Created: record.GetTime("created"),
|
||||||
Updated: resp.GetTime("updated"),
|
Updated: record.GetTime("updated"),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user