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"` OperatingSystemVersion string `json:"osVersion"`
Browser string `json:"browser"` Browser string `json:"browser"`
BrowserVersion string `json:"browserVersion"` BrowserVersion string `json:"browserVersion"`
AuthModule string `json:"authModule"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
SeenAt time.Time `json:"seenAt"` 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/auth"
"github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/authn"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" 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/services/user"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web" "github.com/grafana/grafana/pkg/web"
@ -224,6 +225,12 @@ func (hs *HTTPServer) getUserAuthTokensInternal(c *contextmodel.ReqContext, user
seenAt = createdAt 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{ result = append(result, &dtos.UserToken{
Id: token.Id, Id: token.Id,
IsActive: isActive, IsActive: isActive,
@ -233,6 +240,7 @@ func (hs *HTTPServer) getUserAuthTokensInternal(c *contextmodel.ReqContext, user
OperatingSystemVersion: osVersion, OperatingSystemVersion: osVersion,
Browser: client.UserAgent.Family, Browser: client.UserAgent.Family,
BrowserVersion: browserVersion, BrowserVersion: browserVersion,
AuthModule: authModule,
CreatedAt: createdAt, CreatedAt: createdAt,
SeenAt: seenAt, SeenAt: seenAt,
}) })

View File

@ -2,6 +2,7 @@ package authtest
import ( import (
"context" "context"
"errors"
"net" "net"
"time" "time"
@ -65,6 +66,9 @@ func NewFakeUserAuthTokenService() *FakeUserAuthTokenService {
GetUserTokensProvider: func(ctx context.Context, userId int64) ([]*auth.UserToken, error) { GetUserTokensProvider: func(ctx context.Context, userId int64) ([]*auth.UserToken, error) {
return nil, nil 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 { createRef, PureComponent } from 'react';
import { ConfirmButton, ConfirmModal, Button, Stack } from '@grafana/ui'; import { ConfirmButton, ConfirmModal, Button, Stack } from '@grafana/ui';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
import { contextSrv } from 'app/core/core'; import { contextSrv } from 'app/core/core';
import { Trans } from 'app/core/internationalization';
import { formatDate } from 'app/core/internationalization/dates'; import { formatDate } from 'app/core/internationalization/dates';
import { AccessControlAction, UserSession } from 'app/types'; import { AccessControlAction, UserSession } from 'app/types';
@ -60,7 +62,10 @@ class BaseUserSessions extends PureComponent<Props, State> {
<th>Last seen</th> <th>Last seen</th>
<th>Logged on</th> <th>Logged on</th>
<th>IP address</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> </tr>
</thead> </thead>
<tbody> <tbody>
@ -71,6 +76,9 @@ class BaseUserSessions extends PureComponent<Props, State> {
<td>{formatDate(session.createdAt, { dateStyle: 'long' })}</td> <td>{formatDate(session.createdAt, { dateStyle: 'long' })}</td>
<td>{session.clientIp}</td> <td>{session.clientIp}</td>
<td>{`${session.browser} on ${session.os} ${session.osVersion}`}</td> <td>{`${session.browser} on ${session.os} ${session.osVersion}`}</td>
<td>
{session.authModule && <TagBadge label={session.authModule} removeIcon={false} count={0} />}
</td>
<td> <td>
{canLogout && ( {canLogout && (
<ConfirmButton <ConfirmButton

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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