Merge remote-tracking branch 'origin/develop'

This commit is contained in:
snipe 2022-06-29 00:10:38 -07:00
commit f3887aef33
14 changed files with 440 additions and 1 deletions

View file

@ -0,0 +1,97 @@
<?php
namespace App\Console\Commands;
use App\Helpers\Helper;
use Illuminate\Console\Command;
use App\Models\User;
use Laravel\Passport\TokenRepository;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
use DB;
class GeneratePersonalAccessToken extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:make-api-key
{--user_id= : The ID of the user to create the token for.}
{--name= : The name of the new API token}
{--key-only : Only return the value of the API key}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This console command allows you to generate Personal API tokens to be used with the Snipe-IT JSON REST API on behalf of a user.';
/**
* The token repository implementation.
*
* @var \Laravel\Passport\TokenRepository
*/
protected $tokenRepository;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(TokenRepository $tokenRepository, ValidationFactory $validation)
{
$this->validation = $validation;
$this->tokenRepository = $tokenRepository;
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$accessTokenName = $this->option('name');
if ($accessTokenName=='') {
$accessTokenName = 'CLI Auth Token';
}
if ($this->option('user_id')=='') {
return $this->error('ERROR: user_id cannot be blank.');
}
if ($user = User::find($this->option('user_id'))) {
$createAccessToken = $user->createToken($accessTokenName)->accessToken;
if ($this->option('key-only')) {
$this->info($createAccessToken);
} else {
$this->warn('Your API Token has been created. Be sure to copy this token now, as it will not be accessible again.');
if ($token = DB::table('oauth_access_tokens')->where('user_id', '=', $user->id)->where('name','=',$accessTokenName)->orderBy('created_at', 'desc')->first()) {
$this->info('API Token ID: '.$token->id);
}
$this->info('API Token User: '.$user->present()->fullName.' ('.$user->username.')');
$this->info('API Token Name: '.$accessTokenName);
$this->info('API Token: '.$createAccessToken);
}
} else {
return $this->error('ERROR: Invalid user. API key was not created.');
}
}
}

View file

