Build modified streamline images

The official image from streamline does not currently work for the arm64
platform. As a temporary measure, the source code and docker build scripts
have been lifted from the official images and are used to build locally.

Some additional modifications are made to reduce overall image size, these
are documented in docker/README.md
This commit is contained in:
2024-03-10 16:17:50 -07:00
parent 2ffc3c408a
commit a424394109
13506 changed files with 1860172 additions and 6 deletions
@@ -0,0 +1,626 @@
<?php
namespace Streamline\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Models\Role;
use Streamline\Models\PasswordSecurity;
use Streamline\Models\SecurityQuestion;
use Streamline\Models\StaffPositions;
use Streamline\Models\User;
class UserController extends Controller
{
public function __construct()
{
$this->middleware('permission:users-list', ['only' => ['index']]);
$this->middleware('permission:users-create', ['only' => ['create', 'store']]);
$this->middleware('permission:users-edit', ['only' => ['edit', 'update']]);
$this->middleware('permission:users-delete', ['only' => ['destroy']]);
$this->middleware('check-active-users-limit', ['only' => ['create', 'store', 'activate']]);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$data = User::orderBy('first_name', 'asc')->get();
$roles = Role::orderBy('name', 'asc')->select('name', 'id')->get();
$positions = StaffPositions::pluck('name', 'id');
return view('users.index', compact('data', 'positions', 'roles'))->with('i', ($request->input('page', 1) - 1) * 10);
}
public function find_users_by_role(Request $request){
$positions = StaffPositions::pluck('name', 'id');
$roles = Role::orderBy('name', 'asc')->select('name', 'id')->get();
$role = Role::where('id', $request->role)->first();
$data = User::role($role->name)->get();
return view('users.index', compact('data', 'positions', 'roles'))->with('i', ($request->input('page', 1) - 1) * 10);
}
/**
* Get online users
*/
public function onlineusers()
{
$users = User::select("*")
->whereNotNull('last_seen')
->orderBy('last_seen', 'DESC')
->paginate(25);
return view('users.online_users', compact('users'));
}
/**
* Get online users
*/
public function online_users_search(Request $request)
{
$users = User::select("*")
->whereNotNull('last_seen')
->orderBy('last_seen', 'DESC')
->paginate(25);
return view('users.online_users', compact('users'));
}
/**
* Get failed logins
*/
public function failedlogins()
{
$failed_logins = DB::table('failed_login_attempts')->select("*")
->whereNotNull('user_id')
->orderBy('created_at', 'DESC')
->where('created_at', '>=', Carbon::now()->subDay())
->paginate(100);
return view('users.failed_logins', compact('failed_logins'));
}
/**
* Search failed logins
*/
public function failed_logins_search(Request $request)
{
$failed_logins = null;
$dates = $request->dates;
$filters = [];
switch ($dates) {
case 'today':
$today = Carbon::today()->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', $today)->paginate(100);
break;
case 'yesterday':
$yesterday = Carbon::yesterday()->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', $yesterday)->paginate(100);
break;
case 'week':
$week_ago = Carbon::today()->subDays(7)->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '>=', $week_ago)->paginate(100);
break;
case 'month':
$month_ago = Carbon::today()->subDays(30)->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '>=', $month_ago)->paginate(100);
break;
case 'custom-date':
$start_date = Carbon::parse($request->start_date)->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '=', $start_date)->paginate(100);
break;
case 'custom-range':
$start_date = Carbon::parse($request->start_date)->format('Y-m-d');
$end_date = Carbon::parse($request->end_date)->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereBetween('created_at', [$start_date, $end_date])->paginate(100);
break;
default:
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->whereNotNull('user_id')->where($filters)->paginate(25);
break;
}
return view('users.failed_logins', compact('failed_logins'));
}
/**
* Search for online user records with given parameters
*
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Foundation\Application|\Illuminate\View\View
*/
public function search(Request $request)
{
$user_id = $request->user_id;
$action_performed = $request->action_performed;
$records_affected = $request->records_affected;
// Get the selected date criteria
$dates = $request->dates;
$filters = [];
if ($user_id != 'all') :
array_push($filters, ['user_id', '=', $user_id]);
endif;
if ($action_performed != 'all') :
array_push($filters, ['event', '=', $action_performed]);
endif;
if ($records_affected != 'all') :
array_push($filters, ['auditable_type', '=', 'Streamline\\' . $records_affected]);
endif;
// switch the selected date search criteria - today, yesterday, last week, last month etc
switch ($dates) {
case 'today':
$today = Carbon::today()->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', $today)->paginate(100);
break;
case 'yesterday':
$yesterday = Carbon::yesterday()->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', $yesterday)->paginate(100);
break;
case 'week':
$week_ago = Carbon::today()->subDays(7)->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '>=', $week_ago)->paginate(100);
break;
case 'month':
$month_ago = Carbon::today()->subDays(30)->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '>=', $month_ago)->paginate(100);
break;
case 'custom-date':
$start_date = Carbon::parse($request->start_date)->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '=', $start_date)->paginate(100);
break;
case 'custom-range':
$start_date = Carbon::parse($request->start_date)->format('Y-m-d');
$end_date = Carbon::parse($request->end_date)->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereBetween('created_at', [$start_date, $end_date])->paginate(100);
break;
default:
$users = User::orderBy('created_at', 'desc')->where($filters)->paginate(150);
break;
}
if ($users->count() <= 0) {
flash("There are no records found in the search")->error();
}
// users with activity
$user_id_array = DB::table('users')->groupBy('user_id')->select('user_id')->get()->toArray();
$user_id = array(count($user_id_array));
foreach ($user_id_array as $value) {
$user_id[$value->user_id] = get_full_name($value->user_id, 'id', 'first_name', 'last_name', 'users');
}
// remove the count from the array
unset($user_id[0]);
// add --select--
$user_id = ['all' => 'ALL'] + $user_id;
// users with activity
$action_performed_array = DB::table('audits')->groupBy('event')->select('event')->get()->toArray();
$action_performed = array(count($action_performed_array));
foreach ($action_performed_array as $value) {
$action_performed[$value->event] = ucwords($value->event);
}
// remove the count from the array
unset($action_performed[0]);
// add --select--
$action_performed = ['all' => 'ALL'] + $action_performed;
// users with activity
$records_affected_array = DB::table('audits')->groupBy('auditable_type')->select('auditable_type')->get()->toArray();
$records_affected = array(count($records_affected_array));
foreach ($records_affected_array as $value) {
$record = str_replace('Streamline\\', '', $value->auditable_type);
//$records_affected[$record] = $record;
/*================ show better text on forming the drop down ===========*/
$cleaned_model_name = str_replace('Streamline\\', '', $value->auditable_type);
$cleaned_model_name = preg_split('/(?=[A-Z])/', $cleaned_model_name);
$spaced_model_name = implode(' ', $cleaned_model_name);
/*========================================================*/
$records_affected[$record] = $spaced_model_name;
}
// remove the count from the array
unset($records_affected[0]);
// add --select--
$records_affected = ['all' => 'ALL'] + $records_affected;
// get all first names
$first_names = DB::table('users')->pluck('first_name', 'id');
// get all last names
$last_names = DB::table('users')->pluck('last_name', 'id');
return view('users.online_users', compact('users', 'first_names', 'last_names', 'user_id', 'action_performed', 'records_affected'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$positions = DB::table('staff_positions')->orderBy('name')->pluck('name', 'id');
$positions->prepend('- select -', '');
$councils = DB::table('licence_councils')->orderBy('name')->pluck('name', 'id');
$councils->prepend('- select -', '');
$blood_groups = DB::table('blood_groups')->orderBy('name')->pluck('name', 'id');
$blood_groups->prepend('- select -', '');
$security_questions = SecurityQuestion::orderBy('name')->pluck('name', 'id');
$security_questions->prepend('- select -', '');
if (Auth::user()->hasRole('Super Admin')) {
$roles = Role::pluck('name', 'name')->all();
} else {
$roles = Role::where('name', '!=', 'Super Admin')->pluck('name', 'name')->all();
}
return view('users.create', compact('positions', 'councils', 'blood_groups', 'roles', 'security_questions'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request, [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'username' => 'required|string|max:255|unique:users',
//'email' => 'unique:users',
//'pin' => 'required|min:5|max:5',
'position_id' => 'required|integer',
'council_registration' => 'required',
'blood_group_id' => 'required|integer',
'willing_to_donate' => 'required',
'last_donation_date' => 'date_format:d/m/Y|nullable',
'expiry_date' => 'date_format:d/m/Y|nullable',
'password' => 'required|min:6|confirmed',
'photo' => 'image|mimes:jpeg,png,jpg,gif|max:2048',
]);
$user = new User();
/*
* Dealing with the photo
*/
if ($request->hasFile('photo')):
$photo = $request->file('photo');
$photo_name = str_slug($request->username) . '.' . $photo->getClientOriginalExtension();
$destinationPath = public_path('/uploads/users');
$photoPath = $destinationPath . "/" . $photo_name;
$photo->move($destinationPath, $photoPath);
$user->photo = $photo_name;
else:
$user->photo = 'placeholder.png';
endif;
$user->first_name = $request->first_name;
$user->last_name = $request->last_name;
$user->username = $request->username;
$user->phone = $request->phone;
$user->position_id = $request->position_id;
$user->council_registration = $request->council_registration;
$user->council_id = $request->council_id;
$user->registration_number = $request->registration_number;
$user->expiry_date = $request->expiry_date;
$user->email = $request->email;
//$user->pin = $request->pin;
$user->pin = "";
$user->blood_group_id = $request->blood_group_id;
$user->willing_to_donate = $request->willing_to_donate;
$user->last_donation_date = $request->last_donation_date;
$user->password = Hash::make($request->password);
$user->security_question_id = $request->security_question_id;
$user->security_answer = $request->security_answer;
$user->created_by = Auth::user()->id;
$user->save();
$this_user = User::find($user->id);
$this_user->assignRole($request->input('roles'));
// $user = User::create($input);
// $user->assignRole($request->input('roles'));
/*========= start catering for password expiration ========*/
$general_settings = \Streamline\Models\GeneralSettings::find(1);
$user_password_expiration_days = $general_settings->password_expiration_days;
$passwordSecurity = PasswordSecurity::create([
'user_id' => $user->id,
'password_expiry_days' => $user_password_expiration_days,
'password_updated_at' => Carbon::now(),
]);
/*=========== end catering for password expiration =========*/
return redirect()->route('users.index')->with('success', 'New user has been registered on stre@mline');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$user = User::find($id);
$positions = DB::table('staff_positions')->pluck('name', 'id');
$councils = DB::table('licence_councils')->pluck('name', 'id');
$security_questions = SecurityQuestion::pluck('name', 'id');
$blood_groups = DB::table('blood_groups')->pluck('name', 'id');
return view('users.show', compact('user', 'positions', 'blood_groups', 'councils', 'security_questions'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$positions = DB::table('staff_positions')->orderBy('name')->pluck('name', 'id');
$positions->prepend('- select -', '');
$councils = DB::table('licence_councils')->orderBy('name')->pluck('name', 'id');
$councils->prepend('- select -', '');
$blood_groups = DB::table('blood_groups')->orderBy('name')->pluck('name', 'id');
$blood_groups->prepend('- select -', '');
$security_questions = SecurityQuestion::orderBy('name')->pluck('name', 'id');
$security_questions->prepend('- select -', '');
$user = User::find($id);
if (Auth::user()->hasRole('Super Admin')) {
$roles = Role::pluck('name', 'name')->all();
} else {
$roles = Role::where('name', '!=', 'Super Admin')->pluck('name', 'name')->all();
}
$userRole = $user->roles->pluck('name', 'name')->all();
return view('users.edit', compact('positions', 'councils', 'blood_groups', 'user', 'roles', 'userRole', 'security_questions'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->validate($request, [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'username' => 'required|string|max:255|unique:users,username,' . $id,
//'email' => 'unique:users,email,' . $id,
//'pin' => 'required|min:5|max:5',
'position_id' => 'required|integer',
'council_registration' => 'required',
'blood_group_id' => 'required|integer',
'willing_to_donate' => 'required',
'last_donation_date' => 'date_format:d/m/Y|nullable',
'expiry_date' => 'date_format:d/m/Y|nullable',
'password' => 'min:6|confirmed|nullable',
'photo' => 'image|mimes:jpeg,png,jpg,gif|max:2048',
]);
$user = User::find($id);
/*
* Dealing with the uploaded photo
*/
if ($request->hasFile('photo')):
$photo = $request->file('photo');
$photo_name = str_slug($request->username) . '.' . $photo->getClientOriginalExtension();
$destinationPath = public_path('/uploads/users');
$photoPath = $destinationPath . "/" . $photo_name;
$photo->move($destinationPath, $photoPath);
$user->photo = $photo_name;
endif;
// check if a password has been inserted
if ($request->password) {
$user->password = Hash::make($request->password);
}
$user->first_name = $request->first_name;
$user->last_name = $request->last_name;
$user->username = $request->username;
$user->phone = $request->phone;
$user->position_id = $request->position_id;
$user->council_registration = $request->council_registration;
$user->council_id = $request->council_id;
$user->registration_number = $request->registration_number;
$user->expiry_date = $request->expiry_date;
$user->email = $request->email;
$user->pin = $request->pin;
$user->blood_group_id = $request->blood_group_id;
$user->willing_to_donate = $request->willing_to_donate;
$user->last_donation_date = $request->last_donation_date;
$user->security_question_id = $request->security_question_id;
$user->security_answer = $request->security_answer;
$user->updated_by = Auth::user()->id;
$user->save();
if (Auth::user()->can('edit-users-role')):
DB::table('model_has_roles')->where('model_id', $id)->delete();
$this_user = User::find($id);
$this_user->assignRole($request->input('roles'));
endif;
return redirect()->route('users.index')->with('success', 'The user has been updated successfully');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
// check if user to be deleted is the same one logged in
if (Auth::user()->id == $id) {
flash("You cannot delete a user who is logged in.")->error();
return redirect('/users/');
}
$user = User::find($id);
if ($user->delete()):
flash("User has been deleted.")->success();
return redirect('/users/');
endif;
}
/**
* Display a listing of the inactive resource(s).
*
* @return \Illuminate\Http\Response
*/
public function inactive()
{
$users = User::onlyTrashed()
->orderBy('email', 'asc')
->paginate(50);
if (count($users) < 1) {
flash()->error("There is no inactive user");
return redirect('/users/');
} else {
return view('users.inactive', compact('users'));
}
}
/**
* Activate the specified resource in storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function activate($id)
{
$user = User::withTrashed()->find($id);
if ($user->restore()):
flash("User has been activated.")->success();
return redirect('/users/inactive');
endif;
}
public function check_reset(Request $request)
{
$question_id = $request->security_question_id;
$answer = $request->security_answer;
$pin = $request->pin;
/*
* Check if the combination of email and PIN exists in the database
*/
$user = User::where([
['security_question_id', '=', $question_id],
['security_answer', '=', $answer],
['pin', '=', $pin],
])->first();
if ($user === null):
// user doesn't exist, combination is wrongo
flash('Security question, answer or PIN is incorrect. Please verify and try again.')->error();
return redirect()->route('login');
else:
$full_name = $user->first_name . " " . $user->last_name;
$id = $user->id;
$username = $user->username;
flash('Security question, answer and PIN match! Please reset your password below.')->info();
return view('users.reset', compact('full_name', 'username', 'id'));
endif;
}
public function reset_password(Request $request)
{
// $this->validate($request, [
// 'password' => 'min:6|confirmed',
// ]);
$user = User::find($request->id);
$user->password = Hash::make($request->password);
$user->save();
flash('Success! Please login with your new password.')->success();
return redirect()->route('login');
}
public function search_user_by_name(Request $request)
{
$data = [];
if ($request->has('q')) {
$search = $request->q;
$data = User::select("id", "first_name", "last_name")
->orWhere('first_name', 'LIKE', "%$search%")
->orWhere('last_name', 'LIKE', "%$search%")
->get();
}
return response()->json($data);
}
}