Skip to content

Commit

Permalink
Merge pull request #115 from Kurozora/user-settings
Browse files Browse the repository at this point in the history
  • Loading branch information
kiritokatklian authored Apr 18, 2021
2 parents a8a3773 + b51ec31 commit 7f4c8d1
Show file tree
Hide file tree
Showing 15 changed files with 515 additions and 34 deletions.
20 changes: 20 additions & 0 deletions app/Helpers/CustomHelpers.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
<?php

// Create a deeplinked iOS URL
use App\Helpers\Settings;

if (!function_exists('ios_app_url')) {
function ios_app_url($path) {
return config('app.ios_app_protocol') . $path;
}
}

/**
* The settings of the user.
*
* Provided both arguments to set a value. Provide only one to get a value.
* If none is provided, then the Settings object is returned.
*
* @param ?string $key
* @param mixed $value
* @return mixed
*/
function settings(?string $key = null, mixed $value = null): mixed
{
/** @var Settings $settings */
$settings = app(Settings::class);

return $settings->settings($key, $value);
}
160 changes: 160 additions & 0 deletions app/Helpers/Settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?php

namespace App\Helpers;

use App\Models\User;
use Arr;
use Exception;
use JetBrains\PhpStorm\Pure;

class Settings
{
/**
* The User object.
*
* @var User
*/
protected User $user;

/**
* The list of settings.
*
* @var array
*/
protected array $settings = [];

/**
* Create a new settings instance.
*
* @param array $settings
* @param User $user
*/
public function __construct(array $settings, User $user)
{
$this->settings = $settings;
$this->user = $user;
}

/**
* Magic property access for settings.
*
* @param string $key
* @return mixed
* @throws Exception
*/
public function __get(string $key): mixed
{
if ($this->has($key)) {
return $this->get($key);
}

throw new Exception("The $key setting does not exist.");
}

/**
* Create a new settings object for the given user.
*
* @param User $user
* @return Settings
*/
#[Pure]
public static function create(User $user): Settings
{
return new Settings($user->settings, $user);
}

/**
* Retrieve an array of all settings.
*
* @return array
*/
public function all(): array
{
return $this->settings;
}

/**
* Retrieve the given setting.
*
* @param string $key
* @return mixed
*/
public function get(string $key): mixed
{
return Arr::get($this->settings, $key);
}

/**
* Create and persist a new setting.
*
* @param string $key
* @param mixed $value
* @return bool
*/
public function set(string $key, mixed $value): bool
{
$this->settings[$key] = $value;

return $this->persist();
}

/**
* Determine if the given setting exists.
*
* @param string $key
* @return bool
*/
public function has(string $key): bool
{
return array_key_exists($key, $this->settings);
}

/**
* Merge the given attributes with the current settings without assigning any "new" settings.
*
* @param array $attributes
* @return bool
*/
public function merge(array $attributes): bool
{
$this->settings = array_merge(
$this->settings,
Arr::only($attributes, array_keys($this->settings))
);

return $this->persist();
}

/**
* Persist the settings.
*
* @return bool
*/
protected function persist(): bool
{
return $this->user->update(['settings' => $this->settings]);
}

/**
* The settings of the user.
*
* Provided both arguments to set a value. Provide only one to get a value.
* If none is provided, then the Settings object is returned.
*
* @param ?string $key
* @param mixed $value
* @return mixed
*/
public function settings(?string $key = null, mixed $value = null): mixed
{
if (empty($key) && empty($value)) {
return $this;
}

if (empty($value)) {
return $this->get($key);
}

return $this->set($key, $value);
}
}
11 changes: 7 additions & 4 deletions app/Http/Controllers/Auth/SignInWithAppleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,13 @@ protected function signUpUser(JWTPayload $payload): ?User
{
return User::create(
[
'email' => $payload->get('email'),
'siwa_id' => $payload->get('sub'),
'password' => User::hashPass(Str::random(30)),
'username_change_available' => true,
'email' => $payload->get('email'),
'siwa_id' => $payload->get('sub'),
'password' => User::hashPass(Str::random(30)),
'settings' => [
'can_change_username' => true,
'tv_rating' => -1
],
]
);
}
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/MeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function updateProfile(UpdateProfileRequest $request): JsonResponse

