Session Refactor: Add auth module label to session's list (#94958)

* Add AuthModule to token API

* Add badge to UserSessions

* Change idp label rendering

* Render IdP label for User Profile page

* Add i18n labels
This commit is contained in:
linoman 2024-10-22 10:57:36 +02:00 committed by GitHub
parent 200c613672
commit 3270a9c959
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 36 additions and 1 deletions

View File

@ -11,6 +11,7 @@ type UserToken struct {
OperatingSystemVersion string `json:"osVersion"`
Browser string `json:"browser"`
BrowserVersion string `json:"browserVersion"`
AuthModule string `json:"authModule"`
CreatedAt time.Time `json:"createdAt"`
SeenAt time.Time `json:"seenAt"`
}

View File

@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/authn"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@ -224,6 +225,12 @@ func (hs *HTTPServer) getUserAuthTokensInternal(c *contextmodel.ReqContext, user
seenAt = createdAt
}
// Retrieve AuthModule from external session
authModule := ""
if externalSession, err := hs.AuthTokenService.GetExternalSession(c.Req.Context(), token.ExternalSessionId); err == nil {
authModule = login.GetAuthProviderLabel(externalSession.AuthModule)
}
result = append(result, &dtos.UserToken{
Id: token.Id,
IsActive: isActive,
@ -233,6 +240,7 @@ func (hs *HTTPServer) getUserAuthTokensInternal(c *contextmodel.ReqContext, user
OperatingSystemVersion: osVersion,
Browser: client.UserAgent.Family,
BrowserVersion: browserVersion,
AuthModule: authModule,
CreatedAt: createdAt,
SeenAt: seenAt,
})

View File

@ -2,6 +2,7 @@ package authtest
import (
"context"
"errors"
"net"
"time"
@ -65,6 +66,9 @@ func NewFakeUserAuthTokenService() *FakeUserAuthTokenService {
GetUserTokensProvider: func(ctx context.Context, userId int64) ([]*auth.UserToken, error) {
return nil, nil
},
GetExternalSessionProvider: func(ctx context.Context, externalSessionID int64) (*auth.ExternalSession, error) {
return nil, errors.New("settings Provider table not found")
},
}
}

View File

@ -1,7 +1,9 @@
import { createRef, PureComponent } from 'react';
import { ConfirmButton, ConfirmModal, Button, Stack } from '@grafana/ui';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
import { contextSrv } from 'app/core/core';
import { Trans } from 'app/core/internationalization';
import { formatDate } from 'app/core/internationalization/dates';
import { AccessControlAction, UserSession } from 'app/types';
@ -60,7 +62,10 @@ class BaseUserSessions extends PureComponent<Props, State> {
<th>Last seen</th>
<th>Logged on</th>
<th>IP address</th>
<th colSpan={2}>Browser and OS</th>
<th>Browser and OS</th>
<th colSpan={2}>
<Trans i18nKey="user-session.auth-module-column">Identity Provider</Trans>
</th>
</tr>
</thead>
<tbody>
@ -71,6 +76,9 @@ class BaseUserSessions extends PureComponent<Props, State> {
<td>{formatDate(session.createdAt, { dateStyle: 'long' })}</td>
<td>{session.clientIp}</td>
<td>{`${session.browser} on ${session.os} ${session.osVersion}`}</td>
<td>
{session.authModule && <TagBadge label={session.authModule} removeIcon={false} count={0} />}
</td>
<td>
{canLogout && (
<ConfirmButton

View File

@ -171,6 +171,7 @@ export function loadUserSessions(userId: number): ThunkResult<void> {
clientIp: session.clientIp,
browser: session.browser,
browserVersion: session.browserVersion,
authModule: session.authModule,
os: session.os,
osVersion: session.osVersion,
device: session.device,

View File

@ -4,6 +4,7 @@ import { PureComponent } from 'react';
import { selectors } from '@grafana/e2e-selectors';
import { Button, Icon, LoadingPlaceholder } from '@grafana/ui';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
import { Trans } from 'app/core/internationalization';
import { formatDate } from 'app/core/internationalization/dates';
import { UserSession } from 'app/types';
@ -43,6 +44,9 @@ class UserSessions extends PureComponent<Props> {
<th>
<Trans i18nKey="user-session.browser-column">Browser & OS</Trans>
</th>
<th>
<Trans i18nKey="user-session.identity-provider-column">Identity Provider</Trans>
</th>
<th></th>
</tr>
</thead>
@ -56,6 +60,9 @@ class UserSessions extends PureComponent<Props> {
<td>
{session.browser} on {session.os} {session.osVersion}
</td>
<td>
{session.authModule && <TagBadge label={session.authModule} removeIcon={false} count={0} />}
</td>
<td>
<Button
size="sm"

View File

@ -82,6 +82,7 @@ export const slice = createSlice({
clientIp: session.clientIp,
browser: session.browser,
browserVersion: session.browserVersion,
authModule: session.authModule,
os: session.os,
osVersion: session.osVersion,
device: session.device,

View File

@ -95,6 +95,7 @@ export interface UserSession {
seenAt: string;
browser: string;
browserVersion: string;
authModule?: string;
os: string;
osVersion: string;
device: string;

View File

@ -2888,8 +2888,10 @@
}
},
"user-session": {
"auth-module-column": "Identity Provider",
"browser-column": "Browser & OS",
"created-at-column": "Logged on",
"identity-provider-column": "Identity Provider",
"ip-column": "IP address",
"revoke": "Revoke user session",
"seen-at-column": "Last seen"

View File

@ -2888,8 +2888,10 @@
}
},
"user-session": {
"auth-module-column": "Ĩđęʼnŧįŧy Přővįđęř",
"browser-column": "ßřőŵşęř & ØŜ",
"created-at-column": "Ŀőģģęđ őʼn",
"identity-provider-column": "Ĩđęʼnŧįŧy Přővįđęř",
"ip-column": "ĨP äđđřęşş",
"revoke": "Ŗęvőĸę ūşęř şęşşįőʼn",
"seen-at-column": "Ŀäşŧ şęęʼn"