From e4ef85a1ce7bbdc33dd75e725a4ec32c0f95acb6 Mon Sep 17 00:00:00 2001 From: Graphictoria Date: Thu, 4 Aug 2022 22:32:18 -0400 Subject: [PATCH] Fix bugs with auth pages, added quick management bar, basic profile, and user rolesets. --- web/app/Helpers/GridHelper.php | 2 +- web/app/Helpers/QAaMBHelper.php | 141 ++++++++ .../Controllers/Api/CommentsController.php | 3 +- .../Http/Controllers/Api/FeedController.php | 3 +- .../Http/Controllers/Api/ShopController.php | 3 +- .../Controllers/Web/ProfileController.php | 19 ++ .../Http/Controllers/Web/TestController.php | 35 ++ web/app/Http/Middleware/Administrator.php | 24 ++ web/app/Models/Roleset.php | 11 + web/app/Models/User.php | 44 +++ web/app/Models/UserRoleset.php | 21 ++ web/app/Providers/AppServiceProvider.php | 26 +- ...022_08_04_193626_create_rolesets_table.php | 32 ++ ...8_04_211729_create_user_rolesets_table.php | 33 ++ web/database/seeders/DatabaseSeeder.php | 3 +- web/database/seeders/RolesetSeeder.php | 26 ++ .../js/components/ThumbnailToolbar.js | 0 web/resources/views/layouts/nav.blade.php | 303 ++++++++++++------ .../views/web/auth/forgot-password.blade.php | 2 +- web/resources/views/web/auth/login.blade.php | 2 +- .../views/web/auth/register.blade.php | 2 +- .../views/web/auth/reset-password.blade.php | 2 +- web/resources/views/web/shop/asset.blade.php | 19 +- .../views/web/user/profile.blade.php | 10 + web/routes/web.php | 5 + 25 files changed, 657 insertions(+), 114 deletions(-) create mode 100644 web/app/Helpers/QAaMBHelper.php create mode 100644 web/app/Http/Controllers/Web/ProfileController.php create mode 100644 web/app/Http/Controllers/Web/TestController.php create mode 100644 web/app/Http/Middleware/Administrator.php create mode 100644 web/app/Models/Roleset.php create mode 100644 web/app/Models/UserRoleset.php create mode 100644 web/database/migrations/2022_08_04_193626_create_rolesets_table.php create mode 100644 web/database/migrations/2022_08_04_211729_create_user_rolesets_table.php create mode 100644 web/database/seeders/RolesetSeeder.php create mode 100644 web/resources/js/components/ThumbnailToolbar.js create mode 100644 web/resources/views/web/user/profile.blade.php diff --git a/web/app/Helpers/GridHelper.php b/web/app/Helpers/GridHelper.php index ca88131..ac6d2f1 100644 --- a/web/app/Helpers/GridHelper.php +++ b/web/app/Helpers/GridHelper.php @@ -38,6 +38,6 @@ class GridHelper public static function createScript($scripts = [], $arguments = []) { - + // TODO: XlXi: this when we get the grid working with the site } } diff --git a/web/app/Helpers/QAaMBHelper.php b/web/app/Helpers/QAaMBHelper.php new file mode 100644 index 0000000..42eb6b6 --- /dev/null +++ b/web/app/Helpers/QAaMBHelper.php @@ -0,0 +1,141 @@ +ConnectServer( '127.0.0.1', 'root\CIMV2' ); + $WbemServices->Security_->ImpersonationLevel = 3; + return $WbemServices->ExecQuery( $query ); + } catch ( \com_exception $e ) { + echo $e->getMessage(); + } + } elseif ( ! extension_loaded( 'com_dotnet' ) ) + trigger_error( 'It seems that the COM is not enabled in your php.ini', E_USER_WARNING ); + else { + $err = error_get_last(); + trigger_error( $err['message'], E_USER_WARNING ); + } + + return false; + } + + public static function getSystemMemoryInfo($output_key = '') + { + return cache()->remember('QAaMB-Memory-Info', 5, function(){ + $keys = array('MemTotal', 'MemFree', 'MemAvailable', 'SwapTotal', 'SwapFree'); + $result = array(); + + try { + if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') { + // LINUX + + $proc_dir = '/proc/'; + $data = _dir_in_allowed_path( $proc_dir ) ? @file( $proc_dir . 'meminfo' ) : false; + if ( is_array( $data ) ) + foreach ( $data as $d ) { + if ( 0 == strlen( trim( $d ) ) ) + continue; + $d = preg_split( '/:/', $d ); + $key = trim( $d[0] ); + if ( ! in_array( $key, $keys ) ) + continue; + $value = 1000 * floatval( trim( str_replace( ' kB', '', $d[1] ) ) ); + $result[$key] = $value; + } + } else { + // WINDOWS + + $wmi_found = false; + if ( $wmi_query = self::wmiWBemLocatorQuery( + "SELECT FreePhysicalMemory,FreeVirtualMemory,TotalSwapSpaceSize,TotalVirtualMemorySize,TotalVisibleMemorySize FROM Win32_OperatingSystem" ) ) { + foreach($wmi_query as $r) { + $result['MemFree'] = $r->FreePhysicalMemory * 1024; + $result['MemAvailable'] = $r->FreeVirtualMemory * 1024; + $result['SwapFree'] = $r->TotalSwapSpaceSize * 1024; + $result['SwapTotal'] = $r->TotalVirtualMemorySize * 1024; + $result['MemTotal'] = $r->TotalVisibleMemorySize * 1024; + $wmi_found = true; + } + } + } + } catch(Exception $e) { + echo $e->getMessage(); + } + return empty($output_key) || !isset($result[$output_key]) ? $result : $result[$output_key]; + }); + } + + public static function getSystemCpuInfo($output_key = '') + { + return cache()->remember('QAaMB-Cpu-Info', 5, function(){ + $result = 0; + + try { + if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') { + // LINUX + + return sys_getloadavg(); + } else { + // WINDOWS + + $wmi_found = false; + if ( $wmi_query = self::wmiWBemLocatorQuery( + "SELECT LoadPercentage FROM Win32_Processor" ) ) { + foreach($wmi_query as $r) { + $result = $r->LoadPercentage / 100; + $wmi_found = true; + } + } + } + } catch(Exception $e) { + echo $e->getMessage(); + } + return empty($output_key) || !isset($result[$output_key]) ? $result : $result[$output_key]; + }); + } + + public static function memoryString($memory) + { + $unit = array('B', 'KB', 'MB', 'GB', 'TB', 'PB'); + return @round($memory/pow(1024,($i=floor(log($memory,1024)))),2).' '.$unit[$i]; + } + + public static function getMemoryUsage() + { + $memoryInfo = self::getSystemMemoryInfo(); + + return sprintf( + '%s of %s (%s%%)
%s Free', + self::memoryString($memoryInfo['MemTotal'] - $memoryInfo['MemFree']), + self::memoryString($memoryInfo['MemTotal']), + round(self::getMemoryPercentage() * 100), + self::memoryString($memoryInfo['MemFree']) + ); + } + + public static function getMemoryPercentage() + { + $memoryInfo = self::getSystemMemoryInfo(); + + return ($memoryInfo['MemTotal'] - $memoryInfo['MemFree']) / $memoryInfo['MemTotal']; + } + + public static function getCpuUsage() + { + return sprintf( + '%s%% CPU Usage', + round(self::getSystemCpuInfo() * 100) + ); + } +} diff --git a/web/app/Http/Controllers/Api/CommentsController.php b/web/app/Http/Controllers/Api/CommentsController.php index a5f5c80..4de98f2 100644 --- a/web/app/Http/Controllers/Api/CommentsController.php +++ b/web/app/Http/Controllers/Api/CommentsController.php @@ -47,11 +47,10 @@ class CommentsController extends Controller foreach($comments as $comment) { // TODO: XlXi: user profile link - // TODO: XlXi: user thumbnail $poster = [ 'name' => $comment->user->username, 'thumbnail' => 'https://www.gtoria.local/images/testing/headshot.png', - 'url' => 'https://gtoria.local/todo123' + 'url' => $comment->user->getProfileUrl() ]; $postDate = $comment['updated_at']; diff --git a/web/app/Http/Controllers/Api/FeedController.php b/web/app/Http/Controllers/Api/FeedController.php index 47f0ea1..77179e4 100644 --- a/web/app/Http/Controllers/Api/FeedController.php +++ b/web/app/Http/Controllers/Api/FeedController.php @@ -38,12 +38,11 @@ class FeedController extends Controller if($post['poster_type'] == 'user') { $user = User::where('id', $post['poster_id'])->first(); - // TODO: XlXi: user profile link $poster = [ 'type' => 'User', 'name' => $user->username, 'thumbnail' => 'https://www.gtoria.local/images/testing/headshot.png', - 'url' => 'https://gtoria.local/todo123' + 'url' => $user->getProfileUrl() ]; } diff --git a/web/app/Http/Controllers/Api/ShopController.php b/web/app/Http/Controllers/Api/ShopController.php index f9a9ede..1d7f313 100644 --- a/web/app/Http/Controllers/Api/ShopController.php +++ b/web/app/Http/Controllers/Api/ShopController.php @@ -72,12 +72,11 @@ class ShopController extends Controller foreach($assets as $asset) { $creator = $asset->user; - // TODO: XlXi: creator profile url array_push($data, [ 'Name' => $asset->name, 'Creator' => [ 'Name' => $creator->username, - 'Url' => 'todo123' + 'Url' => $creator->getProfileUrl() ], 'Thumbnail' => $asset->getThumbnail(), 'Url' => route('shop.asset', ['asset' => $asset->id, 'assetName' => Str::slug($asset->name, '-')]) diff --git a/web/app/Http/Controllers/Web/ProfileController.php b/web/app/Http/Controllers/Web/ProfileController.php new file mode 100644 index 0000000..f33b60a --- /dev/null +++ b/web/app/Http/Controllers/Web/ProfileController.php @@ -0,0 +1,19 @@ +with([ + 'title' => sprintf('Profile of %s', $user->username), + 'user' => $user + ]); + } +} diff --git a/web/app/Http/Controllers/Web/TestController.php b/web/app/Http/Controllers/Web/TestController.php new file mode 100644 index 0000000..3181e6b --- /dev/null +++ b/web/app/Http/Controllers/Web/TestController.php @@ -0,0 +1,35 @@ +OpenJob(SoapService::MakeJobJSON('test', 10, 0, 0, 'test render', $testScript)); + + return response(base64_decode($result->OpenJobExResult->LuaValue[0]->value)) + ->header('Content-Type', 'image/png'); + } +} \ No newline at end of file diff --git a/web/app/Http/Middleware/Administrator.php b/web/app/Http/Middleware/Administrator.php new file mode 100644 index 0000000..7d8c80e --- /dev/null +++ b/web/app/Http/Middleware/Administrator.php @@ -0,0 +1,24 @@ +isAdmin()) + return $next($request); + + return abort(403); + } +} diff --git a/web/app/Models/Roleset.php b/web/app/Models/Roleset.php new file mode 100644 index 0000000..8d0dc85 --- /dev/null +++ b/web/app/Models/Roleset.php @@ -0,0 +1,11 @@ +id) ->where('accepted', false); } + + public function getProfileUrl() + { + return route('user.profile', ['user' => $this->id]); + } + + public function _hasRolesetInternal($roleName) + { + $roleset = Roleset::where('Name', $roleName)->first(); + if( + UserRoleset::where('Roleset_id', $roleset->id) + ->where('User_id', Auth::user()->id) + ->exists() + ) + return true; + + return false; + } + + public function hasRoleset($roleName) + { + if(!Auth::check()) + return false; + + $roleName = strtolower($roleName); + + // Special cases for Owner and Administrator rolesets + if($roleName == 'moderator') { + return ( + $this->_hasRolesetInternal('Owner') || + $this->_hasRolesetInternal('Administrator') || + $this->_hasRolesetInternal('Moderator') + ); + } elseif($roleName == 'administrator') { + return ( + $this->_hasRolesetInternal('Owner') || + $this->_hasRolesetInternal('Administrator') + ); + } + + return $this->_hasRolesetInternal($roleName); + } } diff --git a/web/app/Models/UserRoleset.php b/web/app/Models/UserRoleset.php new file mode 100644 index 0000000..282af08 --- /dev/null +++ b/web/app/Models/UserRoleset.php @@ -0,0 +1,21 @@ +belongsTo(Roleset::class, 'Roleset_id'); + } + + public function user() + { + return $this->belongsTo(User::class, 'User_id'); + } +} diff --git a/web/app/Providers/AppServiceProvider.php b/web/app/Providers/AppServiceProvider.php index 5990509..34fc9ce 100644 --- a/web/app/Providers/AppServiceProvider.php +++ b/web/app/Providers/AppServiceProvider.php @@ -2,7 +2,7 @@ namespace App\Providers; -use Illuminate\Support\Facades\Request; +use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -24,6 +24,28 @@ class AppServiceProvider extends ServiceProvider */ public function boot() { - // + Blade::directive('owner', function() { + return 'hasRoleset(\'Owner\')): ?>'; + }); + + Blade::directive('endowner', function() { + return ''; + }); + + Blade::directive('admin', function() { + return 'hasRoleset(\'Administrator\')): ?>'; + }); + + Blade::directive('endadmin', function() { + return ''; + }); + + Blade::directive('moderator', function() { + return 'hasRoleset(\'Moderator\')): ?>'; + }); + + Blade::directive('endmoderator', function() { + return ''; + }); } } diff --git a/web/database/migrations/2022_08_04_193626_create_rolesets_table.php b/web/database/migrations/2022_08_04_193626_create_rolesets_table.php new file mode 100644 index 0000000..b637c43 --- /dev/null +++ b/web/database/migrations/2022_08_04_193626_create_rolesets_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('Name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('rolesets'); + } +}; diff --git a/web/database/migrations/2022_08_04_211729_create_user_rolesets_table.php b/web/database/migrations/2022_08_04_211729_create_user_rolesets_table.php new file mode 100644 index 0000000..99c4853 --- /dev/null +++ b/web/database/migrations/2022_08_04_211729_create_user_rolesets_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('Roleset_id'); + $table->unsignedBigInteger('User_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('user_rolesets'); + } +}; diff --git a/web/database/seeders/DatabaseSeeder.php b/web/database/seeders/DatabaseSeeder.php index 6639aea..6a1c73a 100644 --- a/web/database/seeders/DatabaseSeeder.php +++ b/web/database/seeders/DatabaseSeeder.php @@ -16,7 +16,8 @@ class DatabaseSeeder extends Seeder { $this->call([ //FFlagSeeder::class, - WebConfigurationSeeder::class + WebConfigurationSeeder::class, + RolesetSeeder::class ]); } } diff --git a/web/database/seeders/RolesetSeeder.php b/web/database/seeders/RolesetSeeder.php new file mode 100644 index 0000000..c3c3e41 --- /dev/null +++ b/web/database/seeders/RolesetSeeder.php @@ -0,0 +1,26 @@ + 'Owner']); + Roleset::create(['name' => 'Administrator']); + Roleset::create(['name' => 'Moderator']); + Roleset::create(['name' => 'ProtectedUser']); + Roleset::create(['name' => 'BetaTester']); + Roleset::create(['name' => 'QATester']); + Roleset::create(['name' => 'Soothsayer']); + } +} diff --git a/web/resources/js/components/ThumbnailToolbar.js b/web/resources/js/components/ThumbnailToolbar.js new file mode 100644 index 0000000..e69de29 diff --git a/web/resources/views/layouts/nav.blade.php b/web/resources/views/layouts/nav.blade.php index a504409..8e326e9 100644 --- a/web/resources/views/layouts/nav.blade.php +++ b/web/resources/views/layouts/nav.blade.php @@ -17,108 +17,217 @@ ]; @endphp - - @endlive + @endmoderator + @endlive + -
+
@foreach(App\Models\Banner::all() as $banner)
style, 'graphictoria-alert', 'alert-dismissible' => $banner->dismissable])>

