- Added access-api permission.
- Started user profile UI work.
- Created database table and model for tokens.
- Fixed incorrect templates down migration :(
--- /dev/null
+<?php namespace BookStack\Api;
+
+use Illuminate\Database\Eloquent\Model;
+
+class ApiToken extends Model
+{
+ protected $fillable = ['name', 'expires_at'];
+
+}
<?php namespace BookStack\Auth;
+use BookStack\Api\ApiToken;
use BookStack\Model;
use BookStack\Notifications\ResetPassword;
use BookStack\Uploads\Image;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
+use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Notifications\Notifiable;
/**
return $this->belongsTo(Image::class, 'image_id');
}
+ /**
+ * Get the API tokens assigned to this user.
+ */
+ public function apiTokens(): HasMany
+ {
+ return $this->hasMany(ApiToken::class);
+ }
+
/**
* Get the url for editing this user.
- * @return string
*/
- public function getEditUrl()
+ public function getEditUrl(string $path = ''): string
{
- return url('/settings/users/' . $this->id);
+ $uri = '/settings/users/' . $this->id . '/' . trim($path, '/');
+ return url(rtrim($uri, '/'));
}
/**
* Get the url that links to this user's profile.
- * @return mixed
*/
- public function getProfileUrl()
+ public function getProfileUrl(): string
{
return url('/user/' . $this->id);
}
--- /dev/null
+<?php namespace BookStack\Http\Controllers;
+
+use Illuminate\Http\Request;
+
+class UserApiTokenController extends Controller
+{
+
+ /**
+ * Show the form to create a new API token.
+ */
+ public function create(int $userId)
+ {
+ $this->checkPermission('access-api');
+
+ // TODO - Form
+ return 'test';
+ }
+
+
+}
/**
* Show the form for editing the specified user.
- * @param int $id
- * @param \BookStack\Auth\Access\SocialAuthService $socialAuthService
- * @return Response
*/
- public function edit($id, SocialAuthService $socialAuthService)
+ public function edit(int $id, SocialAuthService $socialAuthService)
{
$this->checkPermissionOrCurrentUser('users-manage', $id);
- $user = $this->user->findOrFail($id);
+ $user = $this->user->newQuery()->with(['apiTokens'])->findOrFail($id);
$authMethod = ($user->system_name) ? 'system' : config('auth.method');
$activeSocialDrivers = $socialAuthService->getActiveDrivers();
$this->setPageTitle(trans('settings.user_profile'));
$roles = $this->userRepo->getAllRoles();
- return view('users.edit', ['user' => $user, 'activeSocialDrivers' => $activeSocialDrivers, 'authMethod' => $authMethod, 'roles' => $roles]);
+ return view('users.edit', [
+ 'user' => $user,
+ 'activeSocialDrivers' => $activeSocialDrivers,
+ 'authMethod' => $authMethod,
+ 'roles' => $roles
+ ]);
}
/**
// Remove templates-manage permission
$templatesManagePermission = DB::table('role_permissions')
- ->where('name', '=', 'templates_manage')->first();
+ ->where('name', '=', 'templates-manage')->first();
DB::table('permission_role')->where('permission_id', '=', $templatesManagePermission->id)->delete();
- DB::table('role_permissions')->where('name', '=', 'templates_manage')->delete();
+ DB::table('role_permissions')->where('name', '=', 'templates-manage')->delete();
}
}
--- /dev/null
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Schema;
+
+class AddApiAuth extends Migration
+{
+ /**
+ * Run the migrations.
+ *
+ * @return void
+ */
+ public function up()
+ {
+
+ // Add API tokens table
+ Schema::create('api_tokens', function(Blueprint $table) {
+ $table->increments('id');
+ $table->string('client_id')->index();
+ $table->string('client_secret');
+ $table->integer('user_id')->unsigned()->index();
+ $table->timestamp('expires_at')->index();
+ $table->nullableTimestamps();
+ });
+
+ // Add access-api permission
+ $adminRoleId = DB::table('roles')->where('system_name', '=', 'admin')->first()->id;
+ $permissionId = DB::table('role_permissions')->insertGetId([
+ 'name' => 'access-api',
+ 'display_name' => 'Access system API',
+ 'created_at' => Carbon::now()->toDateTimeString(),
+ 'updated_at' => Carbon::now()->toDateTimeString()
+ ]);
+ DB::table('permission_role')->insert([
+ 'role_id' => $adminRoleId,
+ 'permission_id' => $permissionId
+ ]);
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ // Remove API tokens table
+ Schema::dropIfExists('api_tokens');
+
+ // Remove access-api permission
+ $apiAccessPermission = DB::table('role_permissions')
+ ->where('name', '=', 'access-api')->first();
+
+ DB::table('permission_role')->where('permission_id', '=', $apiAccessPermission->id)->delete();
+ DB::table('role_permissions')->where('name', '=', 'access-api')->delete();
+ }
+}
'role_manage_entity_permissions' => 'Manage all book, chapter & page permissions',
'role_manage_own_entity_permissions' => 'Manage permissions on own book, chapter & pages',
'role_manage_page_templates' => 'Manage page templates',
+ 'role_access_api' => 'Access system API',
'role_manage_settings' => 'Manage app settings',
'role_asset' => 'Asset Permissions',
'role_asset_desc' => 'These permissions control default access to the assets within the system. Permissions on Books, Chapters and Pages will override these permissions.',
'users_social_disconnect' => 'Disconnect Account',
'users_social_connected' => ':socialAccount account was successfully attached to your profile.',
'users_social_disconnected' => ':socialAccount account was successfully disconnected from your profile.',
+ 'users_api_tokens' => 'API Tokens',
+ 'users_api_tokens_none' => 'No API tokens have been created for this user',
+ 'users_api_tokens_create' => 'Create Token',
+
+ // API Tokens
//! If editing translations files directly please ignore this in all
//! languages apart from en. Content will be auto-copied from en.
<a href="#" permissions-table-toggle-all class="text-small text-primary">{{ trans('common.toggle_all') }}</a>
</div>
<div class="toggle-switch-list">
+ <div>@include('settings.roles.checkbox', ['permission' => 'settings-manage', 'label' => trans('settings.role_manage_settings')])</div>
<div>@include('settings.roles.checkbox', ['permission' => 'users-manage', 'label' => trans('settings.role_manage_users')])</div>
<div>@include('settings.roles.checkbox', ['permission' => 'user-roles-manage', 'label' => trans('settings.role_manage_roles')])</div>
<div>@include('settings.roles.checkbox', ['permission' => 'restrictions-manage-all', 'label' => trans('settings.role_manage_entity_permissions')])</div>
<div>@include('settings.roles.checkbox', ['permission' => 'restrictions-manage-own', 'label' => trans('settings.role_manage_own_entity_permissions')])</div>
<div>@include('settings.roles.checkbox', ['permission' => 'templates-manage', 'label' => trans('settings.role_manage_page_templates')])</div>
- <div>@include('settings.roles.checkbox', ['permission' => 'settings-manage', 'label' => trans('settings.role_manage_settings')])</div>
+ <div>@include('settings.roles.checkbox', ['permission' => 'access-api', 'label' => trans('settings.role_access_api')])</div>
</div>
</div>
</div>
</section>
@endif
+
+ {{-- TODO - Review Control--}}
+ @if(($currentUser->id === $user->id && userCan('access-api')) || userCan('manage-users'))
+ <section class="card content-wrap auto-height">
+ <div class="grid half">
+ <div><h2 class="list-heading">{{ trans('settings.users_api_tokens') }}</h2></div>
+ <div class="text-right pt-xs">
+ @if(userCan('access-api'))
+ <a href="{{ $user->getEditUrl('/create-api-token') }}" class="button outline">{{ trans('settings.users_api_tokens_create') }}</a>
+ @endif
+ </div>
+ </div>
+ @if (count($user->apiTokens) > 0)
+
+ @else
+ <p class="text-muted italic py-m">{{ trans('settings.users_api_tokens_none') }}</p>
+ @endif
+ </section>
+ @endif
</div>
@stop
Route::put('/users/{id}', 'UserController@update');
Route::delete('/users/{id}', 'UserController@destroy');
+ // User API Tokens
+ Route::get('/users/{userId}/create-api-token', 'UserApiTokenController@create');
+
// Roles
Route::get('/roles', 'PermissionController@listRoles');
Route::get('/roles/new', 'PermissionController@createRole');