Skip to content

Commit 249a2c9

Browse files
committed
feat: add audit log for user fields changes
Change-Id: I2db7f2a919b200fee11792f05977884e059d2366
1 parent f8a102f commit 249a2c9

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed

app/Jobs/AddUserAction.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php namespace App\Jobs;
2+
/*
3+
* Copyright 2024 OpenStack Foundation
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
**/
14+
use Illuminate\Bus\Queueable;
15+
use Illuminate\Contracts\Queue\ShouldQueue;
16+
use Illuminate\Foundation\Bus\Dispatchable;
17+
use Illuminate\Queue\InteractsWithQueue;
18+
use Illuminate\Queue\SerializesModels;
19+
use Illuminate\Support\Facades\Log;
20+
use Services\IUserActionService;
21+
22+
/**
23+
* Class AddUserAction
24+
* @package App\Jobs
25+
*/
26+
final class AddUserAction implements ShouldQueue
27+
{
28+
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
29+
public $tries = 1;
30+
31+
public $timeout = 0;
32+
33+
/**
34+
* @var int
35+
*/
36+
private $user_id;
37+
38+
/**
39+
* @var string
40+
*/
41+
private $action;
42+
43+
/**
44+
* @var string
45+
*/
46+
private $ip;
47+
48+
/**
49+
* @param int $user_id
50+
* @param string $ip
51+
* @param string $action
52+
*/
53+
public function __construct(int $user_id, string $ip, string $action){
54+
Log::debug(sprintf("AddUserAction::constructor user %s action %s ip %s", $user_id, $action, $ip));
55+
$this->user_id = $user_id;
56+
$this->action = $action;
57+
$this->ip = $ip;
58+
}
59+
60+
public function handle(IUserActionService $service){
61+
Log::debug(sprintf("AddUserAction::handle"));
62+
try{
63+
$service->addUserAction($this->user_id, $this->ip, $this->action);
64+
}
65+
catch (\Exception $ex) {
66+
Log::error($ex);
67+
}
68+
}
69+
70+
public function failed(\Throwable $exception)
71+
{
72+
Log::error(sprintf( "AddUserAction::failed %s", $exception->getMessage()));
73+
}
74+
}

app/libs/Auth/Models/User.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
* See the License for the specific language governing permissions and
1212
* limitations under the License.
1313
**/
14+
1415
use App\Events\UserCreated;
1516
use App\Events\UserLocked;
1617
use App\Events\UserSpamStateUpdated;
18+
use App\Jobs\AddUserAction;
1719
use App\libs\Auth\Models\IGroupSlugs;
1820
use App\libs\Auth\Models\UserRegistrationRequest;
1921
use App\libs\Utils\PunnyCodeHelper;
@@ -44,6 +46,7 @@
4446
use Doctrine\Common\Collections\ArrayCollection;
4547
use App\Models\Utils\BaseEntity;
4648
use Doctrine\ORM\Mapping AS ORM;
49+
use Utils\IPHelper;
4750

4851
/**
4952
* @ORM\Entity(repositoryClass="App\Repositories\DoctrineUserRepository")
@@ -2003,4 +2006,76 @@ public function createdByOTP():bool{
20032006
return !is_null($this->created_by_otp);
20042007
}
20052008

2009+
/**
2010+
* @ORM\PostUpdate:
2011+
*/
2012+
public function updated($args)
2013+
{
2014+
2015+
}
2016+
2017+
private function formatFieldValue(string $field, $value):string{
2018+
if($field === 'password') $value = "********";
2019+
if($value instanceof \DateTime)
2020+
$value = $value->format('Y-m-d H:i:s');
2021+
return sprintf("%s: %s", $field, $value);
2022+
}
2023+
/**
2024+
* @ORM\PreUpdate:
2025+
*/
2026+
public function updating(PreUpdateEventArgs $args)
2027+
{
2028+
$fields_2_check = [
2029+
'identifier',
2030+
'public_profile_show_photo',
2031+
'public_profile_show_fullname',
2032+
'public_profile_show_email',
2033+
'public_profile_allow_chat_with_me',
2034+
'active',
2035+
'first_name',
2036+
'last_name',
2037+
'email',
2038+
'address1',
2039+
'address2',
2040+
'state',
2041+
'city',
2042+
'post_code',
2043+
'country_iso_code',
2044+
'second_email',
2045+
'third_email',
2046+
'gender',
2047+
'gender_specify',
2048+
'statement_of_interest',
2049+
'bio',
2050+
'irc',
2051+
'linked_in_profile',
2052+
'twitter_name',
2053+
'github_user',
2054+
'wechat_user',
2055+
'password',
2056+
'email_verified',
2057+
'language',
2058+
'birthday',
2059+
'company',
2060+
'job_title',
2061+
'phone_number',
2062+
];
2063+
$old_fields_changed = [];
2064+
$new_fields_changed = [];
2065+
2066+
foreach($fields_2_check as $field){
2067+
if($args->hasChangedField($field)){
2068+
$old_fields_changed[] = sprintf("%s: %s", $field, self::formatFieldValue($field, $args->getOldValue($field)));
2069+
$new_fields_changed[] = sprintf("%s: %s", $field, self::formatFieldValue($field, $args->getNewValue($field)));
2070+
}
2071+
}
2072+
2073+
$action = sprintf
2074+
(
2075+
"User %s updated from %s to %s", $this->email, implode(", ", $old_fields_changed), implode(", ", $new_fields_changed)
2076+
);
2077+
2078+
Event::dispatch(new AddUserAction($this->id, IPHelper::getUserIp(), $action));
2079+
}
2080+
20062081
}

0 commit comments

Comments
 (0)