orchid/http-acme/http-acme-provider_test.go

108 lines
2.8 KiB
Go
Raw Normal View History

2023-06-26 11:56:21 +01:00
package http_acme
2023-06-23 23:00:09 +01:00
import (
"crypto/rand"
"crypto/rsa"
"fmt"
"github.com/1f349/mjwt"
"github.com/1f349/mjwt/auth"
"github.com/1f349/mjwt/claims"
2023-06-23 23:00:09 +01:00
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"
)
2023-07-03 16:27:24 +01:00
func makeQuickHttpProv(accessToken string, ft http.RoundTripper) *HttpAcmeProvider {
return &HttpAcmeProvider{
2023-07-07 15:47:38 +01:00
"",
2023-07-03 16:27:24 +01:00
accessToken,
"",
2023-07-07 15:47:38 +01:00
"https://api.example.com/acme/present/$domain/$token/$content",
"https://api.example.com/acme/clean/$domain/$token",
2023-07-03 16:27:24 +01:00
"https://api.example.com/acme/token",
ft,
}
}
// fakeTransport captures any requests and responds with a successful answer if
// applicable
2023-06-23 23:00:09 +01:00
type fakeTransport struct {
verify mjwt.Verifier
req *http.Request
clean bool
}
func (f *fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) {
2023-07-03 16:27:24 +01:00
// check bearer token and extract claims
2023-06-23 23:00:09 +01:00
bearer := req.Header.Get("Authorization")
if !strings.HasPrefix(bearer, "Bearer ") {
return nil, fmt.Errorf("invalid bearer token")
}
_, b, err := mjwt.ExtractClaims[auth.AccessTokenClaims](f.verify, bearer[7:])
if err != nil {
return nil, err
}
// check perms
if !f.clean && !b.Claims.Perms.Has("test:acme:present") {
return nil, fmt.Errorf("missing perm 'test:acme:present'")
}
if f.clean && !b.Claims.Perms.Has("test:acme:clean") {
return nil, fmt.Errorf("missing perm 'test:acme:clean'")
}
rec := httptest.NewRecorder()
rec.WriteHeader(http.StatusAccepted)
2023-06-23 23:00:09 +01:00
f.req = req
return rec.Result(), nil
}
func TestHttpAcmeProvider_Present(t *testing.T) {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
assert.NoError(t, err)
// perms
ps := claims.NewPermStorage()
ps.Set("test:acme:present")
// signer
signer := mjwt.NewMJwtSigner("Test", privateKey)
accessToken, err := signer.GenerateJwt("", "", nil, 5*time.Minute, auth.AccessTokenClaims{Perms: ps})
assert.NoError(t, err)
ft := &fakeTransport{verify: signer}
2023-07-03 16:27:24 +01:00
prov := makeQuickHttpProv(accessToken, ft)
2023-06-23 23:00:09 +01:00
assert.NoError(t, prov.Present("example.com", "1234", "1234abcd"))
assert.Equal(t, *ft.req.URL, url.URL{
Scheme: "https",
Host: "api.example.com",
Path: "/acme/present/example.com/1234/1234abcd",
})
}
func TestHttpAcmeProvider_CleanUp(t *testing.T) {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
assert.NoError(t, err)
// perms
ps := claims.NewPermStorage()
ps.Set("test:acme:clean")
// signer
signer := mjwt.NewMJwtSigner("Test", privateKey)
accessToken, err := signer.GenerateJwt("", "", nil, 5*time.Minute, auth.AccessTokenClaims{Perms: ps})
assert.NoError(t, err)
ft := &fakeTransport{verify: signer, clean: true}
2023-07-03 16:27:24 +01:00
prov := makeQuickHttpProv(accessToken, ft)
2023-06-23 23:00:09 +01:00
assert.NoError(t, prov.CleanUp("example.com", "1234", "1234abcd"))
assert.Equal(t, *ft.req.URL, url.URL{
Scheme: "https",
Host: "api.example.com",
Path: "/acme/clean/example.com/1234",
})
}