Merge branch 'develop' of https://github.com/snipe/snipe-it into develop
This commit is contained in:
commit
2354e37504
20 changed files with 492 additions and 69 deletions
|
@ -97,6 +97,7 @@ RUN \
|
||||||
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
||||||
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
|
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
|
||||||
&& chown docker "/var/lib/snipeit/keys/" \
|
&& chown docker "/var/lib/snipeit/keys/" \
|
||||||
|
&& chown -h docker "/var/www/html/storage/*.key" \
|
||||||
&& chmod +x /var/www/html/artisan \
|
&& chmod +x /var/www/html/artisan \
|
||||||
&& echo "Finished setting up application in /var/www/html"
|
&& echo "Finished setting up application in /var/www/html"
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ RUN \
|
||||||
&& mkdir -p "/var/lib/snipeit/dumps" && rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \
|
&& mkdir -p "/var/lib/snipeit/dumps" && rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \
|
||||||
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
||||||
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
|
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
|
||||||
|
&& chown -h "/var/www/html/storage/*.key"
|
||||||
&& chown -R apache "/var/lib/snipeit"
|
&& chown -R apache "/var/lib/snipeit"
|
||||||
|
|
||||||
# Install composer
|
# Install composer
|
||||||
|
|
138
app/Http/Controllers/Api/LicenseSeatsController.php
Normal file
138
app/Http/Controllers/Api/LicenseSeatsController.php
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Helpers\Helper;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Transformers\LicenseSeatsTransformer;
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\License;
|
||||||
|
use App\Models\LicenseSeat;
|
||||||
|
use App\Models\User;
|
||||||
|
use Auth;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class LicenseSeatsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index(Request $request, $licenseId)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if ($license = License::find($licenseId)) {
|
||||||
|
$this->authorize('view', $license);
|
||||||
|
|
||||||
|
$seats = LicenseSeat::with('license', 'user', 'asset', 'user.department')
|
||||||
|
->where('license_seats.license_id', $licenseId);
|
||||||
|
|
||||||
|
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||||
|
|
||||||
|
if ($request->input('sort')=='department') {
|
||||||
|
$seats->OrderDepartments($order);
|
||||||
|
} else {
|
||||||
|
$seats->orderBy('id', $order);
|
||||||
|
}
|
||||||
|
|
||||||
|
$total = $seats->count();
|
||||||
|
$offset = (($seats) && (request('offset') > $total)) ? 0 : request('offset', 0);
|
||||||
|
$limit = request('limit', 50);
|
||||||
|
|
||||||
|
$seats = $seats->skip($offset)->take($limit)->get();
|
||||||
|
|
||||||
|
if ($seats) {
|
||||||
|
return (new LicenseSeatsTransformer)->transformLicenseSeats($seats, $total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.does_not_exist')), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function show($licenseId, $seatId)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
$this->authorize('view', License::class);
|
||||||
|
// sanity checks:
|
||||||
|
// 1. does the license seat exist?
|
||||||
|
if (!$licenseSeat = LicenseSeat::find($seatId)) {
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat not found'));
|
||||||
|
}
|
||||||
|
// 2. does the seat belong to the specified license?
|
||||||
|
if (!$license = $licenseSeat->license()->first() || $license->id != intval($licenseId)) {
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat does not belong to the specified license'));
|
||||||
|
}
|
||||||
|
return (new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param int $licenseId
|
||||||
|
* @param int $seatId
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function update(Request $request, $licenseId, $seatId)
|
||||||
|
{
|
||||||
|
$this->authorize('checkout', License::class);
|
||||||
|
|
||||||
|
// sanity checks:
|
||||||
|
// 1. does the license seat exist?
|
||||||
|
if (!$licenseSeat = LicenseSeat::find($seatId)) {
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat not found'));
|
||||||
|
}
|
||||||
|
// 2. does the seat belong to the specified license?
|
||||||
|
if (!$license = $licenseSeat->license()->first() || $license->id != intval($licenseId)) {
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat does not belong to the specified license'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$oldUser = $licenseSeat->user()->first();
|
||||||
|
$oldAsset = $licenseSeat->asset()->first();
|
||||||
|
|
||||||
|
// attempt to update the license seat
|
||||||
|
$licenseSeat->fill($request->all());
|
||||||
|
$licenseSeat->user_id = Auth::user()->id;
|
||||||
|
|
||||||
|
// check if this update is a checkin operation
|
||||||
|
// 1. are relevant fields touched at all?
|
||||||
|
$touched = $licenseSeat->isDirty('assigned_to') || $licenseSeat->isDirty('asset_id');
|
||||||
|
// 2. are they cleared? if yes then this is a checkin operation
|
||||||
|
$is_checkin = ($touched && $licenseSeat->assigned_to === null && $licenseSeat->asset_id === null);
|
||||||
|
|
||||||
|
if (!$touched) {
|
||||||
|
// nothing to update
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($licenseSeat->save()) {
|
||||||
|
// the logging functions expect only one "target". if both asset and user are present in the request,
|
||||||
|
// we simply let assets take precedence over users...
|
||||||
|
$changes = $licenseSeat->getChanges();
|
||||||
|
if (array_key_exists('assigned_to', $changes)) {
|
||||||
|
$target = $is_checkin ? $oldUser : User::find($changes['assigned_to']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('asset_id', $changes)) {
|
||||||
|
$target = $is_checkin ? $oldAsset : Asset::find($changes['asset_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_checkin) {
|
||||||
|
$licenseSeat->logCheckin($target, $request->input('note'));
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
|
||||||
|
}
|
||||||
|
|
||||||
|
// in this case, relevant fields are touched but it's not a checkin operation. so it must be a checkout operation.
|
||||||
|
$licenseSeat->logCheckout($request->input('note'), $target);
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Helper::formatStandardApiResponse('error', null, $licenseSeat->getErrors());
|
||||||
|
}
|
||||||
|
}
|
|
@ -237,50 +237,6 @@ class LicensesController extends Controller
|
||||||
}
|
}
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.assoc_users')));
|
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.assoc_users')));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get license seat listing
|
|
||||||
*
|
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
|
||||||
* @since [v1.0]
|
|
||||||
* @param int $licenseId
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function seats(Request $request, $licenseId)
|
|
||||||
{
|
|
||||||
|
|
||||||
if ($license = License::find($licenseId)) {
|
|
||||||
|
|
||||||
$this->authorize('view', $license);
|
|
||||||
|
|
||||||
$seats = LicenseSeat::with('license', 'user', 'asset', 'user.department')
|
|
||||||
->where('license_seats.license_id', $licenseId);
|
|
||||||
|
|
||||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
|
||||||
|
|
||||||
if ($request->input('sort')=='department') {
|
|
||||||
$seats->OrderDepartments($order);
|
|
||||||
} else {
|
|
||||||
$seats->orderBy('id', $order);
|
|
||||||
}
|
|
||||||
|
|
||||||
$offset = (($seats) && (request('offset') > $seats->count())) ? 0 : request('offset', 0);
|
|
||||||
$limit = request('limit', 50);
|
|
||||||
|
|
||||||
$total = $seats->count();
|
|
||||||
|
|
||||||
$seats = $seats->skip($offset)->take($limit)->get();
|
|
||||||
|
|
||||||
if ($seats) {
|
|
||||||
return (new LicenseSeatsTransformer)->transformLicenseSeats($seats, $total);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.does_not_exist')), 200);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a paginated collection for the select2 menus
|
* Gets a paginated collection for the select2 menus
|
||||||
|
|
|
@ -48,10 +48,9 @@ class ProfileController extends Controller
|
||||||
$user->last_name = $request->input('last_name');
|
$user->last_name = $request->input('last_name');
|
||||||
$user->website = $request->input('website');
|
$user->website = $request->input('website');
|
||||||
$user->gravatar = $request->input('gravatar');
|
$user->gravatar = $request->input('gravatar');
|
||||||
|
$user->skin = $request->input('skin');
|
||||||
$user->phone = $request->input('phone');
|
$user->phone = $request->input('phone');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!config('app.lock_passwords')) {
|
if (!config('app.lock_passwords')) {
|
||||||
$user->locale = $request->input('locale', 'en');
|
$user->locale = $request->input('locale', 'en');
|
||||||
}
|
}
|
||||||
|
|
|
@ -400,6 +400,7 @@ class SettingsController extends Controller
|
||||||
$setting->version_footer = $request->input('version_footer');
|
$setting->version_footer = $request->input('version_footer');
|
||||||
$setting->footer_text = $request->input('footer_text');
|
$setting->footer_text = $request->input('footer_text');
|
||||||
$setting->skin = $request->input('skin');
|
$setting->skin = $request->input('skin');
|
||||||
|
$setting->allow_user_skin = $request->input('allow_user_skin');
|
||||||
$setting->show_url_in_emails = $request->input('show_url_in_emails', '0');
|
$setting->show_url_in_emails = $request->input('show_url_in_emails', '0');
|
||||||
$setting->logo_print_assets = $request->input('logo_print_assets', '0');
|
$setting->logo_print_assets = $request->input('logo_print_assets', '0');
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,11 @@ class LicenseSeatsTransformer
|
||||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transformLicenseSeat (LicenseSeat $seat, $seat_count)
|
public function transformLicenseSeat (LicenseSeat $seat, $seat_count=0)
|
||||||
{
|
{
|
||||||
$array = [
|
$array = [
|
||||||
'id' => (int) $seat->id,
|
'id' => (int) $seat->id,
|
||||||
'license_id' => (int) $seat->license->id,
|
'license_id' => (int) $seat->license->id,
|
||||||
'name' => 'Seat '.$seat_count,
|
|
||||||
'assigned_user' => ($seat->user) ? [
|
'assigned_user' => ($seat->user) ? [
|
||||||
'id' => (int) $seat->user->id,
|
'id' => (int) $seat->user->id,
|
||||||
'name'=> e($seat->user->present()->fullName),
|
'name'=> e($seat->user->present()->fullName),
|
||||||
|
@ -49,6 +48,10 @@ class LicenseSeatsTransformer
|
||||||
'user_can_checkout' => (($seat->assigned_to=='') && ($seat->asset_id=='')),
|
'user_can_checkout' => (($seat->assigned_to=='') && ($seat->asset_id=='')),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if($seat_count != 0) {
|
||||||
|
$array['name'] = 'Seat '.$seat_count;
|
||||||
|
}
|
||||||
|
|
||||||
$permissions_array['available_actions'] = [
|
$permissions_array['available_actions'] = [
|
||||||
'checkout' => Gate::allows('checkout', License::class),
|
'checkout' => Gate::allows('checkout', License::class),
|
||||||
'checkin' => Gate::allows('checkin', License::class),
|
'checkin' => Gate::allows('checkin', License::class),
|
||||||
|
|
|
@ -20,6 +20,16 @@ class LicenseSeat extends SnipeModel implements ICompanyableChild
|
||||||
protected $guarded = 'id';
|
protected $guarded = 'id';
|
||||||
protected $table = 'license_seats';
|
protected $table = 'license_seats';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'assigned_to',
|
||||||
|
'asset_id'
|
||||||
|
];
|
||||||
|
|
||||||
use Acceptable;
|
use Acceptable;
|
||||||
|
|
||||||
public function getCompanyableParents()
|
public function getCompanyableParents()
|
||||||
|
|
|
@ -129,7 +129,13 @@ class LdapAd extends LdapAdConfiguration
|
||||||
$login_username = $username;
|
$login_username = $username;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->ldap->auth()->attempt($login_username, $password, true) === false) {
|
if ($this->ldapConfig['username'] && $this->ldapConfig['password']) {
|
||||||
|
$bind_as_user = false;
|
||||||
|
} else {
|
||||||
|
$bind_as_user = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->ldap->auth()->attempt($login_username, $password, $bind_as_user) === false) {
|
||||||
throw new Exception('Unable to validate user credentials!');
|
throw new Exception('Unable to validate user credentials!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddUserSkinSetting extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
// Update the users table
|
||||||
|
Schema::table('users', function ($table) {
|
||||||
|
$table->string('skin')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
// Update the users table
|
||||||
|
Schema::table('users', function ($table) {
|
||||||
|
$table->dropColumn('skin');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddSettingAllowUserSkin extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
// Update the users table
|
||||||
|
Schema::table('settings', function ($table) {
|
||||||
|
$table->boolean('allow_user_skin')->default(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
// Update the users table
|
||||||
|
Schema::table('settings', function ($table) {
|
||||||
|
$table->dropColumn('allow_user_skin');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,8 @@ return array(
|
||||||
'alerts_enabled' => 'Email Alerts Enabled',
|
'alerts_enabled' => 'Email Alerts Enabled',
|
||||||
'alert_interval' => 'Expiring Alerts Threshold (in days)',
|
'alert_interval' => 'Expiring Alerts Threshold (in days)',
|
||||||
'alert_inv_threshold' => 'Inventory Alert Threshold',
|
'alert_inv_threshold' => 'Inventory Alert Threshold',
|
||||||
|
'allow_user_skin' => 'Allow user skin',
|
||||||
|
'allow_user_skin_help_text' => 'Checking this box will allow a user to change the site skin for himself.' ,
|
||||||
'asset_ids' => 'Asset IDs',
|
'asset_ids' => 'Asset IDs',
|
||||||
'audit_interval' => 'Audit Interval',
|
'audit_interval' => 'Audit Interval',
|
||||||
'audit_interval_help' => 'If you are required to regularly physically audit your assets, enter the interval in months.',
|
'audit_interval_help' => 'If you are required to regularly physically audit your assets, enter the interval in months.',
|
||||||
|
|
|
@ -582,3 +582,34 @@ Form::macro('skin', function ($name = "skin", $selected = null, $class = null) {
|
||||||
return $select;
|
return $select;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Form::macro('user_skin', function ($name = "skin", $selected = null, $class = null) {
|
||||||
|
|
||||||
|
$formats = array(
|
||||||
|
'' => 'Site Default',
|
||||||
|
'blue' => 'Default Blue',
|
||||||
|
'blue-dark' => 'Blue (Dark Mode)',
|
||||||
|
'green' => 'Green Dark',
|
||||||
|
'green-dark' => 'Green (Dark Mode)',
|
||||||
|
'red' => 'Red Dark',
|
||||||
|
'red-dark' => 'Red (Dark Mode)',
|
||||||
|
'orange' => 'Orange Dark',
|
||||||
|
'orange-dark' => 'Orange (Dark Mode)',
|
||||||
|
'black' => 'Black',
|
||||||
|
'black-dark' => 'Black (Dark Mode)',
|
||||||
|
'purple' => 'Purple',
|
||||||
|
'purple-dark' => 'Purple (Dark Mode)',
|
||||||
|
'yellow' => 'Yellow',
|
||||||
|
'yellow-dark' => 'Yellow (Dark Mode)',
|
||||||
|
'contrast' => 'High Contrast',
|
||||||
|
);
|
||||||
|
|
||||||
|
$select = '<select name="'.$name.'" class="'.$class.'" style="width: 250px">';
|
||||||
|
foreach ($formats as $format => $label) {
|
||||||
|
$select .= '<option value="'.$format.'"'.($selected == $format ? ' selected="selected"' : '').'>'.$label.'</option> '."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$select .= '</select>';
|
||||||
|
return $select;
|
||||||
|
|
||||||
|
});
|
|
@ -58,6 +58,17 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if ($snipeSettings->allow_user_skin=='1')
|
||||||
|
<!-- Skin -->
|
||||||
|
<div class="form-group {{ $errors->has('skin') ? 'error' : '' }}">
|
||||||
|
<label for="website" class="col-md-3 control-label">{{ Form::label('skin', trans('general.skin')) }}</label>
|
||||||
|
<div class="col-md-8">
|
||||||
|
{!! Form::user_skin('skin', Input::old('skin', $user->skin), 'select2') !!}
|
||||||
|
{!! $errors->first('skin', '<span class="alert-msg">:message</span>') !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<!-- Phone -->
|
<!-- Phone -->
|
||||||
<div class="form-group {{ $errors->has('phone') ? 'has-error' : '' }}">
|
<div class="form-group {{ $errors->has('phone') ? 'has-error' : '' }}">
|
||||||
<label class="col-md-3 control-label" for="phone">{{ trans('admin/users/table.phone') }}</label>
|
<label class="col-md-3 control-label" for="phone">{{ trans('admin/users/table.phone') }}</label>
|
||||||
|
@ -67,8 +78,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Website URL -->
|
<!-- Website URL -->
|
||||||
<div class="form-group {{ $errors->has('website') ? ' has-error' : '' }}">
|
<div class="form-group {{ $errors->has('website') ? ' has-error' : '' }}">
|
||||||
<label for="website" class="col-md-3 control-label">{{ trans('general.website') }}</label>
|
<label for="website" class="col-md-3 control-label">{{ trans('general.website') }}</label>
|
||||||
|
@ -114,8 +123,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Two factor opt in -->
|
<!-- Two factor opt in -->
|
||||||
@if ($snipeSettings->two_factor_enabled=='1')
|
@if ($snipeSettings->two_factor_enabled=='1')
|
||||||
<div class="form-group {{ $errors->has('avatar') ? 'has-error' : '' }}">
|
<div class="form-group {{ $errors->has('avatar') ? 'has-error' : '' }}">
|
||||||
|
|
|
@ -28,13 +28,13 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{-- stylesheets --}}
|
{{-- stylesheets --}}
|
||||||
|
<link rel="stylesheet" href="{{ mix('css/all.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url(mix('css/dist/all.css')) }}">
|
@if (($snipeSettings) && ($snipeSettings->allow_user_skin==1) && Auth::check() && Auth::user()->present()->skin != '')
|
||||||
|
<link rel="stylesheet" href="{{ mix('css/skins/skin-'.Auth::user()->present()->skin.'.min.css') }}">
|
||||||
|
@elseif (($snipeSettings) && ($snipeSettings->skin!=''))
|
||||||
<link rel="stylesheet" href="{{ url(mix('css/dist/skins/skin-'.($snipeSettings->skin!='' ? $snipeSettings->skin : 'blue').'.css')) }}">
|
<link rel="stylesheet" href="{{ url(mix('css/dist/skins/skin-'.($snipeSettings->skin!='' ? $snipeSettings->skin : 'blue').'.css')) }}">
|
||||||
|
@endif
|
||||||
|
{{-- page level css --}}
|
||||||
|
|
||||||
{{-- page level css --}}
|
|
||||||
@stack('css')
|
@stack('css')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,7 @@
|
||||||
data-sort-order="asc"
|
data-sort-order="asc"
|
||||||
data-sort-name="name"
|
data-sort-name="name"
|
||||||
class="table table-striped snipe-table"
|
class="table table-striped snipe-table"
|
||||||
data-url="{{ route('api.license.seats', $license->id) }}"
|
data-url="{{ route('api.licenses.seats.index', $license->id) }}"
|
||||||
data-export-options='{
|
data-export-options='{
|
||||||
"fileName": "export-seats-{{ str_slug($license->name) }}-{{ date('Y-m-d') }}",
|
"fileName": "export-seats-{{ str_slug($license->name) }}-{{ date('Y-m-d') }}",
|
||||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
iconsPrefix: 'fa',
|
iconsPrefix: 'fa',
|
||||||
cookie: true,
|
cookie: true,
|
||||||
cookieExpire: '2y',
|
cookieExpire: '2y',
|
||||||
cookieIdTable: '{{ Route::currentRouteName() }}',
|
|
||||||
mobileResponsive: true,
|
mobileResponsive: true,
|
||||||
maintainSelected: true,
|
maintainSelected: true,
|
||||||
trimOnSearch: false,
|
trimOnSearch: false,
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Email format -->
|
<!-- Skin -->
|
||||||
<div class="form-group {{ $errors->has('skin') ? 'error' : '' }}">
|
<div class="form-group {{ $errors->has('skin') ? 'error' : '' }}">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
{{ Form::label('skin', trans('general.skin')) }}
|
{{ Form::label('skin', trans('general.skin')) }}
|
||||||
|
@ -161,6 +161,17 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Allow User Skin -->
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-3">
|
||||||
|
{{ Form::label('allow_user_skin', trans('admin/settings/general.allow_user_skin')) }}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
{{ Form::checkbox('allow_user_skin', '1', Input::old('allow_user_skin', $setting->allow_user_skin),array('class' => 'minimal')) }}
|
||||||
|
{{ trans('general.yes') }}
|
||||||
|
<p class="help-block">{{ trans('admin/settings/general.allow_user_skin_help_text') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Custom css -->
|
<!-- Custom css -->
|
||||||
<div class="form-group {{ $errors->has('custom_css') ? 'error' : '' }}">
|
<div class="form-group {{ $errors->has('custom_css') ? 'error' : '' }}">
|
||||||
|
|
|
@ -166,7 +166,6 @@ Route::group(['prefix' => 'v1','namespace' => 'Api', 'middleware' => 'auth:api']
|
||||||
|
|
||||||
/*--- Departments API ---*/
|
/*--- Departments API ---*/
|
||||||
|
|
||||||
/*--- Suppliers API ---*/
|
|
||||||
Route::group(['prefix' => 'departments'], function () {
|
Route::group(['prefix' => 'departments'], function () {
|
||||||
|
|
||||||
|
|
||||||
|
@ -496,11 +495,6 @@ Route::group(['prefix' => 'v1','namespace' => 'Api', 'middleware' => 'auth:api']
|
||||||
/*--- Licenses API ---*/
|
/*--- Licenses API ---*/
|
||||||
|
|
||||||
Route::group(['prefix' => 'licenses'], function () {
|
Route::group(['prefix' => 'licenses'], function () {
|
||||||
Route::get('{licenseId}/seats', [
|
|
||||||
'as' => 'api.license.seats',
|
|
||||||
'uses' => 'LicensesController@seats'
|
|
||||||
]);
|
|
||||||
|
|
||||||
Route::get('selectlist',
|
Route::get('selectlist',
|
||||||
[
|
[
|
||||||
'as' => 'api.licenses.selectlist',
|
'as' => 'api.licenses.selectlist',
|
||||||
|
@ -525,7 +519,18 @@ Route::group(['prefix' => 'v1','namespace' => 'Api', 'middleware' => 'auth:api']
|
||||||
]
|
]
|
||||||
); // Licenses resource
|
); // Licenses resource
|
||||||
|
|
||||||
|
Route::resource('licenses.seats', 'LicenseSeatsController',
|
||||||
|
[
|
||||||
|
'names' =>
|
||||||
|
[
|
||||||
|
'index' => 'api.licenses.seats.index',
|
||||||
|
'show' => 'api.licenses.seats.show',
|
||||||
|
'update' => 'api.licenses.seats.update'
|
||||||
|
],
|
||||||
|
'except' => ['create', 'edit', 'destroy', 'store'],
|
||||||
|
'parameters' => ['licenseseat' => 'licenseseat_id']
|
||||||
|
]
|
||||||
|
); // Licenseseats resource
|
||||||
|
|
||||||
/*--- Locations API ---*/
|
/*--- Locations API ---*/
|
||||||
|
|
||||||
|
|
185
tests/api/ApiLicenseSeatsCest.php
Normal file
185
tests/api/ApiLicenseSeatsCest.php
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Transformers\LicenseSeatsTransformer;
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\License;
|
||||||
|
use App\Models\LicenseSeat;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
class ApiLicenseSeatsCest
|
||||||
|
{
|
||||||
|
protected $license;
|
||||||
|
protected $timeFormat;
|
||||||
|
|
||||||
|
public function _before(ApiTester $I)
|
||||||
|
{
|
||||||
|
$this->user = \App\Models\User::find(1);
|
||||||
|
$I->haveHttpHeader('Accept', 'application/json');
|
||||||
|
$I->amBearerAuthenticated($I->getToken($this->user));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function indexLicenseSeats(ApiTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('Get a list of license seats for a specific license');
|
||||||
|
|
||||||
|
// call
|
||||||
|
$I->sendGET('/licenses/1/seats?limit=10&order=desc');
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
|
||||||
|
// sample verify
|
||||||
|
$licenseSeats = App\Models\LicenseSeat::where('license_id', 1)
|
||||||
|
->orderBy('id','desc')->take(10)->get();
|
||||||
|
// pick a random seat
|
||||||
|
$licenseSeat = $licenseSeats->random();
|
||||||
|
// need the index in the original list so that the "name" field is determined correctly
|
||||||
|
$licenseSeatNumber = 0;
|
||||||
|
foreach($licenseSeats as $index=>$seat) {
|
||||||
|
if ($licenseSeat === $seat) {
|
||||||
|
$licenseSeatNumber = $index+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat, $licenseSeatNumber)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function showLicenseSeat(ApiTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('Get a license seat');
|
||||||
|
|
||||||
|
// call
|
||||||
|
$I->sendGET('/licenses/1/seats/10');
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
|
||||||
|
// sample verify
|
||||||
|
$licenseSeat = App\Models\LicenseSeat::findOrFail(10);
|
||||||
|
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function checkoutLicenseSeatToUser(ApiTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('Checkout a license seat to a user');
|
||||||
|
|
||||||
|
$user = App\Models\User::all()->random();
|
||||||
|
$licenseSeat = App\Models\LicenseSeat::all()->random();
|
||||||
|
$endpoint = '/licenses/'.$licenseSeat->license_id.'/seats/'.$licenseSeat->id;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'assigned_to' => $user->id,
|
||||||
|
'note' => 'Test Checkout to User via API'
|
||||||
|
];
|
||||||
|
|
||||||
|
// update
|
||||||
|
$I->sendPATCH($endpoint, $data);
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
|
||||||
|
$response = json_decode($I->grabResponse());
|
||||||
|
$I->assertEquals('success', $response->status);
|
||||||
|
$I->assertEquals(trans('admin/licenses/message.update.success'), $response->messages);
|
||||||
|
$I->assertEquals($licenseSeat->license_id, $response->payload->license_id); // license id does not change
|
||||||
|
$I->assertEquals($licenseSeat->id, $response->payload->id); // license seat id does not change
|
||||||
|
|
||||||
|
// verify
|
||||||
|
$licenseSeat = $licenseSeat->fresh();
|
||||||
|
$I->sendGET($endpoint);
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat)));
|
||||||
|
|
||||||
|
// verify that the last logged action is a checkout
|
||||||
|
$I->sendGET('/reports/activity?item_type=license&limit=1&item_id='.$licenseSeat->license_id);
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
$I->seeResponseContainsJson([
|
||||||
|
"action_type" => "checkout"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function checkoutLicenseSeatToAsset(ApiTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('Checkout a license seat to an asset');
|
||||||
|
|
||||||
|
$asset = App\Models\Asset::all()->random();
|
||||||
|
$licenseSeat = App\Models\LicenseSeat::all()->random();
|
||||||
|
$endpoint = '/licenses/'.$licenseSeat->license_id.'/seats/'.$licenseSeat->id;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'asset_id' => $asset->id,
|
||||||
|
'note' => 'Test Checkout to Asset via API'
|
||||||
|
];
|
||||||
|
|
||||||
|
// update
|
||||||
|
$I->sendPATCH($endpoint, $data);
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
|
||||||
|
$response = json_decode($I->grabResponse());
|
||||||
|
$I->assertEquals('success', $response->status);
|
||||||
|
$I->assertEquals(trans('admin/licenses/message.update.success'), $response->messages);
|
||||||
|
$I->assertEquals($licenseSeat->license_id, $response->payload->license_id); // license id does not change
|
||||||
|
$I->assertEquals($licenseSeat->id, $response->payload->id); // license seat id does not change
|
||||||
|
|
||||||
|
// verify
|
||||||
|
$licenseSeat = $licenseSeat->fresh();
|
||||||
|
$I->sendGET($endpoint);
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat)));
|
||||||
|
|
||||||
|
// verify that the last logged action is a checkout
|
||||||
|
$I->sendGET('/reports/activity?item_type=license&limit=1&item_id='.$licenseSeat->license_id);
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
$I->seeResponseContainsJson([
|
||||||
|
"action_type" => "checkout"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function checkoutLicenseSeatToUserAndAsset(ApiTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('Checkout a license seat to a user AND an asset');
|
||||||
|
|
||||||
|
$asset = App\Models\Asset::all()->random();
|
||||||
|
$user = App\Models\User::all()->random();
|
||||||
|
$licenseSeat = App\Models\LicenseSeat::all()->random();
|
||||||
|
$endpoint = '/licenses/'.$licenseSeat->license_id.'/seats/'.$licenseSeat->id;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'asset_id' => $asset->id,
|
||||||
|
'assigned_to' => $user->id,
|
||||||
|
'note' => 'Test Checkout to User and Asset via API'
|
||||||
|
];
|
||||||
|
|
||||||
|
// update
|
||||||
|
$I->sendPATCH($endpoint, $data);
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
|
||||||
|
$response = json_decode($I->grabResponse());
|
||||||
|
$I->assertEquals('success', $response->status);
|
||||||
|
$I->assertEquals(trans('admin/licenses/message.update.success'), $response->messages);
|
||||||
|
$I->assertEquals($licenseSeat->license_id, $response->payload->license_id); // license id does not change
|
||||||
|
$I->assertEquals($licenseSeat->id, $response->payload->id); // license seat id does not change
|
||||||
|
|
||||||
|
// verify
|
||||||
|
$licenseSeat = $licenseSeat->fresh();
|
||||||
|
$I->sendGET($endpoint);
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat)));
|
||||||
|
|
||||||
|
// verify that the last logged action is a checkout
|
||||||
|
$I->sendGET('/reports/activity?item_type=license&limit=1&item_id='.$licenseSeat->license_id);
|
||||||
|
$I->seeResponseIsJson();
|
||||||
|
$I->seeResponseCodeIs(200);
|
||||||
|
$I->seeResponseContainsJson([
|
||||||
|
"action_type" => "checkout"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue