Skip to content

Commit

Permalink
Added params for getting sessions associated with client (#436)
Browse files Browse the repository at this point in the history
* Added params GetClientUserSessionsParams for GetClientUserSessions and GetClientOfflineSessions

* Made the params for the GetClientUserSessions and GetClientOfflineSessions variadic functions

---------

Co-authored-by: Dmitry Zakovyrin <dzakovyrin@tdera.ru>
  • Loading branch information
mopo3ula and Dmitry Zakovyrin authored Jul 25, 2023
1 parent f08754e commit 7f490d9
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 7 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ type GoCloak interface {
ClearUserCache(ctx context.Context, token, realm string) error
ClearKeysCache(ctx context.Context, token, realm string) error

GetClientUserSessions(ctx context.Context, token, realm, idOfClient string) ([]*UserSessionRepresentation, error)
GetClientOfflineSessions(ctx context.Context, token, realm, idOfClient string) ([]*UserSessionRepresentation, error)
GetClientUserSessions(ctx context.Context, token, realm, idOfClient string, params ...GetClientUserSessionsParams) ([]*UserSessionRepresentation, error)
GetClientOfflineSessions(ctx context.Context, token, realm, idOfClient string, params ...GetClientUserSessionsParams) ([]*UserSessionRepresentation, error)
GetUserSessions(ctx context.Context, token, realm, userID string) ([]*UserSessionRepresentation, error)
GetUserOfflineSessionsForClient(ctx context.Context, token, realm, userID, idOfClient string) ([]*UserSessionRepresentation, error)

Expand Down
30 changes: 26 additions & 4 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1451,12 +1451,23 @@ func (g *GoCloak) RegenerateClientSecret(ctx context.Context, token, realm, idOf
}

// GetClientOfflineSessions returns offline sessions associated with the client
func (g *GoCloak) GetClientOfflineSessions(ctx context.Context, token, realm, idOfClient string) ([]*UserSessionRepresentation, error) {
func (g *GoCloak) GetClientOfflineSessions(ctx context.Context, token, realm, idOfClient string, params ...GetClientUserSessionsParams) ([]*UserSessionRepresentation, error) {
const errMessage = "could not get client offline sessions"

var res []*UserSessionRepresentation

queryParams := map[string]string{}
if params != nil && len(params) > 0 {
var err error

queryParams, err = GetQueryParams(params[0])
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
}

resp, err := g.GetRequestWithBearerAuth(ctx, token).
SetResult(&res).
SetQueryParams(queryParams).
Get(g.getAdminRealmURL(realm, "clients", idOfClient, "offline-sessions"))

if err := checkForError(resp, err, errMessage); err != nil {
Expand All @@ -1467,12 +1478,23 @@ func (g *GoCloak) GetClientOfflineSessions(ctx context.Context, token, realm, id
}

// GetClientUserSessions returns user sessions associated with the client
func (g *GoCloak) GetClientUserSessions(ctx context.Context, token, realm, idOfClient string) ([]*UserSessionRepresentation, error) {
func (g *GoCloak) GetClientUserSessions(ctx context.Context, token, realm, idOfClient string, params ...GetClientUserSessionsParams) ([]*UserSessionRepresentation, error) {
const errMessage = "could not get client user sessions"

var res []*UserSessionRepresentation

queryParams := map[string]string{}
if params != nil && len(params) > 0 {
var err error

queryParams, err = GetQueryParams(params[0])
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
}

resp, err := g.GetRequestWithBearerAuth(ctx, token).
SetResult(&res).
SetQueryParams(queryParams).
Get(g.getAdminRealmURL(realm, "clients", idOfClient, "user-sessions"))

if err := checkForError(resp, err, errMessage); err != nil {
Expand Down
52 changes: 51 additions & 1 deletion client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3719,14 +3719,52 @@ func Test_GetClientUserSessions(t *testing.T) {
)
require.NoError(t, err, "Login failed")
token := GetAdminToken(t, client)
allSessionsWithoutParams, err := client.GetClientUserSessions(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
gocloakClientID,
)
require.NoError(t, err, "GetClientUserSessions failed")
require.NotEmpty(t, allSessionsWithoutParams, "GetClientUserSessions returned an empty list")

allSessions, err := client.GetClientUserSessions(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
gocloakClientID,
gocloak.GetClientUserSessionsParams{},
)
require.NoError(t, err, "GetClientUserSessions failed")
require.NotEmpty(t, allSessions, "GetClientUserSessions returned an empty list")
require.Equal(t, allSessionsWithoutParams, allSessions,
"GetClientUserSessions with and without params are not the same")

sessions, err := client.GetClientUserSessions(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
gocloakClientID,
gocloak.GetClientUserSessionsParams{
Max: gocloak.IntP(1),
},
)
require.NoError(t, err, "GetClientUserSessions failed")
require.NotEmpty(t, sessions, "GetClientUserSessions returned an empty list")
require.Len(t, sessions, 1)

sessions, err = client.GetClientUserSessions(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
gocloakClientID,
gocloak.GetClientUserSessionsParams{
Max: gocloak.IntP(1),
First: gocloak.IntP(1),
},
)
require.NoError(t, err, "GetClientUserSessions failed")
require.Len(t, sessions, 1)
require.Equal(t, *allSessions[1].ID, *sessions[0].ID)
}

func findProtocolMapperByID(t *testing.T, client *gocloak.Client, id string) *gocloak.ProtocolMapperRepresentation {
Expand Down Expand Up @@ -3865,9 +3903,21 @@ func Test_GetClientOfflineSessions(t *testing.T) {
token.AccessToken,
cfg.GoCloak.Realm,
gocloakClientID,
gocloak.GetClientUserSessionsParams{},
)
require.NoError(t, err, "GetClientOfflineSessions failed")
require.NotEmpty(t, sessions, "GetClientOfflineSessions returned an empty list")

sessionsWithoutParams, err := client.GetClientOfflineSessions(
context.Background(),
token.AccessToken,
cfg.GoCloak.Realm,
gocloakClientID,
)
require.NoError(t, err, "GetClientOfflineSessions failed")
require.NotEmpty(t, sessions, "GetClientOfflineSessions returned an empty list")
require.Equal(t, sessions, sessionsWithoutParams,
"GetClientOfflineSessions with and without params are not the same")
}

func Test_ClientSecret(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ func TestStringerOmitEmpty(t *testing.T) {
&gocloak.GetClientsParams{},
&gocloak.RequestingPartyTokenOptions{},
&gocloak.RequestingPartyPermission{},
&gocloak.GetClientUserSessionsParams{},
}

for _, custom := range customs {
Expand Down
7 changes: 7 additions & 0 deletions models.go
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,12 @@ type ManagementPermissionRepresentation struct {
ScopePermissions *map[string]string `json:"scopePermissions,omitempty"`
}

// GetClientUserSessionsParams represents the optional parameters for getting user sessions associated with the client
type GetClientUserSessionsParams struct {
First *int `json:"first,string,omitempty"`
Max *int `json:"max,string,omitempty"`
}

// prettyStringStruct returns struct formatted into pretty string
func prettyStringStruct(t interface{}) string {
json, err := json.MarshalIndent(t, "", "\t")
Expand Down Expand Up @@ -1509,3 +1515,4 @@ func (v *GetResourcePoliciesParams) String() string { return pre
func (v *CredentialRepresentation) String() string { return prettyStringStruct(v) }
func (v *RequiredActionProviderRepresentation) String() string { return prettyStringStruct(v) }
func (v *BruteForceStatus) String() string { return prettyStringStruct(v) }
func (v *GetClientUserSessionsParams) String() string { return prettyStringStruct(v) }

0 comments on commit 7f490d9

Please sign in to comment.