@ -32,6 +32,28 @@ class CategoriesController extends Controller
$categories = $categories->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$categories->where('name', '=', $request->input('name'));
}
if ($request->filled('category_type')) {
$categories->where('category_type', '=', $request->input('category_type'));
}
if ($request->filled('use_default_eula')) {
$categories->where('use_default_eula', '=', $request->input('use_default_eula'));
}
if ($request->filled('require_acceptance')) {
$categories->where('require_acceptance', '=', $request->input('require_acceptance'));
}
if ($request->filled('checkin_email')) {
$categories->where('checkin_email', '=', $request->input('checkin_email'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($categories) && ($request->get('offset') > $categories->count())) ? $categories->count() : $request->get('offset', 0);

View file

@ -43,6 +43,11 @@ class CompaniesController extends Controller
$companies->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$companies->where('name', '=', $request->input('name'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($companies) && ($request->get('offset') > $companies->count())) ? $companies->count() : $request->get('offset', 0);

View file

@ -51,6 +51,10 @@ class ComponentsController extends Controller
$components = $components->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$components->where('name', '=', $request->input('name'));
}
if ($request->filled('company_id')) {
$components->where('company_id', '=', $request->input('company_id'));
}

View file

@ -55,6 +55,10 @@ class ConsumablesController extends Controller
$consumables = $consumables->TextSearch(e($request->input('search')));
}
if ($request->filled('name')) {
$consumables->where('name', '=', $request->input('name'));
}
if ($request->filled('company_id')) {
$consumables->where('company_id', '=', $request->input('company_id'));
}

View file

@ -42,6 +42,22 @@ class DepartmentsController extends Controller
$departments = $departments->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$departments->where('name', '=', $request->input('name'));
}
if ($request->filled('company_id')) {
$departments->where('company_id', '=', $request->input('company_id'));
}
if ($request->filled('manager_id')) {
$departments->where('manager_id', '=', $request->input('manager_id'));
}
if ($request->filled('location_id')) {
$departments->where('location_id', '=', $request->input('location_id'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($departments) && ($request->get('offset') > $departments->count())) ? $departments->count() : $request->get('offset', 0);

View file

@ -28,6 +28,10 @@ class GroupsController extends Controller
$groups = $groups->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$groups->where('name', '=', $request->input('name'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($groups) && ($request->get('offset') > $groups->count())) ? $groups->count() : $request->get('offset', 0);

View file

@ -53,6 +53,30 @@ class LocationsController extends Controller
$locations = $locations->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$locations->where('locations.name', '=', $request->input('name'));
}
if ($request->filled('address')) {
$locations->where('locations.address', '=', $request->input('address'));
}
if ($request->filled('address2')) {
$locations->where('locations.address2', '=', $request->input('address2'));
}
if ($request->filled('city')) {
$locations->where('locations.city', '=', $request->input('city'));
}
if ($request->filled('zip')) {
$locations->where('locations.zip', '=', $request->input('zip'));
}
if ($request->filled('country')) {
$locations->where('locations.country', '=', $request->input('country'));
}
$offset = (($locations) && (request('offset') > $locations->count())) ? $locations->count() : request('offset', 0);
// Check to make sure the limit is not higher than the max allowed

View file

@ -37,6 +37,26 @@ class ManufacturersController extends Controller
$manufacturers = $manufacturers->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$manufacturers->where('name', '=', $request->input('name'));
}
if ($request->filled('url')) {
$manufacturers->where('url', '=', $request->input('url'));
}
if ($request->filled('support_url')) {
$manufacturers->where('support_url', '=', $request->input('support_url'));
}
if ($request->filled('support_phone')) {
$manufacturers->where('support_phone', '=', $request->input('support_phone'));
}
if ($request->filled('support_email')) {
$manufacturers->where('support_email', '=', $request->input('support_email'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($manufacturers) && ($request->get('offset') > $manufacturers->count())) ? $manufacturers->count() : $request->get('offset', 0);

View file

@ -5,10 +5,37 @@ namespace App\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\CheckoutRequest;
use Auth;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Laravel\Passport\TokenRepository;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
use Gate;
use DB;
class ProfileController extends Controller
{
/**
* The token repository implementation.
*
* @var \Laravel\Passport\TokenRepository
*/
protected $tokenRepository;
/**
* Create a controller instance.
*
* @param \Laravel\Passport\TokenRepository $tokenRepository
* @param \Illuminate\Contracts\Validation\Factory $validation
* @return void
*/
public function __construct(TokenRepository $tokenRepository, ValidationFactory $validation)
{
$this->validation = $validation;
$this->tokenRepository = $tokenRepository;
}
/**
* Display a listing of requested assets.
*
@ -42,4 +69,90 @@ class ProfileController extends Controller
return $results;
}
/**
* Delete an API token
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.0.5]
*
* @return \Illuminate\Http\Response
*/
public function createApiToken(Request $request) {
if (!Gate::allows('self.api')) {
abort(403);
}
$accessTokenName = $request->input('name', 'Auth Token');
if ($accessToken = Auth::user()->createToken($accessTokenName)->accessToken) {
// Get the ID so we can return that with the payload
$token = DB::table('oauth_access_tokens')->where('user_id', '=', Auth::user()->id)->where('name','=',$accessTokenName)->orderBy('created_at', 'desc')->first();
$accessTokenData['id'] = $token->id;
$accessTokenData['token'] = $accessToken;
$accessTokenData['name'] = $accessTokenName;
return response()->json(Helper::formatStandardApiResponse('success', $accessTokenData, 'Personal access token '.$accessTokenName.' created successfully'));
}
return response()->json(Helper::formatStandardApiResponse('error', null, 'Token could not be created.'));
}
/**
* Delete an API token
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.0.5]
*
* @return \Illuminate\Http\Response
*/
public function deleteApiToken($tokenId) {
if (!Gate::allows('self.api')) {
abort(403);
}
$token = $this->tokenRepository->findForUser(
$tokenId, Auth::user()->getAuthIdentifier()
);
if (is_null($token)) {
return new Response('', 404);
}
$token->revoke();
return new Response('', Response::HTTP_NO_CONTENT);
}
/**
* Show user's API tokens
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.0.5]
*
* @return \Illuminate\Http\Response
*/
public function showApiTokens(Request $request) {
if (!Gate::allows('self.api')) {
abort(403);
}
$tokens = $this->tokenRepository->forUser(Auth::user()->getAuthIdentifier());
$token_values = $tokens->load('client')->filter(function ($token) {
return $token->client->personal_access_client && ! $token->revoked;
})->values();
return response()->json(Helper::formatStandardApiResponse('success', $token_values, null));
}
}

View file

@ -2,6 +2,9 @@
namespace App\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Helpers\StorageHelper;
use App\Http\Transformers\DatatablesTransformer;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Ldap;
@ -265,4 +268,52 @@ class SettingsController extends Controller
return (new LoginAttemptsTransformer)->transformLoginAttempts($login_attempt_results, $total);
}
public function listBackups() {
$settings = Setting::getSettings();
$path = 'app/backups';
$backup_files = Storage::files($path);
$files_raw = [];
$count = 0;
if (count($backup_files) > 0) {
for ($f = 0; $f < count($backup_files); $f++) {
// Skip dotfiles like .gitignore and .DS_STORE
if ((substr(basename($backup_files[$f]), 0, 1) != '.')) {
$file_timestamp = Storage::lastModified($backup_files[$f]);
$files_raw[] = [
'filename' => basename($backup_files[$f]),
'filesize' => Setting::fileSizeConvert(Storage::size($backup_files[$f])),
'modified_value' => $file_timestamp,
'modified_display' => date($settings->date_display_format.' '.$settings->time_display_format, $file_timestamp),
];
$count++;
}
}
}
$files = array_reverse($files_raw);
return (new DatatablesTransformer)->transformDatatables($files, $count);
}
public function downloadBackup($file) {
$path = 'app/backups';
if (Storage::exists($path.'/'.$file)) {
$headers = ['ContentType' => 'application/zip'];
return Storage::download($path.'/'.$file, $file, $headers);
} else {
return response()->json(Helper::formatStandardApiResponse('error', null, 'File not found'));
}
}
}

View file

@ -30,6 +30,10 @@ class StatuslabelsController extends Controller
$statuslabels = $statuslabels->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$statuslabels->where('name', '=', $request->input('name'));
}
// if a status_type is passed, filter by that
if ($request->filled('status_type')) {

View file

@ -34,6 +34,46 @@ class SuppliersController extends Controller
$suppliers = $suppliers->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$suppliers->where('name', '=', $request->input('name'));
}
if ($request->filled('address')) {
$suppliers->where('address', '=', $request->input('address'));
}
if ($request->filled('address2')) {
$suppliers->where('address2', '=', $request->input('address2'));
}
if ($request->filled('city')) {
$suppliers->where('city', '=', $request->input('city'));
}
if ($request->filled('zip')) {
$suppliers->where('zip', '=', $request->input('zip'));
}
if ($request->filled('country')) {
$suppliers->where('country', '=', $request->input('country'));
}
if ($request->filled('fax')) {
$suppliers->where('fax', '=', $request->input('fax'));
}
if ($request->filled('email')) {
$suppliers->where('email', '=', $request->input('email'));
}
if ($request->filled('url')) {
$suppliers->where('url', '=', $request->input('url'));
}
if ($request->filled('notes')) {
$suppliers->where('notes', '=', $request->input('notes'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($suppliers) && ($request->get('offset') > $suppliers->count())) ? $suppliers->count() : $request->get('offset', 0);

View file

@ -48,6 +48,27 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
]
)->name('api.assets.requestable');
Route::post('personal-access-tokens',
[
Api\ProfileController::class,
'createApiToken'
]
)->name('api.personal-access-token.create');
Route::get('personal-access-tokens',
[
Api\ProfileController::class,
'showApiTokens'
]
)->name('api.personal-access-token.index');
Route::delete('personal-access-tokens/{tokenId}',
[
Api\ProfileController::class,
'deleteApiToken'
]
)->name('api.personal-access-token.delete');
}); // end account group
@ -765,6 +786,20 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
]
)->name('api.settings.mailtest');
Route::get('backups',
[
Api\SettingsController::class,
'listBackups'
]
)->name('api.settings.backups.index');
Route::get('backups/download/{file}',
[
Api\SettingsController::class,
'downloadBackup'
]
)->name('api.settings.backups.download');
});
Route::resource('settings',