Add user action logs
This commit is contained in:
parent
fc9c8635a6
commit
045a311742
|
@ -6,6 +6,7 @@ use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Utils\Logger;
|
||||||
|
|
||||||
class AuthController extends Controller
|
class AuthController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -27,6 +28,8 @@ class AuthController extends Controller
|
||||||
|
|
||||||
$token = $user->createToken('auth_token')->plainTextToken;
|
$token = $user->createToken('auth_token')->plainTextToken;
|
||||||
|
|
||||||
|
Logger::log("Creato utente $user->name ($user->username)", $user);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'access_token' => $token,
|
'access_token' => $token,
|
||||||
'token_type' => 'Bearer',
|
'token_type' => 'Bearer',
|
||||||
|
@ -47,6 +50,8 @@ class AuthController extends Controller
|
||||||
|
|
||||||
$token = $user->createToken('auth_token')->plainTextToken;
|
$token = $user->createToken('auth_token')->plainTextToken;
|
||||||
|
|
||||||
|
Logger::log("Login", $user, $user);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'access_token' => $token,
|
'access_token' => $token,
|
||||||
'token_type' => 'Bearer',
|
'token_type' => 'Bearer',
|
||||||
|
@ -56,6 +61,7 @@ class AuthController extends Controller
|
||||||
public function logout(Request $request)
|
public function logout(Request $request)
|
||||||
{
|
{
|
||||||
//TODO: https://stackoverflow.com/a/73980629
|
//TODO: https://stackoverflow.com/a/73980629
|
||||||
|
Logger::log("Logout");
|
||||||
auth('web')->logout();
|
auth('web')->logout();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Log;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class LogsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
return response()->json(
|
||||||
|
Log::join('users as changed_user', 'changed_user.id', '=', 'logs.changed_id')
|
||||||
|
->join('users as editor_user', 'editor_user.id', '=', 'logs.editor_id')
|
||||||
|
->select("logs.id", "logs.action", "logs.editor_id", "logs.changed_id", "logs.created_at", "changed_user.name as changed", "editor_user.name as editor")
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->get()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\ScheduleSlots;
|
use App\Models\ScheduleSlots;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Utils\Logger;
|
||||||
|
|
||||||
class ScheduleSlotsController extends Controller
|
class ScheduleSlotsController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -29,6 +30,8 @@ class ScheduleSlotsController extends Controller
|
||||||
return $schedule;
|
return $schedule;
|
||||||
}, $request->input('schedules'));
|
}, $request->input('schedules'));
|
||||||
|
|
||||||
|
Logger::log("Aggiornata disponibilità oraria");
|
||||||
|
|
||||||
return ScheduleSlots::insert($schedules);
|
return ScheduleSlots::insert($schedules);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use App\Models\Service;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\DB;
|
use App\Utils\Logger;
|
||||||
|
|
||||||
class ServiceController extends Controller
|
class ServiceController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -61,8 +61,6 @@ class ServiceController extends Controller
|
||||||
*/
|
*/
|
||||||
public function createOrUpdate(Request $request)
|
public function createOrUpdate(Request $request)
|
||||||
{
|
{
|
||||||
DB::connection()->enableQueryLog();
|
|
||||||
|
|
||||||
$adding = !isset($request->id) || is_null($request->id);
|
$adding = !isset($request->id) || is_null($request->id);
|
||||||
|
|
||||||
$service = $adding ? new Service() : Service::find($request->id)->with('drivers')->with('crew')->first();
|
$service = $adding ? new Service() : Service::find($request->id)->with('drivers')->with('crew')->first();
|
||||||
|
@ -134,7 +132,7 @@ class ServiceController extends Controller
|
||||||
));
|
));
|
||||||
User::whereIn('id', $usersToIncrement)->increment('services');
|
User::whereIn('id', $usersToIncrement)->increment('services');
|
||||||
|
|
||||||
return response()->json(DB::getQueryLog());
|
Logger::log($adding ? "Intervento aggiunto" : "Intervento modificato");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,5 +144,6 @@ class ServiceController extends Controller
|
||||||
$usersToDecrement = $this->extractServiceUsers($service);
|
$usersToDecrement = $this->extractServiceUsers($service);
|
||||||
User::whereIn('id', $usersToDecrement)->decrement('services');
|
User::whereIn('id', $usersToDecrement)->decrement('services');
|
||||||
$service->delete();
|
$service->delete();
|
||||||
|
Logger::log("Intervento eliminato");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\ServiceType;
|
use App\Models\ServiceType;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Utils\Logger;
|
||||||
|
|
||||||
class ServiceTypeController extends Controller
|
class ServiceTypeController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -26,6 +27,8 @@ class ServiceTypeController extends Controller
|
||||||
$serviceType->name = $request->name;
|
$serviceType->name = $request->name;
|
||||||
$serviceType->save();
|
$serviceType->save();
|
||||||
|
|
||||||
|
Logger::log("Aggiunto tipo di intervento ($serviceType->name)");
|
||||||
|
|
||||||
return response()->json(
|
return response()->json(
|
||||||
$serviceType
|
$serviceType
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,6 +6,7 @@ use Illuminate\Http\Request;
|
||||||
use App\Models\TelegramBotLogins;
|
use App\Models\TelegramBotLogins;
|
||||||
use DefStudio\Telegraph\Models\TelegraphBot;
|
use DefStudio\Telegraph\Models\TelegraphBot;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use App\Utils\Logger;
|
||||||
|
|
||||||
class TelegramController extends Controller
|
class TelegramController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -21,6 +22,8 @@ class TelegramController extends Controller
|
||||||
$row->user = $request->user()->id;
|
$row->user = $request->user()->id;
|
||||||
$row->save();
|
$row->save();
|
||||||
|
|
||||||
|
Logger::log("Inizio procedura collegamento bot Telegram");
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"start_link" => "https://t.me/$telegramBotUsername?start=$telegramBotStartParameter"
|
"start_link" => "https://t.me/$telegramBotUsername?start=$telegramBotStartParameter"
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class Log extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
public $timestamps = ["created_at"];
|
||||||
|
const UPDATED_AT = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'action',
|
||||||
|
'ip',
|
||||||
|
'source_type',
|
||||||
|
'user_agent'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function changed(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editor(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -133,7 +133,7 @@ class WebhookController extends
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Availability::updateAvailability($user, true);
|
Availability::updateAvailability($user, true, true);
|
||||||
$this->reply("Disponibilità aggiornata con successo.\nOra sei <b>operativo</b>.");
|
$this->reply("Disponibilità aggiornata con successo.\nOra sei <b>operativo</b>.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ class WebhookController extends
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Availability::updateAvailability($user, false);
|
Availability::updateAvailability($user, false, true);
|
||||||
$this->reply("Disponibilità aggiornata con successo.\nOra sei <b>non operativo</b>.");
|
$this->reply("Disponibilità aggiornata con successo.\nOra sei <b>non operativo</b>.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ class WebhookController extends
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Availability::updateAvailabilityManualMode($user, false);
|
Availability::updateAvailabilityManualMode($user, false, true);
|
||||||
$this->reply("Programmazione oraria <b>abilitata</b>.\nPer disabilitarla (e tornare in modalità manuale), cambiare la disponbilità usando i comandi \"/attiva\" e \"/disattiva\"");
|
$this->reply("Programmazione oraria <b>abilitata</b>.\nPer disabilitarla (e tornare in modalità manuale), cambiare la disponbilità usando i comandi \"/attiva\" e \"/disattiva\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ class WebhookController extends
|
||||||
$this->reply("⚠️ Il tuo account Allerta non è collegato con Telegram.", true);
|
$this->reply("⚠️ Il tuo account Allerta non è collegato con Telegram.", true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Availability::updateAvailabilityManualMode($user, false);
|
Availability::updateAvailabilityManualMode($user, false, true);
|
||||||
$this->reply("✅ Programmazione oraria abilitata", true);
|
$this->reply("✅ Programmazione oraria abilitata", true);
|
||||||
|
|
||||||
//Delete the message that triggered the callback
|
//Delete the message that triggered the callback
|
||||||
|
|
|
@ -5,9 +5,10 @@ namespace App\Utils;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\TelegramBotNotifications;
|
use App\Models\TelegramBotNotifications;
|
||||||
use DefStudio\Telegraph\Facades\Telegraph;
|
use DefStudio\Telegraph\Facades\Telegraph;
|
||||||
|
use App\Utils\Logger;
|
||||||
|
|
||||||
class Availability {
|
class Availability {
|
||||||
public static function updateAvailability(User|int $id, bool $available)
|
public static function updateAvailability(User|int $id, bool $available, bool $fromTelegram = false)
|
||||||
{
|
{
|
||||||
if(is_int($id)) {
|
if(is_int($id)) {
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
|
@ -52,13 +53,20 @@ class Availability {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger::log(
|
||||||
|
"Disponibilità cambiata in ".($available ? "disponibile" : "non disponibile"),
|
||||||
|
$user,
|
||||||
|
$fromTelegram ? $user : null,
|
||||||
|
$fromTelegram ? "telegram" : "web"
|
||||||
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"updated_user_id" => $user->id,
|
"updated_user_id" => $user->id,
|
||||||
"updated_user_name" => $user->name
|
"updated_user_name" => $user->name
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function updateAvailabilityManualMode(User|int $id, bool $manual_mode)
|
public static function updateAvailabilityManualMode(User|int $id, bool $manual_mode, bool $fromTelegram = false)
|
||||||
{
|
{
|
||||||
if(is_int($id)) {
|
if(is_int($id)) {
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
|
@ -68,6 +76,13 @@ class Availability {
|
||||||
$user->availability_manual_mode = $manual_mode;
|
$user->availability_manual_mode = $manual_mode;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
|
Logger::log(
|
||||||
|
($manual_mode ? "Disattivazione" : "Attivazione")." programmazione oraria",
|
||||||
|
$user,
|
||||||
|
$fromTelegram ? $user : null,
|
||||||
|
$fromTelegram ? "telegram" : "web"
|
||||||
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Utils;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Log;
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
public static function log(string $action, User $changed = null, User $editor = null, $source_type = "web")
|
||||||
|
{
|
||||||
|
$log = new Log();
|
||||||
|
$log->action = $action;
|
||||||
|
|
||||||
|
$request = request();
|
||||||
|
if($source_type !== "web") {
|
||||||
|
$log->ip = null;
|
||||||
|
$log->source_type = $source_type;
|
||||||
|
$log->user_agent = null;
|
||||||
|
} else {
|
||||||
|
$log->source_type = "web";
|
||||||
|
$request = request();
|
||||||
|
if(!is_null($request)) {
|
||||||
|
$log->ip = $request->ip();
|
||||||
|
$log->user_agent = $request->userAgent();
|
||||||
|
} else {
|
||||||
|
$log->ip = null;
|
||||||
|
$log->user_agent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_null($changed)) $changed = auth()->user();
|
||||||
|
$log->changed()->associate($changed);
|
||||||
|
if(is_null($editor)) $editor = auth()->user();
|
||||||
|
$log->editor()->associate($editor);
|
||||||
|
|
||||||
|
$log->save();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('logs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('action');
|
||||||
|
$table->string('ip')->nullable();
|
||||||
|
$table->string('source_type');
|
||||||
|
$table->string('user_agent')->nullable();
|
||||||
|
$table->foreignId('changed_id')->nullable()->constrained('users');
|
||||||
|
$table->foreignId('editor_id')->nullable()->constrained('users');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->dropColumn('updated_at');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('logs');
|
||||||
|
}
|
||||||
|
};
|
|
@ -5,6 +5,7 @@ use App\Http\Controllers\AuthController;
|
||||||
use App\Http\Controllers\UserController;
|
use App\Http\Controllers\UserController;
|
||||||
use App\Http\Controllers\ScheduleSlotsController;
|
use App\Http\Controllers\ScheduleSlotsController;
|
||||||
use App\Http\Controllers\AvailabilityController;
|
use App\Http\Controllers\AvailabilityController;
|
||||||
|
use App\Http\Controllers\LogsController;
|
||||||
use App\Http\Controllers\TelegramController;
|
use App\Http\Controllers\TelegramController;
|
||||||
use App\Http\Controllers\ServiceController;
|
use App\Http\Controllers\ServiceController;
|
||||||
use App\Http\Controllers\PlacesController;
|
use App\Http\Controllers\PlacesController;
|
||||||
|
@ -23,10 +24,11 @@ use Illuminate\Support\Facades\Artisan;
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::post('/register', [AuthController::class, 'register']);
|
|
||||||
Route::post('/login', [AuthController::class, 'login']);
|
Route::post('/login', [AuthController::class, 'login']);
|
||||||
|
|
||||||
Route::middleware('auth:web')->group( function () {
|
Route::middleware('auth:web')->group( function () {
|
||||||
|
//Route::post('/register', [AuthController::class, 'register']); //TODO: replace with admin only route
|
||||||
|
|
||||||
Route::get('/me', [AuthController::class, 'me']);
|
Route::get('/me', [AuthController::class, 'me']);
|
||||||
Route::post('/me', [AuthController::class, 'me']);
|
Route::post('/me', [AuthController::class, 'me']);
|
||||||
|
|
||||||
|
@ -52,6 +54,8 @@ Route::middleware('auth:web')->group( function () {
|
||||||
Route::get('/places/search', [PlacesController::class, 'search']);
|
Route::get('/places/search', [PlacesController::class, 'search']);
|
||||||
Route::get('/places/{id}', [PlacesController::class, 'show']);
|
Route::get('/places/{id}', [PlacesController::class, 'show']);
|
||||||
|
|
||||||
|
Route::get('/logs', [LogsController::class, 'index']);
|
||||||
|
|
||||||
Route::post('/telegram_login_token', [TelegramController::class, 'loginToken']);
|
Route::post('/telegram_login_token', [TelegramController::class, 'loginToken']);
|
||||||
|
|
||||||
Route::post('/logout', [AuthController::class, 'logout']);
|
Route::post('/logout', [AuthController::class, 'logout']);
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
<td>{{ row.action }}</td>
|
<td>{{ row.action }}</td>
|
||||||
<td>{{ row.changed }}</td>
|
<td>{{ row.changed }}</td>
|
||||||
<td>{{ row.editor }}</td>
|
<td>{{ row.editor }}</td>
|
||||||
<td>{{ row.timestamp }}</td>
|
<td>{{ row.created_at | date: 'dd/MM/YYYY HH:mm:ss' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
<owner-image></owner-image>
|
<owner-image></owner-image>
|
||||||
<app-table *ngIf="false" [sourceType]="'logs'" [refreshInterval]="1200000"></app-table>
|
<app-table [sourceType]="'logs'" [refreshInterval]="1200000"></app-table>
|
||||||
<div class="alert alert-warning" role="alert">
|
|
||||||
Questa sezione di AllertaVVF è stata temporaneamente disabilitata per motivi di manutenzione. Ci scusiamo per il disagio.
|
|
||||||
</div>
|
|
||||||
|
|
Loading…
Reference in New Issue