Correzione log di accesso e informazioni utente

This commit is contained in:
Dasc3er 2021-02-22 14:36:36 +01:00
parent 04ff4439ed
commit 1610f17255
13 changed files with 227 additions and 57 deletions

View File

@ -24,7 +24,7 @@ class InitializationController extends Controller
if (!isset(self::$init)) {
$database = database();
$has_azienda = $database->fetchNum("SELECT `an_anagrafiche`.`idanagrafica`
$has_azienda = $database->fetchNum("SELECT `an_anagrafiche`.`idanagrafica`
FROM `an_anagrafiche`
LEFT JOIN `an_tipianagrafiche_anagrafiche` ON `an_anagrafiche`.`idanagrafica`=`an_tipianagrafiche_anagrafiche`.`idanagrafica`
LEFT JOIN `an_tipianagrafiche` ON `an_tipianagrafiche`.`idtipoanagrafica`=`an_tipianagrafiche_anagrafiche`.`idtipoanagrafica`

View File

@ -4,8 +4,8 @@ namespace App\Http\Controllers;
use App\Exceptions\LegacyExitException;
use App\Exceptions\LegacyRedirectException;
use Illuminate\Http\Response;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Redirect;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

View File

@ -10,6 +10,9 @@ class UserController extends Controller
/** @var int Lunghezza minima della password */
public static $min_length_password = 8;
/**
* Gestisce la pagina di informazioni dell'utente.
*/
public function index()
{
$user = auth()->user();
@ -29,6 +32,9 @@ class UserController extends Controller
return view('user.info', $args);
}
/**
* Gestisce la visualizzazione del modal per la modifica della password.
*/
public function password()
{
$args['min_length_password'] = self::$min_length_password;
@ -36,7 +42,10 @@ class UserController extends Controller
return view('user.password', $args);
}
public function save(Request $request)
/**
* Gestisce il salvataggio della nuova password per l'utente.
*/
public function savePassword(Request $request)
{
$user = auth()->user();
$password = $request->input('password');
@ -49,6 +58,9 @@ class UserController extends Controller
return redirect(route('user-info'));
}
/***
* Gestisce la visualizzazione dei log di accesso dell'utente corrente al gestionale.
*/
public function logs()
{
$user = auth()->user();
@ -64,4 +76,28 @@ class UserController extends Controller
'logs' => $logs,
]);
}
/**
* Gestisce la visualizzazione del modal per la modifica della foto utente.
*/
public function photo()
{
return view('user.photo');
}
/**
* Gestisce il salvataggio della nuova foto utente.
*/
public function savePhoto(Request $request)
{
$user = auth()->user();
$file = $request->file('photo');
$user->photo = $file;
$user->save();
flash()->info(tr('Foto utente aggiornata!'));
return redirect(route('user-info'));
}
}

View File

@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Models\Log;
class LoginRequest extends FormRequest
{
@ -48,9 +49,23 @@ class LoginRequest extends FormRequest
if (!Auth::attempt($this->only('username', 'password'), $this->filled('remember'))) {
RateLimiter::hit($this->throttleKey());
// Log di accesso
$this->registerLog('failed');
throw ValidationException::withMessages(['username' => tr('auth.failed')]);
}
// Informazioni sull'utente
$user = auth()->user();
if (empty($user->enabled)) {
$status = 'disabled';
} elseif ($user->getFirstAvailableModule() === null) {
$status = 'unauthorized';
} else {
$status = 'success';
}
$this->registerLog($status);
RateLimiter::clear($this->throttleKey());
}
@ -83,4 +98,22 @@ class LoginRequest extends FormRequest
{
return Str::lower($this->input('username')).'|'.$this->ip();
}
/**
* Registra i log di accesso per il tentativo corrente.
*
* @param string $status
*/
protected function registerLog($status)
{
// Log di accesso
$log = new Log();
$log->username = $this->input('username');
$log->ip = $this->ip();
$log->id_utente = auth()->user()->id;
$log->setStatus($status);
$log->save();
}
}

View File