// Update username
if ($request->has('username')) {
if (!$user->username_change_available)
if (!settings('can_change_username'))
throw new AuthorizationException('The request wasn’t accepted due to not being allowed to change the username.');

$user->username = $data['username'];
Expand Down
6 changes: 5 additions & 1 deletion app/Http/Controllers/RegistrationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ public function signUp(SignUpRequest $request): JsonResponse
$newUser = User::create([
'username' => $data['username'],
'email' => $data['email'],
'password' => User::hashPass($data['password'])
'password' => User::hashPass($data['password']),
'settings' => [
'can_change_username' => false,
'tv_rating' => -1,
],
]);

if ($request->hasFile('profileImage') &&
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Resources/UserResourceBasic.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ protected function getPrivateDetails(): array

return [
'private' => [
'usernameChangeAvailable' => $user->username_change_available,
'settings' => $user->settings,
]
];
}
Expand Down
2 changes: 1 addition & 1 deletion app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class User extends Authenticatable implements HasMedia, MustVerifyEmail, Reacter
* @var array
*/
protected $casts = [
'username_change_available' => 'boolean',
'settings' => 'json'
];

/**
Expand Down
11 changes: 9 additions & 2 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace App\Providers;

use App\Helpers\Settings;
use Auth;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
Expand Down Expand Up @@ -32,7 +34,7 @@ public function boot()
else Config::set(self::$queryCountConfigKey, $currentConfigValue + 1);
});

/**
/*
* Set the default pagination views.
*
* Options: default, simple-default, tailwind, simple-tailwind
Expand All @@ -48,6 +50,11 @@ public function boot()
*/
public function register()
{
//
// Register the user settings helper class.
$this->app->singleton(Settings::class, function() {
$user = Auth::user();

return new Settings($user->settings, $user);
});
}
}
2 changes: 1 addition & 1 deletion config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
| the framework needs to place the application's version in a notification
| or any other location as required by the application or its packages.
*/
'version' => '1.1.0',
'version' => '1.2.0-alpha.1',

/*
|--------------------------------------------------------------------------
Expand Down
14 changes: 9 additions & 5 deletions database/factories/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ class UserFactory extends Factory
public function definition()
{
return [
'username' => $this->faker->userName,
'email' => $this->faker->unique()->safeEmail,
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'biography' => $this->faker->paragraph(),
'remember_token' => Str::random(10),
'username' => $this->faker->userName,
'email' => $this->faker->unique()->safeEmail,
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'biography' => $this->faker->paragraph(),
'remember_token' => Str::random(10),
'settings' => [
'can_change_username' => false,
'tv_rating' => -1
],
];
}
}
4 changes: 2 additions & 2 deletions database/migrations/2018_08_13_131512_create_users_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ public function up()
$table->string('password')->nullable();
$table->text('two_factor_secret')->nullable();
$table->text('two_factor_recovery_codes')->nullable();
$table->text('biography')->nullable();
$table->rememberToken();
$table->text('biography')->nullable();
$table->json('settings');
$table->timestamp('last_mal_import_at')->nullable();
$table->boolean('username_change_available')->default(false);
$table->timestamps();
});

Expand Down
36 changes: 24 additions & 12 deletions database/seeders/UserSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,25 @@ public function run()
$admins = [];

$admins[] = User::create([
'username' => 'Usopp',
'email' => '[email protected]',
'password' => '$2y$10$LFvuPaQpn6kccakk4sRABef223GV0.NJUJ94Xr.TAvswkCKJBisVK',
'email_verified_at' => now(),
'username' => 'Usopp',
'email' => '[email protected]',
'password' => '$2y$10$LFvuPaQpn6kccakk4sRABef223GV0.NJUJ94Xr.TAvswkCKJBisVK',
'email_verified_at' => now(),
'settings' => [
'can_change_username' => false,
'tv_rating' => -1,
],
]);

$admins[] = User::create([
'username' => 'Kirito',
'email' => '[email protected]',
'password' => '$2y$10$LFvuPaQpn6kccakk4sRABef223GV0.NJUJ94Xr.TAvswkCKJBisVK',
'email_verified_at' => now(),
'username' => 'Kirito',
'email' => '[email protected]',
'password' => '$2y$10$LFvuPaQpn6kccakk4sRABef223GV0.NJUJ94Xr.TAvswkCKJBisVK',
'email_verified_at' => now(),
'settings' => [
'can_change_username' => false,
'tv_rating' => -1,
],
]);

foreach($admins as $admin) {
Expand All @@ -42,10 +50,14 @@ public function run()
* password: KurozoraLovesApple4Ever!
*/
User::create([
'username' => 'JohnAppleseed',
'email' => '[email protected]',
'password' => '$2y$10$/aVrkVAq4LT6FEEw3dNwguaM77MzoHB4.IpVoVxLLEKI4jyHuITii',
'email_verified_at' => now(),
'username' => 'JohnAppleseed',
'email' => '[email protected]',
'password' => '$2y$10$/aVrkVAq4LT6FEEw3dNwguaM77MzoHB4.IpVoVxLLEKI4jyHuITii',
'email_verified_at' => now(),
'settings' => [
'can_change_username' => false,
'tv_rating' => -1,
],
]);

// 50 fake users
Expand Down
6 changes: 3 additions & 3 deletions tests/API/SignInWithAppleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Tests\API;

use App\Helpers\Settings;
use App\Models\Session;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
Expand Down Expand Up @@ -34,9 +35,8 @@ function an_account_can_be_signed_up_via_siwa()
$this->assertEquals(1, Session::count(), 'A session was not created.');

// Check whether the user can change their username
/** @var User $user */
$user = User::first();
$this->assertTrue($user->username_change_available, 'The user does not have a username change available.');
$settings = Settings::create(User::first());
$this->assertTrue($settings->get('can_change_username'), 'The user cannot change their username when it should be possible.');
}

/**
Expand Down
Loading

0 comments on commit 7f4c8d1

Please sign in to comment.