Skip to content

Commit

Permalink
Merge pull request #396 from GluuFederation/admin-ui-331-session-viewer
Browse files Browse the repository at this point in the history
feat(admin-ui): session viewer page
  • Loading branch information
duttarnab authored Sep 7, 2022
2 parents 1726893 + 6c2737d commit 80fd7c1
Show file tree
Hide file tree
Showing 14 changed files with 448 additions and 8 deletions.
15 changes: 12 additions & 3 deletions admin-ui/app/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"yes": "Yes",
"change_password": "Change Password",
"close": "Close",
"delete": "Delete"
"delete": "Delete",
"revoke": "Revoke"
},
"dashboard": {
"summary_title": "Actives Users & Access Token Stats",
Expand Down Expand Up @@ -57,6 +58,7 @@
"attributes": "Attributes",
"attribute_edit_type": "Attribute Edit Type",
"attribute_view_type": "Attribute View Type",
"auth_time": "Auth Time",
"authentication_method": "Authentication method for the Token Endpoint",
"authorization_code_access_token": "Authorization Code Access Token",
"average_of_mau": "Average of MAU",
Expand All @@ -71,6 +73,7 @@
"client_credentials_access_token": "Client Credentials Access Token",
"client_expiration_date": "Client Expiration Date",
"client_id": "Client Id",
"client_id_used": "Client Id Used",
"client_name": "Client name",
"client_secret": "Client secret",
"computation_pool_size": "Computation Pool Size",
Expand Down Expand Up @@ -113,7 +116,9 @@
"in_memory_configuration": "inMemoryConfiguration",
"internal": "Internal",
"introspection_scripts": "Introspection",
"ropcScripts": "Password Grant",
"inum": "inum",
"ip_address": "IP Address",
"is_active": "Active",
"is_expirable_client": "Is Expirable Client?",
"is_trusted_client": "Supress authorization",
Expand Down Expand Up @@ -171,7 +176,6 @@
"required_ssl": "Required SSL",
"response_types": "Response types",
"revision": "Revision",
"ropcScripts": "Password Grant",
"rpt_scripts": "RPT Modification Script",
"saml1_uri": "Saml1 URI",
"saml2_uri": "Saml2 URI",
Expand All @@ -190,6 +194,8 @@
"sentinel_master_group_name": "sentinelMasterGroupName",
"servers": "Server Details",
"show_in_configuration_endpoint": "Show in configuration endpoint",
"s_id": "Session ID",
"session_expired": "Session Expired",
"smtp_server_port": "SMTP server port",
"smtp_test_status": "Smtp Test Status",
"smtp_user_name": "SMTP User Name",
Expand All @@ -206,6 +212,7 @@
"ssl_trust_store_file_path": "sslTrustStoreFilePath",
"ssl_trust_store_format": "SSL Trust Store Format",
"ssl_trust_store_pin": "SSL Trust Store Pin",
"state": "State",
"status": "Status",
"scopes": "Scopes",
"subject_type": "id_token subject type",
Expand Down Expand Up @@ -294,7 +301,8 @@
"creationTime": "Creation Time",
"select_date_range":"Select a date range",
"scope": "Scope",
"scopeExpression": "Scope Expression"
"scopeExpression": "Scope Expression",
"selectUserRevoke": "Select the user to revoke"
},
"languages": {
"french": "French",
Expand Down Expand Up @@ -335,6 +343,7 @@
"scopes": "Scopes",
"scripts": "Scripts",
"services": "Services",
"sessions": "Sessions",
"settings": "Settings",
"signout": "Sign out",
"user_management": "User Management",
Expand Down
13 changes: 11 additions & 2 deletions admin-ui/app/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"scopes": "Portées",
"scripts": "Scénarios",
"services": "Prestations de service",
"sessions": "Séances",
"settings": "Paramètres",
"signout": "Déconnexion",
"user_management": "User Management",
Expand Down Expand Up @@ -90,7 +91,8 @@
"view": "Vue",
"yes": "Oui",
"close": "Fermer",
"delete": "Supprimez"
"delete": "Supprimez",
"revoke": "Révoquer"
},
"fields": {
"access_token_signing_alg": "Algorithme de signature de jeton d'accès",
Expand All @@ -100,6 +102,7 @@
"attributes": "Les attributs",
"attribute_edit_type": "Type de modification d'attribut",
"attribute_view_type": "Type de vue d'attribut",
"auth_time": "Heure d'authentification",
"authentication_method": "Méthode d'authentification pour le point de terminaison du jeton",
"authorization_code_access_token": "Jeton d'accès au code d'autorisation",
"average_of_mau": "Moyenne de MAU",
Expand All @@ -114,6 +117,7 @@
"client_credentials_access_token": "Jeton d'accès aux informations d'identification du client",
"client_expiration_date": "Date d'expiration du client",
"client_id": "Identité du client",
"client_id_used": "Identifiant client utilisé",
"client_name": "Nom du client",
"client_secret": "Secret du client",
"computation_pool_size": "Taille du pool de calcul",
Expand Down Expand Up @@ -157,6 +161,7 @@
"internal": "Interne",
"introspection_scripts": "Scripts d'introspection",
"inum": "inum",
"ip_address": "Adresse IP",
"is_active": "C'est actif",
"is_expirable_client": "est un client expirable ?",
"is_trusted_client": "Est un client de confiance",
Expand Down Expand Up @@ -225,6 +230,8 @@
"sentinel_master_group_name": "sentinelleMasterGroupName",
"servers": "Les serveurs",
"show_in_configuration_endpoint": "Afficher dans le point de terminaison de configuration",
"s_id": "ID de session",
"session_expired": "Session expirée",
"smtp_server_port": "Port du serveur SMTP",
"smtp_test_status": "État du test SMTP",
"smtp_user_name": "Nom d'utilisateur SMTP",
Expand All @@ -240,6 +247,7 @@
"ssl_trust_store_file_path": "sslTrustStoreFilePath",
"ssl_trust_store_format": "Format de magasin de confiance SSL",
"ssl_trust_store_pin": "NIP du magasin de confiance SSL",
"state": "État",
"status": "StatutStatut",
"subject_type": "Type de sujet",
"test_config": "Tester la configuration",
Expand Down Expand Up @@ -280,7 +288,8 @@
"associatedClient": "Client associé",
"creationTime": "Heure de création",
"portée": "Portée",
"scopeExpression": "Expression d'étendue"
"scopeExpression": "Expression d'étendue",
"selectUserRevoke": "Sélectionnez l'utilisateur à révoquer"
},
"messages": {
"action_commit_question": "Journal d'audit : vous souhaitez appliquer les modifications apportées sur cette page ?",
Expand Down
13 changes: 11 additions & 2 deletions admin-ui/app/locales/pt/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"scopes": "Scopes",
"scripts": "Scripts",
"services": "Serviços",
"sessions": "Sessão",
"settings": "Configurações",
"signout": "Sair",
"user_management": "User Management",
Expand Down Expand Up @@ -88,7 +89,8 @@
"view": "Visualizar",
"yes": "Sim",
"close": "Fechar",
"delete": "Deletar"
"delete": "Deletar",
"revoke": "Revogar"
},
"fields": {
"access_token_signing_alg": "Algoritmo de assinatura de token de acesso",
Expand All @@ -98,6 +100,7 @@
"attributes": "Atributos",
"attribute_edit_type": "Tipo de edição de atributo",
"attribute_view_type": "Tipo de visualização de atributo",
"auth_time": "Hora de autenticação",
"authentication_method": "Método de autenticação para o terminal de token",
"authorization_code_access_token": "Token de acesso ao código de autorização",
"average_of_mau": "Média de MAU",
Expand All @@ -112,6 +115,7 @@
"client_credentials_access_token": "Token de acesso de credenciais de cliente",
"client_expiration_date": "Data de Vencimento do Cliente",
"client_id": "ID do Cliente",
"client_id_used": "ID do cliente usado",
"client_name": "Nome do cliente",
"client_secret": "Segredo do cliente",
"computation_pool_size": "Tamanho do pool de computação",
Expand Down Expand Up @@ -155,6 +159,7 @@
"internal": "interno",
"introspection_scripts": "Scripts de introspecção",
"inum": "inum",
"ip_address": "Endereço de IP",
"is_active": "Está ativo",
"is_expirable_client": "É cliente expirável?",
"is_trusted_client": "É um cliente confiávelÉ um cliente confiável",
Expand Down Expand Up @@ -221,6 +226,8 @@
"sentinel_master_group_name": "sentinelMasterGroupName",
"servers": "Servidores",
"show_in_configuration_endpoint": "Mostrar ponto final na configuração",
"s_id": "ID da sessão",
"session_expired": "Sessão expirada",
"smtp_server_port": "Porta do servidor SMTP",
"smtp_test_status": "Status do teste Smtp",
"smtp_user_name": "Nome de usuário SMTP",
Expand All @@ -234,6 +241,7 @@
"ssl_trust_store_file_path": "sslTrustStoreFilePath",
"ssl_trust_store_format": "Formato SSL Trust Store",
"ssl_trust_store_pin": "Pin SSL Trust Store",
"state": "Estado",
"status": "Status",
"subject_type": "Tipo de Assunto",
"test_config": "Testar configuração",
Expand Down Expand Up @@ -274,7 +282,8 @@
"associatedClient": "Cliente Associado",
"creationTime": "Tempo de Criação",
"escopo": "Escopo",
"scopeExpression": "Expressão de escopo"
"scopeExpression": "Expressão de escopo",
"selectUserRevoke": "Selecione o usuário para revogar"
},
"messages": {
"action_commit_question": "Registro de auditoria: deseja aplicar as alterações feitas nesta página?",
Expand Down
5 changes: 4 additions & 1 deletion admin-ui/app/utils/PermChecker.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,12 @@ export const STAT_JANS_READ = 'jans_stat'
export const USER_READ = BASE_URL + '/config/user.readonly'
export const USER_WRITE = BASE_URL + '/config/user.write'

export const SESSION_READ = BASE_URL + '/jans-auth-server/session.readonly'
export const SESSION_DELETE = BASE_URL + '/jans-auth-server/session.delete'

export const hasPermission = (scopes, scope) => {
if (scopes) {
return scopes.includes(scope, 0)
return scopes.map(scp => scope === scp)
}
return false
}
Expand Down
1 change: 1 addition & 0 deletions admin-ui/plugins/auth-server/common/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export const FETCHING_SCOPES = 'Fetch scopes'
export const SEARCHING_SCRIPTS = 'Search scripts'
export const FETCHING_SCRIPTS = 'Fetch scripts'
export const FETCHING_JSON_PROPERTIES = 'Fetch json properties'
export const FETCHING_SESSIONS = 'Fetch session'

export const SIMPLE_PASSWORD_AUTH = 'simple_password_auth'
157 changes: 157 additions & 0 deletions admin-ui/plugins/auth-server/components/Sessions/SessionListPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import React, { useState, useEffect, useContext } from 'react'
import moment from 'moment'
import isEmpty from 'lodash/isEmpty'
import MaterialTable from '@material-table/core'
import Autocomplete from '@material-ui/lab/Autocomplete'
import { Paper, TextField, Box } from '@material-ui/core'
import { connect } from 'react-redux'
import { Button } from 'reactstrap'
import { Card, CardBody } from 'Components'
import GluuViewWrapper from 'Routes/Apps/Gluu/GluuViewWrapper'
import applicationStyle from 'Routes/Apps/Gluu/styles/applicationstyle'
import GluuDialog from 'Routes/Apps/Gluu/GluuDialog'
import { useTranslation } from 'react-i18next'
import { getSessions, revokeSession } from 'Plugins/auth-server/redux/actions/SessionActions'
import SetTitle from 'Utils/SetTitle'
import { ThemeContext } from 'Context/theme/themeContext'
import getThemeColor from 'Context/theme/config'
import {
hasPermission,
SESSION_DELETE,
} from 'Utils/PermChecker'

function SessionListPage({ sessions, permissions, loading, dispatch }) {
const { t } = useTranslation()
const myActions = []
const [item, setItem] = useState({})
const [modal, setModal] = useState(false)
const pageSize = localStorage.getItem('paggingSize') || 10
const toggle = () => setModal(!modal)
const theme = useContext(ThemeContext)
const selectedTheme = theme.state.theme
const themeColors = getThemeColor(selectedTheme)
const bgThemeColor = { background: themeColors.background }
const sessionUsername = sessions.map(session => session.sessionAttributes.auth_user)
const usernames = [...new Set(sessionUsername)]
const [revokeUsername, setRevokeUsername] = useState()

SetTitle(t('menus.sessions'))

const tableColumns = [
{ title: `${t('fields.s_id')}`, field: 'sessionAttributes.sid' },
{ title: `${t('fields.username')}`, field: 'sessionAttributes.auth_user' },
{ title: `${t('fields.ip_address')}`, field: 'sessionAttributes.remote_ip' },
{ title: `${t('fields.client_id_used')}`, field: 'sessionAttributes.client_id' },
{
title: `${t('fields.auth_time')}`,
field: 'authenticationTime',
render: (rowData) => (
<span>
{ moment(rowData.authenticationTime).format("ddd, MMM DD, YYYY h:mm:ss A") }
</span>
),
},
{ title: `ACR`, field: 'sessionAttributes.acr_values' },
{
title: `${t('fields.session_expired')}`,
field: 'expirationDate',
hidden: true,
render: (rowData) => (
<span>
{ moment(rowData.expirationDate).format("ddd, MMM DD, YYYY h:mm:ss A") }
</span>
),
},
{ title: `${t('fields.state')}`, field: 'state' },
]

useEffect(() => {
dispatch(getSessions())
}, [])

const handleRevoke = () => {
const row = !isEmpty(sessions) ? sessions.find(({ sessionAttributes }) => sessionAttributes.auth_user === revokeUsername) : null
if (row) {
setItem(row)
toggle()
}
}

const onRevokeConfirmed = (message) => {
const { userDn } = item
const params = { userDn, action_message: message }
dispatch(revokeSession(params))
toggle()
}

return (
<Card style={applicationStyle.mainCard}>
<CardBody>
<GluuViewWrapper canShow>
{hasPermission(permissions, SESSION_DELETE) && (
<Box display="flex" justifyContent="flex-end">
<Box display="flex" alignItems="center" fontSize="16px" mr="20px">
{t('fields.selectUserRevoke')}
</Box>
<Autocomplete
id="combo-box-demo"
options={usernames}
getOptionLabel={(option) => option}
style={{ width: 300 }}
onChange={(_, value) => setRevokeUsername(value)}
renderInput={(params) => <TextField {...params} label="Username" variant="outlined" />}
/>
{revokeUsername && (
<Button
color={`danger`}
style={{ marginLeft: 20 }}
onClick={handleRevoke}
>
{t('actions.revoke')}
</Button>
)}
</Box>
)}
<MaterialTable
components={{
Container: (props) => <Paper {...props} elevation={0} />,
}}
columns={tableColumns}
data={sessions}
isLoading={loading}
title=""
actions={myActions}
options={{
columnsButton: true,
search: true,
searchFieldAlignment: 'left',
selection: false,
pageSize: pageSize,
headerStyle: { ...applicationStyle.tableHeaderStyle, ...bgThemeColor },
actionsColumnIndex: -1
}}
/>
</GluuViewWrapper>
{!isEmpty(item) && (
<GluuDialog
row={item}
name={item.sessionAttributes.auth_user}
handler={toggle}
modal={modal}
subject="user session revoke"
onAccept={onRevokeConfirmed}
/>
)}
</CardBody>
</Card>
)
}

const mapStateToProps = (state) => {
return {
sessions: state.sessionReducer.items,
loading: state.sessionReducer.loading,
permissions: state.authReducer.permissions,
}
}
export default connect(mapStateToProps)(SessionListPage)
Loading

0 comments on commit 80fd7c1

Please sign in to comment.