@ -5,6 +5,7 @@ namespace App\Models;
use Common\SimpleModelTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Http\UploadedFile;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
use Intervention\Image\ImageManagerStatic;
@ -153,9 +154,9 @@ class User extends Authenticatable
return base_url().'/'.$image->filepath;
}
public function setPhotoAttribute($value)
public function setPhotoAttribute(UploadedFile $file)
{
$module = \module('Utenti e permessi');
$module = module('Utenti e permessi');
$data = [
'id_module' => $module->id,
@ -165,22 +166,19 @@ class User extends Authenticatable
// Foto precedenti
$old_photo = Upload::where($data)->get();
// Informazioni sull'immagine
$filepath = is_array($value) ? $value['tmp_name'] : $value;
$info = Upload::getInfo(is_array($value) ? $value['name'] : $value);
$file = base_dir().'/files/temp_photo.'.$info['extension'];
// Ridimensionamento
$driver = extension_loaded('gd') ? 'gd' : 'imagick';
ImageManagerStatic::configure(['driver' => $driver]);
$img = ImageManagerStatic::make($filepath)->resize(100, 100, function ($constraint) {
$constraint->aspectRatio();
});
$img->save(slashes($file));
$temp_file = temp_file(secure_random_string().'.'.$file->getClientOriginalExtension(), $file->getContent());
$img = ImageManagerStatic::make($temp_file)
->resize(100, 100, function ($constraint) {
$constraint->aspectRatio();
});
$img->save($temp_file);
// Aggiunta nuova foto
$upload = Upload::build($file, $data);
$upload = Upload::build($temp_file, $data);
// Rimozione foto precedenti
delete($file);

View File

@ -152,5 +152,5 @@ return [
*
* "__" and "_n" and "_i" and "_s" are helpers functions @see \Xinax\LaravelGettext\Support\helpers.php
*/
'keywords-list' => ['_', '__', '_i', '_s', 'gettext', '_n:1,2', 'ngettext:1,2', 'dgettext:2'],
'keywords-list' => ['_', '__', '_i', '_s', 'gettext', '_n:1,2', 'ngettext:1,2', 'dgettext:2', 'tr'],
];

2
legacy

@ -1 +1 @@
Subproject commit a4c7c2c560cc34d7d48b81158db3795650968c8b
Subproject commit 9310e63a3b0ec69cf43481bedcf0f1099e876bd1

View File

@ -37,7 +37,7 @@
<div class="box-body">
<p>{{ tr("Il progetto è software libero perchè permette a tutti di conoscere come funziona avendo il codice sorgente del programma e fornisce così la possibilità di studiare come funziona, modificarlo, adattarlo alle proprie esigenze e, in ambito commerciale, non obbliga l'utilizzatore ad essere legato allo stesso fornitore di assistenza") }}.</p>
<p>{{ tr("E' altrettanto importante sapere come funziona per conoscere come vengono trattati i VOSTRI dati, proteggendo così la vostra <b>privacy</b>") }}.</p>
<p>{!! tr("E' altrettanto importante sapere come funziona per conoscere come vengono trattati i VOSTRI dati, proteggendo così la vostra <b>privacy</b>") !!}.</p>
<p>{{ tr('OpenSTAManager è inoltre stato progettato utilizzando altro software libero, tra cui principalmente') }}:</p>
<ul>
@ -70,7 +70,7 @@
</a>
</div>
<div class="col-xs-3 text-center">
<a href="http://www.openstamanager.com/forum/" target="_blank">
<a href="http://forum.openstamanager.com/" target="_blank">
<i class="fa fa-2x fa-edit"></i><br>
{{ tr('Forum') }}
</a>
@ -116,7 +116,7 @@
<div class="box-body">
<p>{{ tr('OpenSTAManager è software libero ed è nato e cresciuto con il lavoro volontario di alcuni programmatori') }}.</p>
<p>{{ tr('La filosofia del software libero fa sì che il progetto sia <b>accessibile a tutti</b> e nel nostro caso specifico lo è, anche dal punto di vista della gratuità') }}.</p>
<p>{!! tr('La filosofia del software libero fa sì che il progetto sia <b>accessibile a tutti</b> e nel nostro caso specifico lo è, anche dal punto di vista della gratuità') !!}.</p>
<p>{{ tr('Offriamo supporto a pagamento professionale a chi fosse interessato, ma a chi non interessa il supporto a pagamento e sta comunque utilizzando il software chiediamo una donazione per il lavoro svolto finora e per la possibilità di continuare questo progetto con lo stesso spirito con cui è nato') }}. {!! tr('Le donazioni non ci rendono ricchi, ma sono un <b>grande simbolo di apprezzamento</b>') !!}.</p>
@ -132,7 +132,7 @@
</div>
<div class="box-body">
<p>{{ tr('Per le aziende che hanno necessità di essere seguite da <b>supporto professionale</b> è disponibile un servizio di assistenza e supporto a pagamento') }}.</p>
<p>{!! tr('Per le aziende che hanno necessità di essere seguite da <b>supporto professionale</b> è disponibile un servizio di assistenza e supporto a pagamento') !!}.</p>
<p>{!! tr("E' disponibile anche un <b>servizio cloud</b> su cui poter installare OpenSTAManager, in modo da non doverti più preoccupare di backup e gestione dei dati") !!}.</p>

View File

@ -244,7 +244,7 @@
<a href="{{ route('user-info') }}" class="user-panel text-center info" style="height: 60px">
<div class="text-center mt-2">
@if ($user->photo)
<img src="{{ base_url() }}{{ $user->photo }}" class="profile-user-img img-fluid img-circle" alt="{{ $user->username }}" />
<img src="{{ $user->photo }}" class="profile-user-img img-fluid img-circle" alt="{{ $user->username }}" />
@else
<i class="fa fa-user-circle-o fa-5x"></i>
@endif

View File

@ -28,7 +28,7 @@
<div class="col-sm-4 border-right">
<div class="description-block">
<a class="btn btn-info btn-block tip" data-href="" data-toggle="modal" data-title="{{ tr('Cambia foto utente') }}">
<a class="btn btn-info btn-block tip" data-href="{{ route('user-photo') }}" data-toggle="modal" data-title="{{ tr('Cambia foto utente') }}">
<i class="fa fa-picture-o"></i> {{ tr('Cambia foto utente') }}
</a>
</div>

View File

@ -0,0 +1,58 @@
<form action="{{ route('user-password-save') }}" method="post" id="password-form">
@csrf
<div class="row">
<div class="col-md-12">
{[ "type": "password", "label": "{{ tr('Password') }}", "name": "password", "required": 1 ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
{[ "type": "password", "label": "{{ tr('Ripeti la password') }}", "name": "password_rep", "required": 1 ]}
</div>
</div>
<button type="button" onclick="updatePassword()" class="btn btn-primary pull-right">
<i class="fa fa-plus"></i> {{ tr('Aggiorna password') }}
</button>
<div class="clearfix">&nbsp;</div>
</form>
<script type="text/javascript">
var min_length = {{ $min_length_password }};
function updatePassword() {
let password = $("#password").val();
let password_rep = $("#password_rep").val();
if(password === "" || password_rep === ""){
swal({
title: "{{ tr('Inserire una password valida') }}",
type: "error",
});
}
else if(password !== password_rep){
swal({
title: "{{ tr('Le password non coincidono') }}",
type: "error",
});
}
else if(password.length < min_length ){
swal({
title: "{{ tr('La password deve essere lunga minimo _MIN_ caratteri!', [
'_MIN_' => $min_length_password,
]) }}",
type: "error",
});
}
else {
$("#password-form").submit();
}
}
</script>
<script>$(document).ready(init);</script>