{{ \App\Helpers\MarkdownHelper::parse($banner->message) }}

diff --git a/web/resources/views/web/auth/forgot-password.blade.php b/web/resources/views/web/auth/forgot-password.blade.php index 1218425..b4c139e 100644 --- a/web/resources/views/web/auth/forgot-password.blade.php +++ b/web/resources/views/web/auth/forgot-password.blade.php @@ -34,7 +34,7 @@
@csrf @foreach($fields as $field => $label) - ($errors->first($field) != null)]) placeholder="{{ $label }}" name="{{ $field }}" :value="old($field)" /> + ($errors->first($field) != null)]) placeholder="{{ $label }}" name="{{ $field }}" value="{{ old($field) }}" /> @endforeach Back  diff --git a/web/resources/views/web/auth/login.blade.php b/web/resources/views/web/auth/login.blade.php index 49881b4..56c658e 100644 --- a/web/resources/views/web/auth/login.blade.php +++ b/web/resources/views/web/auth/login.blade.php @@ -33,7 +33,7 @@ @csrf @foreach($fields as $field => $label) - ($errors->first($field) != null)]) placeholder="{{ $label }}" name="{{ $field }}" :value="old($field)" /> + ($errors->first($field) != null)]) placeholder="{{ $label }}" name="{{ $field }}" value="{{ old($field) }}" /> @endforeach
diff --git a/web/resources/views/web/auth/register.blade.php b/web/resources/views/web/auth/register.blade.php index 9c027b4..53cc177 100644 --- a/web/resources/views/web/auth/register.blade.php +++ b/web/resources/views/web/auth/register.blade.php @@ -33,7 +33,7 @@ @csrf @foreach($fields as $field => $label) - ($errors->first($field) != null)]) placeholder="{{ $label }}" name="{{ $field }}" :value="old($field)" /> + ($errors->first($field) != null)]) placeholder="{{ $label }}" name="{{ $field }}" value="{{ old($field) }}" /> @endforeach diff --git a/web/resources/views/web/auth/reset-password.blade.php b/web/resources/views/web/auth/reset-password.blade.php index 372a19d..14a0249 100644 --- a/web/resources/views/web/auth/reset-password.blade.php +++ b/web/resources/views/web/auth/reset-password.blade.php @@ -27,7 +27,7 @@ @csrf @foreach($fields as $field => $label) - ($errors->first($field) != null)]) placeholder="{{ $label }}" name="{{ $field }}" :value="old($field)" /> + ($errors->first($field) != null)]) placeholder="{{ $label }}" name="{{ $field }}" value="{{ old($field) }}" /> @endforeach diff --git a/web/resources/views/web/shop/asset.blade.php b/web/resources/views/web/shop/asset.blade.php index f5c690a..bf5e655 100644 --- a/web/resources/views/web/shop/asset.blade.php +++ b/web/resources/views/web/shop/asset.blade.php @@ -6,6 +6,13 @@ @endsection +@section('quick-admin') + +@endsection + @section('content')
@if(!$asset->approved) @@ -29,12 +36,18 @@
- {{ $asset->name }} +
+ {{ $asset->name }} +
+
+ + +
+

{{ $asset->name }}

- {{-- TODO: XlXi: url to user's profile --}} -

By {{ $asset->user->username }}

+

By {{ $asset->user->username }}


{{-- TODO: XlXi: limiteds/trading --}}
diff --git a/web/resources/views/web/user/profile.blade.php b/web/resources/views/web/user/profile.blade.php new file mode 100644 index 0000000..105e9b7 --- /dev/null +++ b/web/resources/views/web/user/profile.blade.php @@ -0,0 +1,10 @@ +@extends('layouts.app') + +@section('title', $title) + +@section('page-specific') +@endsection + +@section('content') +

this is {{ $user->username }}'s profile

+@endsection \ No newline at end of file diff --git a/web/routes/web.php b/web/routes/web.php index 38520b8..4f0894e 100644 --- a/web/routes/web.php +++ b/web/routes/web.php @@ -1,6 +1,11 @@ 'user.', 'prefix' => 'users'], function() { + Route::get('/{user}/profile', 'ProfileController@index')->name('profile'); +}); Route::group(['as' => 'home.'], function() { Route::get('/', 'HomeController@landing')->name('landing')->middleware('guest');