✨ Added authn module for expicitly choosen auth providers
This commit is contained in:
parent
83b9f56a4f
commit
4f8ac62b7b
|
@ -0,0 +1,7 @@
|
|||
package authn
|
||||
|
||||
import "context"
|
||||
|
||||
type Repository interface {
|
||||
Fetch(ctx context.Context, me string) ([]string, error)
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
http "github.com/valyala/fasthttp"
|
||||
"willnorris.com/go/microformats"
|
||||
|
||||
"source.toby3d.me/website/oauth/internal/authn"
|
||||
)
|
||||
|
||||
type httpAuthnRepository struct {
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
func NewHTTPAuthnRepository(client *http.Client) authn.Repository {
|
||||
return &httpAuthnRepository{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *httpAuthnRepository) Fetch(ctx context.Context, me string) ([]string, error) {
|
||||
u, err := url.Parse(me)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse me as url")
|
||||
}
|
||||
|
||||
req := http.AcquireRequest()
|
||||
defer http.ReleaseRequest(req)
|
||||
req.SetRequestURI(u.String())
|
||||
req.Header.SetMethod(http.MethodGet)
|
||||
|
||||
resp := http.AcquireResponse()
|
||||
defer http.ReleaseResponse(resp)
|
||||
|
||||
if err := repo.client.Do(req, resp); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to make a request to the entered me")
|
||||
}
|
||||
|
||||
data := microformats.Parse(bytes.NewReader(resp.Body()), u)
|
||||
authn := make([]string, 0)
|
||||
|
||||
for rel, values := range data.Rels {
|
||||
if rel != "authn" {
|
||||
continue
|
||||
}
|
||||
|
||||
authn = append(authn, values...)
|
||||
}
|
||||
|
||||
return authn, nil
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package http_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
http "github.com/valyala/fasthttp"
|
||||
|
||||
repository "source.toby3d.me/website/oauth/internal/authn/repository/http"
|
||||
"source.toby3d.me/website/oauth/internal/common"
|
||||
"source.toby3d.me/website/oauth/internal/util"
|
||||
)
|
||||
|
||||
const testBody string = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Example Profile</title>
|
||||
<link rel="me authn" href="https://user.example.com/">
|
||||
</head>
|
||||
<body>
|
||||
<div class="h-card">
|
||||
<img src="/photo.png" class="u-photo">
|
||||
<a rel="me" href="https://user.example.org/">Unsecure profile</a>
|
||||
<a rel="me authn" href="https://user.example.net/">Secure profile</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
func TestFetch(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client, _, cleanup := util.TestServe(t, func(ctx *http.RequestCtx) {
|
||||
ctx.SetStatusCode(http.StatusOK)
|
||||
ctx.SetContentType(common.MIMETextHTML)
|
||||
ctx.SetBodyString(testBody)
|
||||
})
|
||||
t.Cleanup(cleanup)
|
||||
|
||||
result, err := repository.NewHTTPAuthnRepository(client).Fetch(context.TODO(), "https://example.com/")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{
|
||||
"https://user.example.com/",
|
||||
"https://user.example.net/",
|
||||
}, result)
|
||||
}
|
Loading…
Reference in New Issue