View File

@ -0,0 +1,24 @@
<form action="{{ route('user-photo-save') }}" method="post" enctype="multipart/form-data" id="photo-form">
@csrf
@php
$user = auth()->user();
$user_photo = $user->photo;
@endphp
@if($user_photo) {
<center><img src="{{ $user_photo }}" class="img-responsive" alt="{{ $user->username }}" /></center>
@endif
<div class="row">
<div class="col-md-12">
{[ "type": "file", "label": "{{ tr('Foto utente') }}", "name": "photo", "help": "{{ tr('Dimensione consigliata 100x100 pixel') }}", "required": 1 ]}
</div>
</div>
<button type="submit" class="btn btn-primary pull-right">
<i class="fa fa-plus"></i> {{ tr('Aggiorna foto') }}
</button>
<div class="clearfix">&nbsp;</div>
</form>
<script>$(document).ready(init);</script>

View File

@ -27,7 +27,7 @@ Route::get('/', function () {
return redirect('controller.php?id_module='.$module->id);
})
->middleware('auth');
->middleware(['auth']);
// Sezione di configurazione
Route::get('/config', [ConfigurationController::class, 'index'])
@ -48,64 +48,85 @@ Route::get('/messages', [Test::class, 'index'])
->name('messages');
// Operazioni Ajax
Route::prefix('ajax')->group(function () {
Route::get('/select', [Test::class, 'index'])
Route::prefix('ajax')
->group(function () {
Route::get('/select', [Test::class, 'index'])
->name('ajax-select');
Route::get('/complete', [Test::class, 'index'])
Route::get('/complete', [Test::class, 'index'])
->name('ajax-complete');
Route::get('/search', [Test::class, 'index'])
Route::get('/search', [Test::class, 'index'])
->name('ajax-search');
// Sessioni
Route::get('/session/', [Test::class, 'index'])
// Sessioni
Route::get('/session/', [Test::class, 'index'])
->name('ajax-session');
Route::get('/session-array/', [Test::class, 'index'])
Route::get('/session-array/', [Test::class, 'index'])
->name('ajax-session-array');
// Dataload
Route::get('/dataload/{module_id}/{reference_id?}', [Test::class, 'index'])
// Dataload
Route::get('/dataload/{module_id}/{reference_id?}', [Test::class, 'index'])
->where('module_id', '[0-9]+')
->where('reference_id', '[0-9]+')
->name('ajax-dataload');
});
});
// Hooks
Route::prefix('hook')->group(function () {
Route::get('/list', [Test::class, 'index'])
->name('hooks');
Route::prefix('hook')
->middleware(['auth'])
->group(function () {
Route::get('/list', [Test::class, 'index'])
->name('hooks');
Route::get('/lock/{hook_id}', [Test::class, 'index'])
->where('hook_id', '[0-9]+')
->name('hook-lock');
Route::get('/lock/{hook_id}', [Test::class, 'index'])
->where('hook_id', '[0-9]+')
->name('hook-lock');
Route::get('/execute/{hook_id}/{token}', [Test::class, 'index'])
->where('hook_id', '[0-9]+')
->name('hook-execute');
Route::get('/execute/{hook_id}/{token}', [Test::class, 'index'])
->where('hook_id', '[0-9]+')
->name('hook-execute');
Route::get('/response/{hook_id}', [Test::class, 'index'])
->where('hook_id', '[0-9]+')
->name('hook-response');
});
Route::get('/response/{hook_id}', [Test::class, 'index'])
->where('hook_id', '[0-9]+')
->name('hook-response');
});
// Informazioni su OpenSTAManager
Route::get('/info', [InfoController::class, 'info'])
->middleware(['auth'])
->name('info');
// Segnalazione bug
Route::get('/bug', [InfoController::class, 'bug'])
->name('bug');
Route::post('/bug', [InfoController::class, 'send'])
->name('bug-send');
Route::prefix('bug')
->middleware(['auth'])
->group(function () {
Route::get('', [InfoController::class, 'bug'])
->name('bug');
Route::post('', [InfoController::class, 'send'])
->name('bug-send');
});
// Log di accesso
Route::get('/logs', [UserController::class, 'logs'])
->middleware(['auth'])
->name('logs');
// Informazioni sull'utente
Route::get('/user', [UserController::class, 'index'])
->name('user-info');
Route::prefix('user')
->middleware(['auth'])
->group(function () {
Route::get('/info', [UserController::class, 'index'])
->name('user-info');
Route::get('/password', [UserController::class, 'password'])
->name('user-password');
Route::post('/password', [UserController::class, 'save'])
->name('user-password-save');;
Route::get('/password', [UserController::class, 'password'])
->name('user-password');
Route::post('/password', [UserController::class, 'savePassword'])
->name('user-password-save');
Route::get('/photo', [UserController::class, 'photo'])
->name('user-photo');
Route::post('/photo', [UserController::class, 'savePhoto'])
->name('user-photo-save');
});