Add Roles & Parental Controls

This commit is contained in:
Daniel Supernault 2023-12-27 02:51:47 -07:00
parent f66b9fe74e
commit 7dbdbf15a5
No known key found for this signature in database
GPG key ID: 23740873EE6F76A1
7 changed files with 213 additions and 1 deletions

View file

@ -98,6 +98,7 @@ use App\Jobs\MediaPipeline\MediaSyncLicensePipeline;
use App\Services\DiscoverService;
use App\Services\CustomEmojiService;
use App\Services\MarkerService;
use App\Services\UserRoleService;
use App\Models\Conversation;
use App\Jobs\FollowPipeline\FollowAcceptPipeline;
use App\Jobs\FollowPipeline\FollowRejectPipeline;
@ -1623,6 +1624,8 @@ class ApiV1Controller extends Controller
]);
$user = $request->user();
abort_if($user->has_roles && !UserRoleService::can('can-post', $user->id), 403, 'Invalid permissions for this action');
AccountService::setLastActive($user->id);
if($user->last_active_at == null) {
@ -1792,6 +1795,7 @@ class ApiV1Controller extends Controller
abort_if(!$request->user(), 403);
$user = $request->user();
abort_if($user->has_roles && !UserRoleService::can('can-post', $user->id), 403, 'Invalid permissions for this action');
AccountService::setLastActive($user->id);
$media = Media::whereUserId($user->id)
@ -1831,6 +1835,7 @@ class ApiV1Controller extends Controller
]);
$user = $request->user();
abort_if($user->has_roles && !UserRoleService::can('can-post', $user->id), 403, 'Invalid permissions for this action');
if($user->last_active_at == null) {
return [];
@ -2419,8 +2424,13 @@ class ApiV1Controller extends Controller
$max = $request->input('max_id');
$limit = $request->input('limit') ?? 20;
$user = $request->user();
$remote = $request->has('remote');
$local = $request->has('local');
$userRoleKey = $remote ? 'can-view-network-feed' : 'can-view-public-feed';
if($user->has_roles && !UserRoleService::can($userRoleKey, $user->id)) {
return [];
}
$filtered = $user ? UserFilterService::filters($user->profile_id) : [];
AccountService::setLastActive($user->id);
$domainBlocks = UserFilterService::domainBlocks($user->profile_id);

View file

@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserRolesController extends Controller
{
//
}

23
app/Models/UserRoles.php Normal file
View file

@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\User;
class UserRoles extends Model
{
use HasFactory;
protected $guarded = [];
protected $casts = [
'roles' => 'array'
];
public function user()
{
return $this->belongsTo(User::class);
}
}

View file

@ -14,7 +14,7 @@ class AuthServiceProvider extends ServiceProvider
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
// 'App\Model' => 'App\Policies\ModelPolicy',
];
/**

View file

@ -0,0 +1,111 @@
<?php
namespace App\Services;
use App\Models\UserRoles;
class UserRoleService
{
public static function can($action, $id)
{
$roles = self::get($id);
return in_array($action, $roles) ? $roles[$action] : null;
}
public static function get($id)
{
if($roles = UserRoles::whereUserId($id)->first()) {
return $roles->roles;
}
return self::defaultRoles();
}
public static function roleKeys()
{
return array_keys(self::defaultRoles());
}
public static function defaultRoles()
{
return [
'account-force-private' => true,
'account-ignore-follow-requests' => true,
'can-view-public-feed' => true,
'can-view-network-feed' => true,
'can-view-discover' => true,
'can-post' => true,
'can-comment' => true,
'can-like' => true,
'can-share' => true,
'can-follow' => false,
'can-make-public' => false,
];
}
public static function getRoles($id)
{
$myRoles = self::get($id);
$roleData = collect(self::roleData())
->map(function($role, $k) use($myRoles) {
$role['value'] = $myRoles[$k];
return $role;
})
->toArray();
return $roleData;
}
public static function roleData()
{
return [
'account-force-private' => [
'title' => 'Force Private Account',
'action' => 'Prevent changing account from private'
],
'account-ignore-follow-requests' => [
'title' => 'Ignore Follow Requests',
'action' => 'Hide follow requests and associated notifications'
],
'can-view-public-feed' => [
'title' => 'Hide Public Feed',
'action' => 'Hide the public feed timeline'
],
'can-view-network-feed' => [
'title' => 'Hide Network Feed',
'action' => 'Hide the network feed timeline'
],
'can-view-discover' => [
'title' => 'Hide Discover',
'action' => 'Hide the discover feature'
],
'can-post' => [
'title' => 'Can post',
'action' => 'Allows new posts to be shared'
],
'can-comment' => [
'title' => 'Can comment',
'action' => 'Allows new comments to be posted'
],
'can-like' => [
'title' => 'Can Like',
'action' => 'Allows the ability to like posts and comments'
],
'can-share' => [
'title' => 'Can Share',
'action' => 'Allows the ability to share posts and comments'
],
'can-follow' => [
'title' => 'Can Follow',
'action' => 'Allows the ability to follow accounts'
],
'can-make-public' => [
'title' => 'Can make account public',
'action' => 'Allows the ability to make account public'
],
];
}
}

View file

@ -0,0 +1,30 @@
<?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('user_roles', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('profile_id')->unique()->index();
$table->unsignedInteger('user_id')->unique()->index();
$table->json('roles')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_roles');
}
};

View file

@ -0,0 +1,28 @@
<?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::table('users', function (Blueprint $table) {
$table->boolean('has_roles')->default(false);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('has_roles');
});
}
};