13 changed files with 1064 additions and 817 deletions
@ -0,0 +1,268 @@ |
|||||
|
package client |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"encoding/json" |
||||
|
"fmt" |
||||
|
"net/http" |
||||
|
"net/url" |
||||
|
"time" |
||||
|
|
||||
|
oidc "github.com/coreos/go-oidc" |
||||
|
"gopkg.in/h2non/gentleman.v2" |
||||
|
"gopkg.in/h2non/gentleman.v2/plugin" |
||||
|
"gopkg.in/h2non/gentleman.v2/plugins/timeout" |
||||
|
) |
||||
|
|
||||
|
type HttpConfig struct { |
||||
|
Addr string |
||||
|
Username string |
||||
|
Password string |
||||
|
Timeout time.Duration |
||||
|
} |
||||
|
|
||||
|
type client struct { |
||||
|
username string |
||||
|
password string |
||||
|
accessToken string |
||||
|
oidcProvider *oidc.Provider |
||||
|
httpClient *gentleman.Client |
||||
|
} |
||||
|
|
||||
|
func New(config HttpConfig) (*client, error) { |
||||
|
var u *url.URL |
||||
|
{ |
||||
|
var err error |
||||
|
u, err = url.Parse(config.Addr) |
||||
|
if err != nil { |
||||
|
return nil, fmt.Errorf("could not parse URL: %v", err) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if u.Scheme != "http" { |
||||
|
return nil, fmt.Errorf("protocol not supported, your address must start with http://, not %v", u.Scheme) |
||||
|
} |
||||
|
|
||||
|
var httpClient = gentleman.New() |
||||
|
{ |
||||
|
httpClient = httpClient.URL(u.String()) |
||||
|
httpClient = httpClient.Use(timeout.Request(config.Timeout)) |
||||
|
} |
||||
|
|
||||
|
var oidcProvider *oidc.Provider |
||||
|
{ |
||||
|
var err error |
||||
|
var issuer = fmt.Sprintf("%s/auth/realms/master", u.String()) |
||||
|
oidcProvider, err = oidc.NewProvider(context.Background(), issuer) |
||||
|
if err != nil { |
||||
|
return nil, fmt.Errorf("could not create oidc provider: %v", err) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return &client{ |
||||
|
username: config.Username, |
||||
|
password: config.Password, |
||||
|
oidcProvider: oidcProvider, |
||||
|
httpClient: httpClient, |
||||
|
}, nil |
||||
|
} |
||||
|
|
||||
|
func (c *client) getToken() error { |
||||
|
var req *gentleman.Request |
||||
|
{ |
||||
|
var authPath = "/auth/realms/master/protocol/openid-connect/token" |
||||
|
req = c.httpClient.Post() |
||||
|
req = req.SetHeader("Content-Type", "application/x-www-form-urlencoded") |
||||
|
req = req.Path(authPath) |
||||
|
req = req.Type("urlencoded") |
||||
|
req = req.BodyString(fmt.Sprintf("username=%s&password=%s&grant_type=password&client_id=admin-cli", c.username, c.password)) |
||||
|
} |
||||
|
|
||||
|
var resp *gentleman.Response |
||||
|
{ |
||||
|
var err error |
||||
|
resp, err = req.Do() |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not get token: %v", err) |
||||
|
} |
||||
|
} |
||||
|
defer resp.Close() |
||||
|
|
||||
|
var unmarshalledBody map[string]interface{} |
||||
|
{ |
||||
|
var err error |
||||
|
err = resp.JSON(&unmarshalledBody) |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not unmarshal response: %v", err) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var accessToken interface{} |
||||
|
{ |
||||
|
var ok bool |
||||
|
accessToken, ok = unmarshalledBody["access_token"] |
||||
|
if !ok { |
||||
|
return fmt.Errorf("could not find access token in response body") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
c.accessToken = accessToken.(string) |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
func (c *client) verifyToken() error { |
||||
|
var v = c.oidcProvider.Verifier(&oidc.Config{SkipClientIDCheck: true}) |
||||
|
|
||||
|
var err error |
||||
|
_, err = v.Verify(context.Background(), c.accessToken) |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
func (c *client) get(data interface{}, plugins ...plugin.Plugin) error { |
||||
|
var req = c.httpClient.Get() |
||||
|
req = applyPlugins(req, c.accessToken, plugins...) |
||||
|
|
||||
|
var resp *gentleman.Response |
||||
|
{ |
||||
|
var err error |
||||
|
resp, err = req.Do() |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not get response: %v", err) |
||||
|
} |
||||
|
|
||||
|
switch { |
||||
|
case resp.StatusCode == http.StatusUnauthorized: |
||||
|
// If the token is not valid (expired, ...) ask a new one.
|
||||
|
if err = c.verifyToken(); err != nil { |
||||
|
var err = c.getToken() |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not get token: %v", err) |
||||
|
} |
||||
|
} |
||||
|
return c.get(data, plugins...) |
||||
|
case resp.StatusCode >= 400: |
||||
|
return handleError(resp) |
||||
|
case resp.StatusCode >= 200: |
||||
|
return json.Unmarshal(resp.Bytes(), data) |
||||
|
default: |
||||
|
return fmt.Errorf("unknown response status code: %v", resp.StatusCode) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (c *client) post(plugins ...plugin.Plugin) error { |
||||
|
var req = c.httpClient.Post() |
||||
|
req = applyPlugins(req, c.accessToken, plugins...) |
||||
|
|
||||
|
var resp *gentleman.Response |
||||
|
{ |
||||
|
var err error |
||||
|
resp, err = req.Do() |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not get response: %v", err) |
||||
|
} |
||||
|
|
||||
|
switch { |
||||
|
case resp.StatusCode == http.StatusUnauthorized: |
||||
|
// If the token is not valid (expired, ...) ask a new one.
|
||||
|
if err = c.verifyToken(); err != nil { |
||||
|
var err = c.getToken() |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not get token: %v", err) |
||||
|
} |
||||
|
} |
||||
|
return c.post(plugins...) |
||||
|
case resp.StatusCode >= 400: |
||||
|
return handleError(resp) |
||||
|
case resp.StatusCode >= 200: |
||||
|
return nil |
||||
|
default: |
||||
|
return fmt.Errorf("unknown response status code: %v", resp.StatusCode) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (c *client) delete(plugins ...plugin.Plugin) error { |
||||
|
var req = c.httpClient.Delete() |
||||
|
req = applyPlugins(req, c.accessToken, plugins...) |
||||
|
|
||||
|
var resp *gentleman.Response |
||||
|
{ |
||||
|
var err error |
||||
|
resp, err = req.Do() |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not get response: %v", err) |
||||
|
} |
||||
|
|
||||
|
switch { |
||||
|
case resp.StatusCode == http.StatusUnauthorized: |
||||
|
// If the token is not valid (expired, ...) ask a new one.
|
||||
|
if err = c.verifyToken(); err != nil { |
||||
|
var err = c.getToken() |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not get token: %v", err) |
||||
|
} |
||||
|
} |
||||
|
return c.delete(plugins...) |
||||
|
case resp.StatusCode >= 400: |
||||
|
return handleError(resp) |
||||
|
case resp.StatusCode >= 200: |
||||
|
return nil |
||||
|
default: |
||||
|
return fmt.Errorf("unknown response status code: %v", resp.StatusCode) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (c *client) put(plugins ...plugin.Plugin) error { |
||||
|
var req = c.httpClient.Put() |
||||
|
req = applyPlugins(req, c.accessToken, plugins...) |
||||
|
|
||||
|
var resp *gentleman.Response |
||||
|
{ |
||||
|
var err error |
||||
|
resp, err = req.Do() |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not get response: %v", err) |
||||
|
} |
||||
|
|
||||
|
switch { |
||||
|
case resp.StatusCode == http.StatusUnauthorized: |
||||
|
// If the token is not valid (expired, ...) ask a new one.
|
||||
|
if err = c.verifyToken(); err != nil { |
||||
|
var err = c.getToken() |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("could not get token: %v", err) |
||||
|
} |
||||
|
} |
||||
|
return c.put(plugins...) |
||||
|
case resp.StatusCode >= 400: |
||||
|
return handleError(resp) |
||||
|
case resp.StatusCode >= 200: |
||||
|
return nil |
||||
|
default: |
||||
|
return fmt.Errorf("unknown response status code: %v", resp.StatusCode) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func applyPlugins(req *gentleman.Request, accessToken string, plugins ...plugin.Plugin) *gentleman.Request { |
||||
|
var r = req.SetHeader("Authorization", fmt.Sprintf("Bearer %s", accessToken)) |
||||
|
for _, p := range plugins { |
||||
|
r = r.Use(p) |
||||
|
} |
||||
|
return r |
||||
|
} |
||||
|
|
||||
|
func handleError(resp *gentleman.Response) error { |
||||
|
var m = map[string]string{} |
||||
|
var err = json.Unmarshal(resp.Bytes(), &m) |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("invalid status code: %v; could not unmarshal response: %v", resp.StatusCode, err) |
||||
|
} |
||||
|
return fmt.Errorf("error message: %v", m) |
||||
|
} |
||||
|
|
||||
|
func str(s string) *string { |
||||
|
return &s |
||||
|
} |
||||
@ -1,147 +0,0 @@ |
|||||
package client |
|
||||
|
|
||||
import ( |
|
||||
"fmt" |
|
||||
"net/url" |
|
||||
"github.com/pkg/errors" |
|
||||
"time" |
|
||||
"net/http" |
|
||||
"gopkg.in/h2non/gentleman.v2" |
|
||||
"gopkg.in/h2non/gentleman.v2/plugin" |
|
||||
"gopkg.in/h2non/gentleman.v2/plugins/timeout" |
|
||||
//"gopkg.in/h2non/gentleman.v2/plugins/multipart"
|
|
||||
) |
|
||||
|
|
||||
|
|
||||
type Client interface { |
|
||||
GetRealms() ([]RealmRepresentation, error) |
|
||||
GetUsers(realm string) ([]UserRepresentation, error) |
|
||||
} |
|
||||
|
|
||||
type HttpConfig struct { |
|
||||
Addr string |
|
||||
Username string |
|
||||
Password string |
|
||||
Timeout time.Duration |
|
||||
} |
|
||||
|
|
||||
type client struct { |
|
||||
username string |
|
||||
password string |
|
||||
accessToken string |
|
||||
httpClient *gentleman.Client |
|
||||
} |
|
||||
|
|
||||
|
|
||||
func NewHttpClient(config HttpConfig) (Client, error) { |
|
||||
var u *url.URL |
|
||||
{ |
|
||||
var err error |
|
||||
u, err = url.Parse(config.Addr) |
|
||||
if err != nil { |
|
||||
return nil, errors.Wrap(err, "Parse failed") |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if u.Scheme != "http" { |
|
||||
var m string = fmt.Sprintf("Unsupported protocol %s. Your address must start with http://", u.Scheme) |
|
||||
return nil, errors.New(m) |
|
||||
} |
|
||||
|
|
||||
var httpClient *gentleman.Client = gentleman.New() |
|
||||
{ |
|
||||
httpClient = httpClient.URL(u.String()) |
|
||||
httpClient = httpClient.Use(timeout.Request(config.Timeout)) |
|
||||
} |
|
||||
|
|
||||
return &client{ |
|
||||
username: config.Username, |
|
||||
password: config.Password, |
|
||||
httpClient: httpClient, |
|
||||
}, nil |
|
||||
} |
|
||||
|
|
||||
func (c *client) getToken() error { |
|
||||
var req *gentleman.Request |
|
||||
{ |
|
||||
var authPath string = "/auth/realms/master/protocol/openid-connect/token" |
|
||||
//var formData multipart.FormData = multipart.FormData{
|
|
||||
// Data: map[string]multipart.Values{
|
|
||||
// "username": multipart.Values{c.username},
|
|
||||
// "password": multipart.Values{c.password},
|
|
||||
// "grant_type": multipart.Values{"password"},
|
|
||||
// "client_id": multipart.Values{"admin-cli"},
|
|
||||
// },
|
|
||||
//}
|
|
||||
req = c.httpClient.Post() |
|
||||
req = req.SetHeader("Content-Type", "application/x-www-form-urlencoded") |
|
||||
req = req.Path(authPath) |
|
||||
req = req.Type("urlencoded") |
|
||||
req = req.BodyString(fmt.Sprintf("username=%s&password=%s&grant_type=password&client_id=admin-cli",c.username,c.password)) |
|
||||
} |
|
||||
|
|
||||
var resp *gentleman.Response |
|
||||
{ |
|
||||
var err error |
|
||||
resp, err = req.Do() |
|
||||
if err != nil { |
|
||||
return errors.Wrap(err, "Failed to get the token response") |
|
||||
} |
|
||||
} |
|
||||
defer resp.Close() |
|
||||
|
|
||||
var unmarshalledBody map[string]interface{} |
|
||||
{ |
|
||||
var err error |
|
||||
err = resp.JSON(&unmarshalledBody) |
|
||||
if err != nil { |
|
||||
return errors.Wrap(err, "Failed to unmarshal response json") |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
var accessToken interface{} |
|
||||
{ |
|
||||
var ok bool |
|
||||
accessToken, ok = unmarshalledBody["access_token"] |
|
||||
if !ok { |
|
||||
return errors.New("No access token in reponse body") |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
c.accessToken = accessToken.(string) |
|
||||
|
|
||||
return nil |
|
||||
} |
|
||||
|
|
||||
func (c *client) do(path string, plugins ...plugin.Plugin) (*gentleman.Response, error) { |
|
||||
var req *gentleman.Request = c.httpClient.Get() |
|
||||
{ |
|
||||
req = req.Path(path) |
|
||||
req = req.SetHeader("Authorization", fmt.Sprintf("Bearer %s", c.accessToken)) |
|
||||
for _, p := range plugins { |
|
||||
req = req.Use(p) |
|
||||
} |
|
||||
} |
|
||||
var resp *gentleman.Response |
|
||||
{ |
|
||||
var err error |
|
||||
resp, err = req.Do() |
|
||||
if err != nil { |
|
||||
return nil, errors.Wrap(err, "Failed to get the response") |
|
||||
} |
|
||||
switch resp.StatusCode { |
|
||||
case http.StatusUnauthorized: |
|
||||
var err = c.getToken() |
|
||||
//This induces a potential infinite loop, where a new token gets requested and the
|
|
||||
//process gets delayed so much it expires before the recursion.
|
|
||||
//It is decided that should this happen, the machine would be considered to be in terrible shape
|
|
||||
//and the loop wouldn't be the biggest problem.
|
|
||||
if err != nil { |
|
||||
return nil, errors.Wrap(err, "Failed to get token") |
|
||||
} |
|
||||
return c.do(path) |
|
||||
default: |
|
||||
return resp, nil |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,35 @@ |
|||||
|
package client |
||||
|
|
||||
|
import ( |
||||
|
"gopkg.in/h2non/gentleman.v2/plugins/body" |
||||
|
"gopkg.in/h2non/gentleman.v2/plugins/url" |
||||
|
) |
||||
|
|
||||
|
const ( |
||||
|
realmRootPath = "/auth/admin/realms" |
||||
|
realmPath = realmRootPath + "/:realm" |
||||
|
) |
||||
|
|
||||
|
func (c *client) GetRealms() ([]RealmRepresentation, error) { |
||||
|
var resp = []RealmRepresentation{} |
||||
|
var err = c.get(&resp, url.Path(realmRootPath)) |
||||
|
return resp, err |
||||
|
} |
||||
|
|
||||
|
func (c *client) CreateRealm(realm RealmRepresentation) error { |
||||
|
return c.post(url.Path(realmRootPath), body.JSON(realm)) |
||||
|
} |
||||
|
|
||||
|
func (c *client) GetRealm(realm string) (RealmRepresentation, error) { |
||||
|
var resp = RealmRepresentation{} |
||||
|
var err = c.get(&resp, url.Path(realmPath), url.Param("realm", realm)) |
||||
|
return resp, err |
||||
|
} |
||||
|
|
||||
|
func (c *client) UpdateRealm(realmName string, realm RealmRepresentation) error { |
||||
|
return c.put(url.Path(realmPath), url.Param("realm", realmName), body.JSON(realm)) |
||||
|
} |
||||
|
|
||||
|
func (c *client) DeleteRealm(realm string) error { |
||||
|
return c.delete(url.Path(realmPath), url.Param("realm", realm)) |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
package client |
||||
|
|
||||
|
import ( |
||||
|
"testing" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
) |
||||
|
|
||||
|
func TestGetRealms(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
var realms []RealmRepresentation |
||||
|
{ |
||||
|
var err error |
||||
|
realms, err = client.GetRealms() |
||||
|
require.Nil(t, err, "could not get realms") |
||||
|
assert.NotNil(t, realms) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func TestCreateRealm(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
var realm = RealmRepresentation{ |
||||
|
Realm: str("__internal"), |
||||
|
} |
||||
|
var err = client.CreateRealm(realm) |
||||
|
assert.Nil(t, err) |
||||
|
} |
||||
|
|
||||
|
func TestGetRealm(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
|
||||
|
var realm, err = client.GetRealm("__internal") |
||||
|
assert.Nil(t, err) |
||||
|
assert.NotNil(t, realm) |
||||
|
} |
||||
|
|
||||
|
func TestUpdateRealm(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
|
||||
|
var realm = RealmRepresentation{ |
||||
|
DisplayName: str("Test realm"), |
||||
|
} |
||||
|
var err = client.UpdateRealm("__internal", realm) |
||||
|
assert.Nil(t, err) |
||||
|
} |
||||
|
func TestDeleteRealm(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
|
||||
|
var err = client.DeleteRealm("__internal") |
||||
|
assert.Nil(t, err) |
||||
|
} |
||||
@ -1,29 +0,0 @@ |
|||||
package client |
|
||||
|
|
||||
|
|
||||
import ( |
|
||||
"github.com/pkg/errors" |
|
||||
gentleman "gopkg.in/h2non/gentleman.v2" |
|
||||
"encoding/json" |
|
||||
) |
|
||||
|
|
||||
func (c *client) GetRealms() ([]RealmRepresentation, error) { |
|
||||
var getRealms_Path string = "/auth/admin/realms" |
|
||||
var resp *gentleman.Response |
|
||||
{ |
|
||||
var err error |
|
||||
resp, err = c.do(getRealms_Path) |
|
||||
if err != nil { |
|
||||
return nil, errors.Wrap(err, "Get Realms failed.") |
|
||||
} |
|
||||
} |
|
||||
var result []RealmRepresentation |
|
||||
{ |
|
||||
var err error |
|
||||
err = json.Unmarshal(resp.Bytes(), &result) |
|
||||
if err != nil { |
|
||||
return nil, errors.Wrap(err, "Get Realms failed to unmarshal response.") |
|
||||
} |
|
||||
} |
|
||||
return result, nil |
|
||||
} |
|
||||
@ -0,0 +1,42 @@ |
|||||
|
package client |
||||
|
|
||||
|
import ( |
||||
|
"gopkg.in/h2non/gentleman.v2/plugins/body" |
||||
|
"gopkg.in/h2non/gentleman.v2/plugins/url" |
||||
|
) |
||||
|
|
||||
|
const ( |
||||
|
userPath = "/auth/admin/realms/:realm/users" |
||||
|
userCountPath = userPath + "/count" |
||||
|
userIDPath = userPath + "/:id" |
||||
|
) |
||||
|
|
||||
|
func (c *client) GetUsers(realm string) ([]UserRepresentation, error) { |
||||
|
var resp = []UserRepresentation{} |
||||
|
var err = c.get(&resp, url.Path(userPath), url.Param("realm", realm)) |
||||
|
return resp, err |
||||
|
} |
||||
|
|
||||
|
func (c *client) CreateUser(realm string, user UserRepresentation) error { |
||||
|
return c.post(url.Path(userPath), url.Param("realm", realm), body.JSON(user)) |
||||
|
} |
||||
|
|
||||
|
func (c *client) CountUsers(realm string) (int, error) { |
||||
|
var resp = 0 |
||||
|
var err = c.get(&resp, url.Path(userCountPath), url.Param("realm", realm)) |
||||
|
return resp, err |
||||
|
} |
||||
|
|
||||
|
func (c *client) GetUser(realm, userID string) (UserRepresentation, error) { |
||||
|
var resp = UserRepresentation{} |
||||
|
var err = c.get(&resp, url.Path(userIDPath), url.Param("realm", realm), url.Param("id", userID)) |
||||
|
return resp, err |
||||
|
} |
||||
|
|
||||
|
func (c *client) UpdateUser(realm, userID string, user UserRepresentation) error { |
||||
|
return c.put(url.Path(userIDPath), url.Param("realm", realm), url.Param("id", userID), body.JSON(user)) |
||||
|
} |
||||
|
|
||||
|
func (c *client) DeleteUser(realm, userID string) error { |
||||
|
return c.delete(url.Path(userIDPath), url.Param("realm", realm), url.Param("id", userID)) |
||||
|
} |
||||
@ -0,0 +1,67 @@ |
|||||
|
package client |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"testing" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
"github.com/stretchr/testify/require" |
||||
|
) |
||||
|
|
||||
|
func TestGetUsers(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
var users []UserRepresentation |
||||
|
{ |
||||
|
var err error |
||||
|
users, err = client.GetUsers("__internal") |
||||
|
require.Nil(t, err, "could not get users") |
||||
|
} |
||||
|
for _, i := range users { |
||||
|
fmt.Println(*i.Username) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func TestCreateUser(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
var realm = "__internal" |
||||
|
var user = UserRepresentation{ |
||||
|
Username: str("johanr"), |
||||
|
} |
||||
|
var err = client.CreateUser(realm, user) |
||||
|
assert.Nil(t, err) |
||||
|
} |
||||
|
|
||||
|
func TestCountUsers(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
var realm = "__internal" |
||||
|
|
||||
|
var count, err = client.CountUsers(realm) |
||||
|
assert.Nil(t, err) |
||||
|
assert.NotZero(t, count) |
||||
|
} |
||||
|
func TestGetUser(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
var user UserRepresentation |
||||
|
{ |
||||
|
var err error |
||||
|
user, err = client.GetUser("__internal", "078f735b-ac07-4b39-88cb-88647c4ff47c") |
||||
|
require.Nil(t, err, "could not get users") |
||||
|
} |
||||
|
fmt.Println(*user.Username) |
||||
|
} |
||||
|
|
||||
|
func TestUpdateUser(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
|
||||
|
var user = UserRepresentation{ |
||||
|
Email: str("john.doe@elca.ch"), |
||||
|
} |
||||
|
var err = client.UpdateUser("__internal", "078f735b-ac07-4b39-88cb-88647c4ff47c", user) |
||||
|
assert.Nil(t, err) |
||||
|
} |
||||
|
func TestDeleteUser(t *testing.T) { |
||||
|
var client = initTest(t) |
||||
|
|
||||
|
var err = client.DeleteUser("__internal", "078f735b-ac07-4b39-88cb-88647c4ff47c") |
||||
|
assert.Nil(t, err) |
||||
|
} |
||||
@ -1,29 +0,0 @@ |
|||||
package client |
|
||||
|
|
||||
import ( |
|
||||
"fmt" |
|
||||
"gopkg.in/h2non/gentleman.v2" |
|
||||
"github.com/pkg/errors" |
|
||||
"encoding/json" |
|
||||
) |
|
||||
|
|
||||
func (c *client)GetUsers(realm string) ([]UserRepresentation, error) { |
|
||||
var getUsers_Path string = fmt.Sprintf("/auth/admin/realms/%s/users", realm) |
|
||||
var resp *gentleman.Response |
|
||||
{ |
|
||||
var err error |
|
||||
resp, err = c.do(getUsers_Path) |
|
||||
if err != nil { |
|
||||
return nil, errors.Wrap(err, "Get Realms failed.") |
|
||||
} |
|
||||
} |
|
||||
var result []UserRepresentation |
|
||||
{ |
|
||||
var err error |
|
||||
err = json.Unmarshal(resp.Bytes(), &result) |
|
||||
if err != nil { |
|
||||
return nil, errors.Wrap(err, "Get Users failed to unmarshal response.") |
|
||||
} |
|
||||
} |
|
||||
return result, nil |
|
||||
} |
|
||||
@ -0,0 +1,2 @@ |
|||||
|
// Keycloak client is a client for keycloak.
|
||||
|
package keycloakclient |
||||
Loading…
Reference in new issue