554 lines
16 KiB
PHP
554 lines
16 KiB
PHP
<?php
|
|
namespace Controllers;
|
|
|
|
class UsersController
|
|
{
|
|
private const ADMIN_USER_ID = 1;
|
|
private const IMPERSONATOR_SESSION_KEY = 'impersonator_user';
|
|
|
|
public static function mainView()
|
|
{
|
|
global $user, $mdb;
|
|
|
|
if ( !$user )
|
|
return \controls\Users::login_form();
|
|
|
|
$impersonator_user = self::getImpersonatorUser();
|
|
if ( !self::canManageUsers( $user, $impersonator_user ) )
|
|
self::forbiddenRedirect();
|
|
|
|
$users_repository = new \Domain\Users\UserRepository();
|
|
$all_users = $users_repository -> all();
|
|
|
|
$permission_repo = new \Domain\Users\PermissionRepository( $mdb );
|
|
$permissions_map = [];
|
|
foreach ( $all_users as $u )
|
|
{
|
|
if ( (int)$u['id'] !== self::ADMIN_USER_ID )
|
|
$permissions_map[ (int)$u['id'] ] = $permission_repo -> byUserId( (int)$u['id'] );
|
|
}
|
|
|
|
return \Tpl::view( 'users/main-view', self::buildMainViewModel(
|
|
$user,
|
|
$impersonator_user,
|
|
$all_users,
|
|
$permissions_map
|
|
) );
|
|
}
|
|
|
|
public static function loginAs()
|
|
{
|
|
global $user;
|
|
|
|
if ( !$user )
|
|
return \controls\Users::login_form();
|
|
|
|
$impersonator_user = self::getImpersonatorUser();
|
|
if ( !self::canManageUsers( $user, $impersonator_user ) )
|
|
self::forbiddenRedirect();
|
|
|
|
$target_user_id = (int)\S::get( 'user_id' );
|
|
$users_repository = new \Domain\Users\UserRepository();
|
|
$target_user = $users_repository -> byId( $target_user_id );
|
|
|
|
if ( !$target_user )
|
|
{
|
|
\S::alert( 'Nie znaleziono wskazanego uzytkownika.' );
|
|
header( 'Location: /users/main_view/' );
|
|
exit;
|
|
}
|
|
|
|
$new_session_state = self::impersonationStateAfterLoginAs( $user, $target_user, $impersonator_user );
|
|
|
|
\S::set_session( 'user', $new_session_state['user'] );
|
|
\S::set_session( self::IMPERSONATOR_SESSION_KEY, $new_session_state['impersonator_user'] );
|
|
|
|
\S::alert( 'Zalogowano jako: ' . $target_user['name'] . ' ' . $target_user['surname'] . '.' );
|
|
header( 'Location: /' );
|
|
exit;
|
|
}
|
|
|
|
public static function switchBackToAdmin()
|
|
{
|
|
$impersonator_user = self::getImpersonatorUser();
|
|
|
|
if ( !$impersonator_user or !isset( $impersonator_user['id'] ) or (int)$impersonator_user['id'] !== self::ADMIN_USER_ID )
|
|
{
|
|
\S::alert( 'Brak aktywnej sesji podszywania.' );
|
|
header( 'Location: /' );
|
|
exit;
|
|
}
|
|
|
|
\S::set_session( 'user', $impersonator_user );
|
|
\S::del_session( self::IMPERSONATOR_SESSION_KEY );
|
|
|
|
\S::alert( 'Powrot do konta administratora.' );
|
|
header( 'Location: /users/main_view/' );
|
|
exit;
|
|
}
|
|
|
|
public static function canManageUsers( $current_user, $impersonator_user = null )
|
|
{
|
|
if ( !is_array( $current_user ) )
|
|
return false;
|
|
|
|
if ( isset( $current_user['id'] ) and (int)$current_user['id'] === self::ADMIN_USER_ID )
|
|
return true;
|
|
|
|
if ( is_array( $impersonator_user ) and isset( $impersonator_user['id'] ) and (int)$impersonator_user['id'] === self::ADMIN_USER_ID )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
public static function vacations()
|
|
{
|
|
global $user, $mdb;
|
|
|
|
if ( !$user )
|
|
return \controls\Users::login_form();
|
|
|
|
$impersonator_user = self::getImpersonatorUser();
|
|
if ( !self::canManageUsers( $user, $impersonator_user ) )
|
|
self::forbiddenRedirect();
|
|
|
|
$users_repository = new \Domain\Users\UserRepository();
|
|
$vacation_repository = new \Domain\Users\VacationRepository( $mdb );
|
|
$all_users = $users_repository -> all();
|
|
|
|
$year = (int) \S::get( 'year' ) ?: (int) date( 'Y' );
|
|
$filter_user_id = (int) \S::get( 'user_id' ) ?: 0;
|
|
|
|
$vacations = $vacation_repository -> allByYear( $year, $filter_user_id ?: null );
|
|
$summary = $vacation_repository -> summaryByYear( $year, $all_users );
|
|
$carryover = $vacation_repository -> carryoverByYear( (int) date( 'Y' ), $all_users );
|
|
|
|
return \Tpl::view( 'users/vacations', [
|
|
'active_tab' => 'vacations',
|
|
'can_switch_back' => is_array( $impersonator_user ) and isset( $impersonator_user['id'] ) and (int)$impersonator_user['id'] === self::ADMIN_USER_ID,
|
|
'users' => $all_users,
|
|
'vacations' => $vacations,
|
|
'summary' => $summary,
|
|
'carryover' => $carryover,
|
|
'year' => $year,
|
|
'filter_user_id' => $filter_user_id,
|
|
'vacation_types' => \Domain\Users\VacationRepository::TYPES
|
|
] );
|
|
}
|
|
|
|
public static function vacationAdd()
|
|
{
|
|
global $user, $mdb;
|
|
header( 'Content-Type: application/json; charset=utf-8' );
|
|
|
|
$response = [ 'status' => 'error', 'msg' => 'Wystąpił błąd podczas dodawania urlopu.' ];
|
|
|
|
if ( !$user || !self::canManageUsers( $user, self::getImpersonatorUser() ) )
|
|
{
|
|
$response['msg'] = 'Brak uprawnień.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( !\S::csrf_verify() )
|
|
{
|
|
$response['msg'] = 'Nieprawidłowy token bezpieczeństwa. Odśwież stronę.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$user_id = (int) \S::get( 'user_id' );
|
|
$date_from = \S::get( 'date_from' );
|
|
$date_to = \S::get( 'date_to' );
|
|
$type = \S::get( 'type' );
|
|
$comment = \S::get( 'comment' );
|
|
|
|
if ( !$user_id || !$date_from || !$date_to || !$type )
|
|
{
|
|
$response['msg'] = 'Wypełnij wszystkie wymagane pola.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( !preg_match( '/^\d{4}-\d{2}-\d{2}$/', $date_from ) || !preg_match( '/^\d{4}-\d{2}-\d{2}$/', $date_to ) )
|
|
{
|
|
$response['msg'] = 'Nieprawidłowy format daty.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$vacation_repository = new \Domain\Users\VacationRepository( $mdb );
|
|
$id = $vacation_repository -> add( $user_id, $date_from, $date_to, $type, $comment );
|
|
|
|
if ( $id )
|
|
$response = [ 'status' => 'success', 'msg' => 'Urlop został dodany.' ];
|
|
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
public static function vacationEdit()
|
|
{
|
|
global $user, $mdb;
|
|
header( 'Content-Type: application/json; charset=utf-8' );
|
|
|
|
$response = [ 'status' => 'error', 'msg' => 'Wystąpił błąd podczas edycji urlopu.' ];
|
|
|
|
if ( !$user || !self::canManageUsers( $user, self::getImpersonatorUser() ) )
|
|
{
|
|
$response['msg'] = 'Brak uprawnień.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( !\S::csrf_verify() )
|
|
{
|
|
$response['msg'] = 'Nieprawidłowy token bezpieczeństwa. Odśwież stronę.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$id = (int) \S::get( 'id' );
|
|
$user_id = (int) \S::get( 'user_id' );
|
|
$date_from = \S::get( 'date_from' );
|
|
$date_to = \S::get( 'date_to' );
|
|
$type = \S::get( 'type' );
|
|
$comment = \S::get( 'comment' );
|
|
|
|
if ( !$id || !$user_id || !$date_from || !$date_to || !$type )
|
|
{
|
|
$response['msg'] = 'Wypełnij wszystkie wymagane pola.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( !preg_match( '/^\d{4}-\d{2}-\d{2}$/', $date_from ) || !preg_match( '/^\d{4}-\d{2}-\d{2}$/', $date_to ) )
|
|
{
|
|
$response['msg'] = 'Nieprawidłowy format daty.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$vacation_repository = new \Domain\Users\VacationRepository( $mdb );
|
|
|
|
if ( $vacation_repository -> update( $id, $user_id, $date_from, $date_to, $type, $comment ) )
|
|
$response = [ 'status' => 'success', 'msg' => 'Urlop został zaktualizowany.' ];
|
|
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
public static function vacationDelete()
|
|
{
|
|
global $user, $mdb;
|
|
header( 'Content-Type: application/json; charset=utf-8' );
|
|
|
|
$response = [ 'status' => 'error', 'msg' => 'Wystąpił błąd podczas usuwania urlopu.' ];
|
|
|
|
if ( !$user || !self::canManageUsers( $user, self::getImpersonatorUser() ) )
|
|
{
|
|
$response['msg'] = 'Brak uprawnień.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( !\S::csrf_verify() )
|
|
{
|
|
$response['msg'] = 'Nieprawidłowy token bezpieczeństwa. Odśwież stronę.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$id = (int) \S::get( 'id' );
|
|
|
|
if ( !$id )
|
|
{
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$vacation_repository = new \Domain\Users\VacationRepository( $mdb );
|
|
|
|
if ( $vacation_repository -> delete( $id ) )
|
|
$response = [ 'status' => 'success', 'msg' => 'Urlop został usunięty.' ];
|
|
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
public static function vacationLimitSave()
|
|
{
|
|
global $user, $mdb;
|
|
header( 'Content-Type: application/json; charset=utf-8' );
|
|
|
|
$response = [ 'status' => 'error', 'msg' => 'Wystąpił błąd podczas zapisywania limitu.' ];
|
|
|
|
if ( !$user || !self::canManageUsers( $user, self::getImpersonatorUser() ) )
|
|
{
|
|
$response['msg'] = 'Brak uprawnień.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( !\S::csrf_verify() )
|
|
{
|
|
$response['msg'] = 'Nieprawidłowy token bezpieczeństwa. Odśwież stronę.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$user_id = (int) \S::get( 'user_id' );
|
|
$year = (int) \S::get( 'year' );
|
|
$days_limit = (int) \S::get( 'days_limit' );
|
|
|
|
if ( !$user_id || !$year || $days_limit < 0 )
|
|
{
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$vacation_repository = new \Domain\Users\VacationRepository( $mdb );
|
|
|
|
if ( $vacation_repository -> setLimit( $user_id, $year, $days_limit ) )
|
|
$response = [ 'status' => 'success', 'msg' => 'Limit został zapisany.' ];
|
|
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
public static function permissionSave()
|
|
{
|
|
global $user, $mdb;
|
|
header( 'Content-Type: application/json; charset=utf-8' );
|
|
|
|
$response = [ 'status' => 'error', 'msg' => 'Wystapil blad podczas zapisywania uprawnien.' ];
|
|
|
|
if ( !$user || !self::canManageUsers( $user, self::getImpersonatorUser() ) )
|
|
{
|
|
$response['msg'] = 'Brak uprawnien.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( !\S::csrf_verify() )
|
|
{
|
|
$response['msg'] = 'Nieprawidlowy token bezpieczenstwa. Odswiez strone.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$target_user_id = (int) \S::get( 'user_id' );
|
|
$module = \S::get( 'perm_module' );
|
|
$value = (int) \S::get( 'value' );
|
|
|
|
if ( !$target_user_id || !$module )
|
|
{
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
// Superadmin permissions cannot be changed
|
|
if ( $target_user_id === self::ADMIN_USER_ID )
|
|
{
|
|
$response['msg'] = 'Nie mozna zmieniac uprawnien administratora.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
// Whitelist check
|
|
if ( !in_array( $module, \Domain\Users\PermissionRepository::MODULES, true ) )
|
|
{
|
|
$response['msg'] = 'Nieznany modul.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$repo = new \Domain\Users\PermissionRepository( $mdb );
|
|
$current = $repo -> byUserId( $target_user_id );
|
|
$current[ $module ] = $value ? 1 : 0;
|
|
$repo -> save( $target_user_id, $current );
|
|
|
|
$response = [ 'status' => 'success', 'msg' => 'Uprawnienia zostaly zapisane.' ];
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
public static function permissionPopup()
|
|
{
|
|
global $user, $mdb;
|
|
header( 'Content-Type: application/json; charset=utf-8' );
|
|
|
|
$response = [ 'status' => 'error', 'msg' => 'Nie mozna otworzyc ustawien uprawnien.' ];
|
|
|
|
if ( !$user || !self::canManageUsers( $user, self::getImpersonatorUser() ) )
|
|
{
|
|
$response['msg'] = 'Brak uprawnien.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( !\S::csrf_verify() )
|
|
{
|
|
$response['msg'] = 'Nieprawidlowy token bezpieczenstwa. Odswiez strone.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$target_user_id = (int)\S::get( 'user_id' );
|
|
if ( !$target_user_id )
|
|
{
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$users_repository = new \Domain\Users\UserRepository();
|
|
$target_user = $users_repository -> byId( $target_user_id );
|
|
if ( !$target_user )
|
|
{
|
|
$response['msg'] = 'Nie znaleziono uzytkownika.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$permission_repo = new \Domain\Users\PermissionRepository( $mdb );
|
|
$permissions = (int)$target_user['id'] === self::ADMIN_USER_ID
|
|
? \Domain\Users\PermissionRepository::defaults()
|
|
: $permission_repo -> byUserId( (int)$target_user['id'] );
|
|
|
|
$defs = self::permissionDefinitions();
|
|
|
|
$response = [
|
|
'status' => 'success',
|
|
'popup_content' => \Tpl::view( 'users/permissions-popup', [
|
|
'target_user' => $target_user,
|
|
'permissions' => $permissions,
|
|
'module_labels' => $defs['module_labels'],
|
|
'permission_groups' => $defs['permission_groups']
|
|
] )
|
|
];
|
|
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
public static function permissionSaveBulk()
|
|
{
|
|
global $user, $mdb;
|
|
header( 'Content-Type: application/json; charset=utf-8' );
|
|
|
|
$response = [ 'status' => 'error', 'msg' => 'Wystapil blad podczas zapisywania uprawnien.' ];
|
|
|
|
if ( !$user || !self::canManageUsers( $user, self::getImpersonatorUser() ) )
|
|
{
|
|
$response['msg'] = 'Brak uprawnien.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( !\S::csrf_verify() )
|
|
{
|
|
$response['msg'] = 'Nieprawidlowy token bezpieczenstwa. Odswiez strone.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$target_user_id = (int)\S::get( 'user_id' );
|
|
$selected_modules_raw = (string)\S::get( 'selected_modules' );
|
|
|
|
if ( !$target_user_id )
|
|
{
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
if ( $target_user_id === self::ADMIN_USER_ID )
|
|
{
|
|
$response['msg'] = 'Nie mozna zmieniac uprawnien administratora.';
|
|
echo json_encode( $response );
|
|
exit;
|
|
}
|
|
|
|
$selected_modules = array_filter( array_map( 'trim', explode( ',', $selected_modules_raw ) ) );
|
|
$selected_modules = array_values( array_unique( $selected_modules ) );
|
|
|
|
$payload = [];
|
|
foreach ( \Domain\Users\PermissionRepository::MODULES as $module )
|
|
$payload[ $module ] = in_array( $module, $selected_modules, true ) ? 1 : 0;
|
|
|
|
$repo = new \Domain\Users\PermissionRepository( $mdb );
|
|
$repo -> save( $target_user_id, $payload );
|
|
|
|
echo json_encode( [ 'status' => 'success', 'msg' => 'Uprawnienia zostaly zapisane.' ] );
|
|
exit;
|
|
}
|
|
|
|
public static function buildMainViewModel( $current_user, $impersonator_user, array $users, array $permissions_map = [] )
|
|
{
|
|
$defs = self::permissionDefinitions();
|
|
|
|
return [
|
|
'current_user' => $current_user,
|
|
'impersonator_user' => $impersonator_user,
|
|
'users' => $users,
|
|
'active_tab' => 'users',
|
|
'can_switch_back' => is_array( $impersonator_user ) and isset( $impersonator_user['id'] ) and (int)$impersonator_user['id'] === self::ADMIN_USER_ID,
|
|
'permissions_map' => $permissions_map,
|
|
'modules' => \Domain\Users\PermissionRepository::MODULES,
|
|
'module_labels' => $defs['module_labels'],
|
|
'permission_groups' => $defs['permission_groups']
|
|
];
|
|
}
|
|
|
|
public static function impersonationStateAfterLoginAs( $current_user, $target_user, $existing_impersonator_user = null )
|
|
{
|
|
$impersonator_user = $existing_impersonator_user;
|
|
|
|
if ( !is_array( $impersonator_user ) )
|
|
$impersonator_user = ( is_array( $current_user ) and isset( $current_user['id'] ) and (int)$current_user['id'] === self::ADMIN_USER_ID ) ? $current_user : null;
|
|
|
|
return [
|
|
'user' => $target_user,
|
|
'impersonator_user' => $impersonator_user
|
|
];
|
|
}
|
|
|
|
private static function getImpersonatorUser()
|
|
{
|
|
$session_value = \S::get_session( self::IMPERSONATOR_SESSION_KEY );
|
|
|
|
if ( is_array( $session_value ) )
|
|
return $session_value;
|
|
|
|
return null;
|
|
}
|
|
|
|
private static function forbiddenRedirect()
|
|
{
|
|
\S::alert( 'Brak uprawnien do zarzadzania uzytkownikami.' );
|
|
header( 'Location: /' );
|
|
exit;
|
|
}
|
|
|
|
private static function permissionDefinitions()
|
|
{
|
|
return [
|
|
'module_labels' => [
|
|
'tasks' => 'Zadania',
|
|
'projects_view' => 'Projekty: przegladanie',
|
|
'projects_add' => 'Projekty: dodawanie',
|
|
'projects_edit' => 'Projekty: edycja',
|
|
'projects_delete' => 'Projekty: usuwanie',
|
|
'work_time' => 'Czas pracy',
|
|
'finances' => 'Finanse',
|
|
'crm' => 'CRM',
|
|
'wiki' => 'Wiki'
|
|
],
|
|
'permission_groups' => [
|
|
'Podstawowe' => [ 'tasks', 'work_time', 'wiki' ],
|
|
'Projekty' => [ 'projects_view', 'projects_add', 'projects_edit', 'projects_delete' ],
|
|
'Pozostale' => [ 'finances', 'crm' ]
|
|
]
|
|
];
|
|
}
|
|
}
|