2021-09-29 20:35:39 +00:00
|
|
|
package domain
|
|
|
|
|
2021-12-29 20:08:30 +00:00
|
|
|
import (
|
2022-01-08 10:49:02 +00:00
|
|
|
"net"
|
2023-01-02 01:15:11 +00:00
|
|
|
"net/url"
|
2022-01-08 10:49:02 +00:00
|
|
|
"strings"
|
2021-12-29 20:08:30 +00:00
|
|
|
"testing"
|
|
|
|
)
|
2021-09-29 20:35:39 +00:00
|
|
|
|
2021-12-29 20:08:30 +00:00
|
|
|
// Client describes the client requesting data about the user.
|
|
|
|
type Client struct {
|
2023-08-07 03:07:55 +00:00
|
|
|
Logo *url.URL
|
|
|
|
URL *url.URL
|
2023-01-14 21:27:37 +00:00
|
|
|
ID ClientID
|
2023-08-07 03:07:55 +00:00
|
|
|
Name string
|
2023-01-02 01:15:11 +00:00
|
|
|
RedirectURI []*url.URL
|
2021-09-29 20:35:39 +00:00
|
|
|
}
|
|
|
|
|
2022-01-29 17:50:45 +00:00
|
|
|
// NewClient creates a new empty Client with provided ClientID, if any.
|
2023-01-14 21:27:37 +00:00
|
|
|
func NewClient(cid ClientID) *Client {
|
2022-01-29 17:50:45 +00:00
|
|
|
return &Client{
|
|
|
|
ID: cid,
|
2023-08-07 03:07:55 +00:00
|
|
|
Logo: nil,
|
2023-01-02 01:15:11 +00:00
|
|
|
RedirectURI: make([]*url.URL, 0),
|
2023-08-07 03:07:55 +00:00
|
|
|
URL: nil,
|
|
|
|
Name: "",
|
2022-01-29 17:50:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestClient returns valid random generated client for tests.
|
2021-09-29 20:35:39 +00:00
|
|
|
func TestClient(tb testing.TB) *Client {
|
|
|
|
tb.Helper()
|
|
|
|
|
|
|
|
return &Client{
|
2023-01-14 21:27:37 +00:00
|
|
|
ID: *TestClientID(tb),
|
2023-08-07 03:07:55 +00:00
|
|
|
Name: "Example App",
|
|
|
|
URL: &url.URL{Scheme: "https", Host: "app.example.com", Path: "/"},
|
|
|
|
Logo: &url.URL{Scheme: "https", Host: "app.example.com", Path: "/logo.png"},
|
2023-01-02 01:15:11 +00:00
|
|
|
RedirectURI: []*url.URL{
|
|
|
|
{Scheme: "https", Host: "app.example.com", Path: "/redirect"},
|
|
|
|
{Scheme: "https", Host: "app.example.net", Path: "/redirect"},
|
|
|
|
},
|
2021-09-29 20:35:39 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-08 10:49:02 +00:00
|
|
|
|
|
|
|
// ValidateRedirectURI validates RedirectURI from request to ClientID or
|
|
|
|
// registered set of client RedirectURI.
|
|
|
|
//
|
|
|
|
// If the URL scheme, host or port of the redirect_uri in the request do not
|
|
|
|
// match that of the client_id, then the authorization endpoint SHOULD verify
|
|
|
|
// that the requested redirect_uri matches one of the redirect URLs published by
|
|
|
|
// the client, and SHOULD block the request from proceeding if not.
|
2023-01-02 01:15:11 +00:00
|
|
|
func (c *Client) ValidateRedirectURI(redirectURI *url.URL) bool {
|
2022-01-08 10:49:02 +00:00
|
|
|
if redirectURI == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2023-01-02 01:15:11 +00:00
|
|
|
rHost, rPort, err := net.SplitHostPort(redirectURI.Host)
|
2022-01-08 10:49:02 +00:00
|
|
|
if err != nil {
|
2023-01-02 01:15:11 +00:00
|
|
|
rHost = redirectURI.Hostname()
|
2022-01-08 10:49:02 +00:00
|
|
|
}
|
|
|
|
|
2023-01-02 00:32:13 +00:00
|
|
|
cHost, cPort, err := net.SplitHostPort(c.ID.clientID.Host)
|
2022-01-08 10:49:02 +00:00
|
|
|
if err != nil {
|
2023-01-02 00:32:13 +00:00
|
|
|
cHost = c.ID.clientID.Hostname()
|
2022-01-08 10:49:02 +00:00
|
|
|
}
|
|
|
|
|
2023-01-02 01:15:11 +00:00
|
|
|
if strings.EqualFold(redirectURI.Scheme, c.ID.clientID.Scheme) &&
|
2022-01-08 10:49:02 +00:00
|
|
|
strings.EqualFold(rHost, cHost) &&
|
|
|
|
strings.EqualFold(rPort, cPort) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range c.RedirectURI {
|
|
|
|
if redirectURI.String() != c.RedirectURI[i].String() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|