add client config

This commit is contained in:
kekskurse 2024-09-13 11:05:36 +02:00
parent ec7eab2638
commit 2e7e4630af
4 changed files with 68 additions and 34 deletions

View file

@ -2,3 +2,4 @@ Small oAuth2 Client to have an easy way to connect to Authentik
# Links # Links
* https://www.oauth.com/oauth2-servers/authorization/the-authorization-request/ * https://www.oauth.com/oauth2-servers/authorization/the-authorization-request/
* https://connect2id.com/products/server/docs/api/token

60
auth.go
View file

@ -7,27 +7,33 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
"time"
) )
type Auth struct { type Auth struct {
config AuthConfig authConfig AuthConfig
clientID string clientConfig ClientConfig
clientSecret string
} }
func NewAuthWithConfig(config AuthConfig, clientID, clientSecret string) (Auth, error) { type Token struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiredIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
CreatedAt time.Time
}
func NewAuthWithConfig(config ClientConfig, authConfig AuthConfig) (Auth, error) {
a := Auth{} a := Auth{}
a.config = config a.authConfig = authConfig
a.clientID = clientID a.clientConfig = config
a.clientSecret = clientSecret
return a, nil return a, nil
} }
func NewAuthWithConfigurationURL(url, clientID, clientSecret string) (Auth, error) { func NewAuthWithConfigurationURL(config ClientConfig, url string) (Auth, error) {
a := Auth{} a := Auth{}
a.clientID = clientID a.clientConfig = config
a.clientSecret = clientSecret authConfig := AuthConfig{}
config := AuthConfig{}
res, err := http.Get(url) res, err := http.Get(url)
if err != nil { if err != nil {
@ -40,38 +46,38 @@ func NewAuthWithConfigurationURL(url, clientID, clientSecret string) (Auth, erro
return Auth{}, fmt.Errorf("%w: %q", ErrCantGetConfiguratorData, err) return Auth{}, fmt.Errorf("%w: %q", ErrCantGetConfiguratorData, err)
} }
err = json.Unmarshal(bodyContent, &config) err = json.Unmarshal(bodyContent, &authConfig)
if err != nil { if err != nil {
return Auth{}, fmt.Errorf("%w: %q", ErrCantGetConfiguratorData, err) return Auth{}, fmt.Errorf("%w: %q", ErrCantGetConfiguratorData, err)
} }
a.config = config a.authConfig = authConfig
return a, nil return a, nil
} }
func (a Auth) GetAuthorizationURL(redirectUrl string, scope []string, state string) (string, error) { func (a Auth) GetAuthorizationURL(state string) (string, error) {
if a.config.AuthorizationEndpoint == "" { if a.authConfig.AuthorizationEndpoint == "" {
return "", fmt.Errorf("%w: %s", ErrCantGetAuthorizationURL, "AuthorizationEndpoint in config is empty") return "", fmt.Errorf("%w: %s", ErrCantGetAuthorizationURL, "AuthorizationEndpoint in config is empty")
} }
if a.clientID == "" { if a.clientConfig.ClientID == "" {
return "", fmt.Errorf("%w: %s", ErrCantGetAuthorizationURL, "clientid in config is empty") return "", fmt.Errorf("%w: %s", ErrCantGetAuthorizationURL, "clientid in config is empty")
} }
url, err := url.Parse(a.config.AuthorizationEndpoint) url, err := url.Parse(a.authConfig.AuthorizationEndpoint)
if err != nil { if err != nil {
return "", fmt.Errorf("%w: %q", ErrCantGetAuthorizationURL, err) return "", fmt.Errorf("%w: %q", ErrCantGetAuthorizationURL, err)
} }
values := url.Query() values := url.Query()
values.Set("client_id", a.clientID) values.Set("client_id", a.clientConfig.ClientID)
if redirectUrl != "" { if a.clientConfig.RedirectURL != "" {
values.Set("redirect_uri", redirectUrl) values.Set("redirect_uri", a.clientConfig.RedirectURL)
} }
if len(scope) > 0 { if len(a.clientConfig.Scope) > 0 {
values.Set("scope", strings.Join(scope, "+")) values.Set("scope", strings.Join(a.clientConfig.Scope, "+"))
} }
if state != "" { if state != "" {
@ -84,3 +90,13 @@ func (a Auth) GetAuthorizationURL(redirectUrl string, scope []string, state stri
return url.String(), nil return url.String(), nil
} }
func (a Auth) GetTokenFromCode(code string) (Token, error) {
t := Token{}
form := url.Values{}
form.Add("grant_type", "authorization_code")
form.Add("code", code)
return t, nil
}

View file

@ -8,21 +8,23 @@ import (
) )
func TestNewAuthWithConfig(t *testing.T) { func TestNewAuthWithConfig(t *testing.T) {
clientConfig := ClientConfig{ClientID: "abc", ClientSecret: "def"}
config := AuthConfig{} config := AuthConfig{}
config.TokenEndpoint = "http://localhost/something" config.TokenEndpoint = "http://localhost/something"
client, err := NewAuthWithConfig(config, "abc", "def") client, err := NewAuthWithConfig(clientConfig, config)
assert.Equal(t, nil, err, "should return no error while creating Auth") assert.Equal(t, nil, err, "should return no error while creating Auth")
assert.Equal(t, "http://localhost/something", client.config.TokenEndpoint, "should have currect config") assert.Equal(t, "http://localhost/something", client.authConfig.TokenEndpoint, "should have currect config")
assert.Equal(t, "abc", client.clientID, "should have stored currect clientid") assert.Equal(t, "abc", client.clientConfig.ClientID, "should have stored currect clientid")
assert.Equal(t, "def", client.clientSecret, "should have stored currect client secret") assert.Equal(t, "def", client.clientConfig.ClientSecret, "should have stored currect client secret")
} }
func TestNewAuthWithConfigurationURL(t *testing.T) { func TestNewAuthWithConfigurationURL(t *testing.T) {
client, err := NewAuthWithConfigurationURL("http://localhost:8084/openid-configuration", "abc", "def") clientConfig := ClientConfig{ClientID: "abc", ClientSecret: "def"}
client, err := NewAuthWithConfigurationURL(clientConfig, "http://localhost:8084/openid-configuration")
assert.Nil(t, err, "should create client without any error") assert.Nil(t, err, "should create client without any error")
assert.Equal(t, "https://auth.keks.cloud/application/o/token/", client.config.TokenEndpoint, "token endpoint should match") assert.Equal(t, "https://auth.keks.cloud/application/o/token/", client.authConfig.TokenEndpoint, "token endpoint should match")
assert.Equal(t, "abc", client.clientID, "should have stored currect clientid") assert.Equal(t, "abc", client.clientConfig.ClientID, "should have stored currect clientid")
assert.Equal(t, "def", client.clientSecret, "should have stored currect client secret") assert.Equal(t, "def", client.clientConfig.ClientSecret, "should have stored currect client secret")
} }
func TestGetAuthorizationUrl(t *testing.T) { func TestGetAuthorizationUrl(t *testing.T) {
@ -61,10 +63,12 @@ func TestGetAuthorizationUrl(t *testing.T) {
for _, tt := range tts { for _, tt := range tts {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
client, err := NewAuthWithConfig(tt.config, "abc", "def") config := ClientConfig{ClientID: "abc", ClientSecret: "def", Scope: tt.scops, RedirectURL: tt.redirectURL}
client, err := NewAuthWithConfig(config, tt.config)
assert.Nil(t, err, "should be able to create client without error") assert.Nil(t, err, "should be able to create client without error")
url, err := client.GetAuthorizationURL(tt.redirectURL, tt.scops, tt.state) url, err := client.GetAuthorizationURL(tt.state)
if tt.exptError == nil { if tt.exptError == nil {
assert.Nil(t, err, "should get link without error") assert.Nil(t, err, "should get link without error")
} else { } else {
@ -76,9 +80,15 @@ func TestGetAuthorizationUrl(t *testing.T) {
} }
func TestAuthenticLogin(t *testing.T) { func TestAuthenticLogin(t *testing.T) {
client, err := NewAuthWithConfigurationURL("http://localhost:8084/openid-configuration", "abc", "def") t.Skip("dev test")
clientConfig := ClientConfig{ClientID: "abc", ClientSecret: "def"}
client, err := NewAuthWithConfigurationURL(clientConfig, "http://localhost:8084/openid-configuration")
assert.Nil(t, err, "should be able to create client without error") assert.Nil(t, err, "should be able to create client without error")
url, err := client.GetAuthorizationURL("http://localhost/something", []string{}, "") url, err := client.GetAuthorizationURL("")
assert.Nil(t, err, "should be able to create url without error") assert.Nil(t, err, "should be able to create url without error")
fmt.Println(url) fmt.Println(url)
token, err := client.GetTokenFromCode("e34bc2c7840e4386b17880dd1142c67b")
assert.Nil(t, err, "should be able to get code without error")
fmt.Println(token)
} }

View file

@ -1,5 +1,12 @@
package kekskurseauth package kekskurseauth
type ClientConfig struct {
ClientID string
ClientSecret string
RedirectURL string
Scope []string
}
type AuthConfig struct { type AuthConfig struct {
TokenEndpoint string `json:"token_endpoint"` TokenEndpoint string `json:"token_endpoint"`
UserinfoEndpoint string `json:"userinfo_endpoint"` UserinfoEndpoint string `json:"userinfo_endpoint"`