forked from go-acme/lego
/
s3.go
78 lines (63 loc) · 2 KB
/
s3.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Package s3 implements an HTTP provider for solving the HTTP-01 challenge using AWS S3.
package s3
import (
"bytes"
"context"
"errors"
"fmt"
"strings"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/go-acme/lego/v4/challenge/http01"
)
// HTTPProvider implements ChallengeProvider for `http-01` challenge.
type HTTPProvider struct {
bucket string
client *s3.Client
}
// NewHTTPProvider returns a HTTPProvider instance with a configured s3 bucket and aws session.
// Credentials must be passed in the environment variables.
func NewHTTPProvider(bucket string) (*HTTPProvider, error) {
if bucket == "" {
return nil, errors.New("s3: bucket name missing")
}
ctx := context.Background()
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
return nil, fmt.Errorf("s3: unable to create AWS config: %w", err)
}
client := s3.NewFromConfig(cfg)
return &HTTPProvider{
bucket: bucket,
client: client,
}, nil
}
// Present makes the token available at `HTTP01ChallengePath(token)` by creating a file in the given s3 bucket.
func (s *HTTPProvider) Present(domain, token, keyAuth string) error {
ctx := context.Background()
params := &s3.PutObjectInput{
ACL: "public-read",
Bucket: aws.String(s.bucket),
Key: aws.String(strings.Trim(http01.ChallengePath(token), "/")),
Body: bytes.NewReader([]byte(keyAuth)),
}
_, err := s.client.PutObject(ctx, params)
if err != nil {
return fmt.Errorf("s3: failed to upload token to s3: %w", err)
}
return nil
}
// CleanUp removes the file created for the challenge.
func (s *HTTPProvider) CleanUp(domain, token, keyAuth string) error {
ctx := context.Background()
params := &s3.DeleteObjectInput{
Bucket: aws.String(s.bucket),
Key: aws.String(strings.Trim(http01.ChallengePath(token), "/")),
}
_, err := s.client.DeleteObject(ctx, params)
if err != nil {
return fmt.Errorf("s3: could not remove file in s3 bucket after HTTP challenge: %w", err)
}
return nil
}