2020-05-18 14:18:38 +02:00
Ext . define ( 'pmx-users' , {
extend : 'Ext.data.Model' ,
fields : [
2023-06-27 13:27:07 +02:00
'userid' , 'firstname' , 'lastname' , 'email' , 'comment' , 'totp-locked' ,
2020-05-18 14:18:38 +02:00
{ type : 'boolean' , name : 'enable' , defaultValue : true } ,
{ type : 'date' , dateFormat : 'timestamp' , name : 'expire' } ,
] ,
idProperty : 'userid' ,
proxy : {
type : 'proxmox' ,
url : '/api2/json/access/users' ,
} ,
} ) ;
Ext . define ( 'PBS.config.UserView' , {
extend : 'Ext.grid.GridPanel' ,
alias : 'widget.pbsUserView' ,
stateful : true ,
stateId : 'grid-users' ,
title : gettext ( 'Users' ) ,
controller : {
xclass : 'Ext.app.ViewController' ,
addUser : function ( ) {
let me = this ;
Ext . create ( 'PBS.window.UserEdit' , {
listeners : {
destroy : function ( ) {
me . reload ( ) ;
} ,
} ,
} ) . show ( ) ;
} ,
editUser : function ( ) {
let me = this ;
let view = me . getView ( ) ;
let selection = view . getSelection ( ) ;
if ( selection . length < 1 ) return ;
Ext . create ( 'PBS.window.UserEdit' , {
userid : selection [ 0 ] . data . userid ,
listeners : {
destroy : function ( ) {
me . reload ( ) ;
} ,
} ,
} ) . show ( ) ;
} ,
2020-08-03 11:56:25 +02:00
setPassword : function ( ) {
let me = this ;
let view = me . getView ( ) ;
let selection = view . getSelection ( ) ;
if ( selection . length < 1 ) return ;
Ext . create ( 'PBS.window.UserPassword' , {
url : '/api2/extjs/access/users/' + selection [ 0 ] . data . userid ,
} ) . show ( ) ;
} ,
2020-10-21 09:42:56 +02:00
showPermissions : function ( ) {
let me = this ;
let view = me . getView ( ) ;
let selection = view . getSelection ( ) ;
if ( selection . length < 1 ) return ;
Ext . create ( 'Proxmox.PermissionView' , {
auth _id : selection [ 0 ] . data . userid ,
2020-10-30 15:18:41 +01:00
auth _id _name : 'auth-id' ,
2020-10-21 09:42:56 +02:00
} ) . show ( ) ;
} ,
2020-11-11 13:34:14 +01:00
renderName : function ( val , cell , rec ) {
let name = [ ] ;
if ( rec . data . firstname ) {
name . push ( rec . data . firstname ) ;
}
if ( rec . data . lastname ) {
name . push ( rec . data . lastname ) ;
}
return name . join ( ' ' ) ;
} ,
2020-05-18 14:18:38 +02:00
renderUsername : function ( userid ) {
return Ext . String . htmlEncode ( userid . match ( /^(.+)@([^@]+)$/ ) [ 1 ] ) ;
} ,
renderRealm : function ( userid ) {
return Ext . String . htmlEncode ( userid . match ( /^(.+)@([^@]+)$/ ) [ 2 ] ) ;
} ,
reload : function ( ) { this . getView ( ) . getStore ( ) . rstore . load ( ) ; } ,
2020-05-26 12:23:26 +02:00
init : function ( view ) {
Proxmox . Utils . monStoreErrors ( view , view . getStore ( ) . rstore ) ;
} ,
2023-06-27 12:04:51 +02:00
unlockTfa : function ( btn , event , rec ) {
let me = this ;
let view = me . getView ( ) ;
Ext . Msg . confirm (
Ext . String . format ( gettext ( 'Unlock TFA authentication for {0}' ) , rec . data . userid ) ,
gettext ( "Locked 2nd factors can happen if the user's password was leaked. Are you sure you want to unlock the user?" ) ,
function ( btn _response ) {
if ( btn _response === 'yes' ) {
Proxmox . Utils . API2Request ( {
url : ` /access/users/ ${ rec . data . userid } /unlock-tfa ` ,
waitMsgTarget : view ,
method : 'PUT' ,
failure : function ( response , options ) {
Ext . Msg . alert ( gettext ( 'Error' ) , response . htmlStatus ) ;
} ,
success : function ( response , options ) {
me . reload ( ) ;
} ,
} ) ;
}
} ,
) ;
} ,
2020-05-18 14:18:38 +02:00
} ,
listeners : {
activate : 'reload' ,
itemdblclick : 'editUser' ,
} ,
store : {
type : 'diff' ,
autoDestroy : true ,
autoDestroyRstore : true ,
sorters : 'userid' ,
rstore : {
type : 'update' ,
storeid : 'pmx-users' ,
model : 'pmx-users' ,
autoStart : true ,
interval : 5000 ,
} ,
} ,
tbar : [
{
xtype : 'proxmoxButton' ,
text : gettext ( 'Add' ) ,
handler : 'addUser' ,
selModel : false ,
} ,
2021-01-18 09:33:29 +01:00
'-' ,
2020-05-18 14:18:38 +02:00
{
xtype : 'proxmoxButton' ,
text : gettext ( 'Edit' ) ,
handler : 'editUser' ,
disabled : true ,
} ,
{
xtype : 'proxmoxStdRemoveButton' ,
baseurl : '/access/users/' ,
enableFn : ( rec ) => rec . data . userid !== 'root@pam' ,
2021-01-19 14:33:23 +01:00
getUrl : ( rec ) =>
` /access/users/ ${ encodeURIComponent ( rec . getId ( ) ) } ` ,
2020-05-18 14:18:38 +02:00
callback : 'reload' ,
} ,
2021-01-18 09:33:29 +01:00
'-' ,
{
xtype : 'proxmoxButton' ,
text : gettext ( 'Change Password' ) ,
handler : 'setPassword' ,
disabled : true ,
} ,
2020-10-21 09:42:56 +02:00
{
xtype : 'proxmoxButton' ,
2021-01-18 09:33:29 +01:00
text : gettext ( 'Show Permissions' ) ,
2020-10-21 09:42:56 +02:00
handler : 'showPermissions' ,
disabled : true ,
} ,
2023-06-23 14:44:04 +02:00
'-' ,
{
xtype : 'proxmoxButton' ,
text : gettext ( 'Unlock TFA' ) ,
handler : 'unlockTfa' ,
2023-06-26 19:55:52 +02:00
enableFn : ( { data } ) =>
data [ 'totp-locked' ] || ( data [ 'tfa-locked-until' ] > ( new Date ( ) . getTime ( ) / 1000 ) ) ,
2023-06-23 14:44:04 +02:00
} ,
2020-05-18 14:18:38 +02:00
] ,
viewConfig : {
trackOver : false ,
} ,
columns : [
{
header : gettext ( 'User name' ) ,
width : 200 ,
sortable : true ,
renderer : 'renderUsername' ,
dataIndex : 'userid' ,
} ,
{
header : gettext ( 'Realm' ) ,
width : 100 ,
sortable : true ,
renderer : 'renderRealm' ,
dataIndex : 'userid' ,
} ,
{
header : gettext ( 'Enabled' ) ,
width : 80 ,
sortable : true ,
renderer : Proxmox . Utils . format _boolean ,
dataIndex : 'enable' ,
} ,
{
header : gettext ( 'Expire' ) ,
width : 80 ,
sortable : true ,
renderer : Proxmox . Utils . format _expire ,
dataIndex : 'expire' ,
} ,
{
header : gettext ( 'Name' ) ,
width : 150 ,
sortable : true ,
dataIndex : 'firstname' ,
2020-11-11 13:34:14 +01:00
renderer : 'renderName' ,
2020-05-18 14:18:38 +02:00
} ,
2023-06-23 14:44:04 +02:00
{
header : gettext ( 'TFA Lock' ) ,
width : 120 ,
sortable : true ,
dataIndex : 'totp-locked' ,
renderer : function ( v , metaData , record ) {
let locked _until = record . data [ 'tfa-locked-until' ] ;
if ( locked _until !== undefined ) {
let now = new Date ( ) . getTime ( ) / 1000 ;
if ( locked _until > now ) {
return gettext ( 'Locked' ) ;
}
}
if ( record . data [ 'totp-locked' ] ) {
return gettext ( 'TOTP Locked' ) ;
}
return Proxmox . Utils . noText ;
} ,
} ,
2020-05-18 14:18:38 +02:00
{
header : gettext ( 'Comment' ) ,
sortable : false ,
renderer : Ext . String . htmlEncode ,
dataIndex : 'comment' ,
flex : 1 ,
} ,
] ,
} ) ;