Merge branch 'develop'

This commit is contained in:
snipe 2017-10-02 13:09:17 -07:00
commit e389f67629
40 changed files with 1177 additions and 64682 deletions

View file

@ -43,7 +43,7 @@ before_script:
# use the $DB env variable to determine the phpunit.xml to use
# script: ./vendor/bin/codecept run --env testing-ci
script:
- ./vendor/bin/codecept run unit --env testing-ci
- ./vendor/bin/codecept run unit
# - ./vendor/bin/codecept run acceptance --env=testing-ci
- ./vendor/bin/codecept run functional --env=functional-travis
#script: ./vendor/bin/codecept run

View file

@ -23,7 +23,7 @@ class LocationsController extends Controller
$allowed_columns = ['id','name','address','address2','city','state','country','zip','created_at',
'updated_at','parent_id', 'manager_id'];
$locations = Location::select([
$locations = Location::with('parent', 'manager', 'childLocations')->select([
'locations.id',
'locations.name',
'locations.address',
@ -37,7 +37,10 @@ class LocationsController extends Controller
'locations.created_at',
'locations.updated_at',
'locations.currency'
])->withCount('assets')->withCount('users');
])->withCount('locationAssets')
->withCount('assignedAssets')
->withCount('assets')
->withCount('users');
if ($request->has('search')) {
$locations = $locations->TextSearch($request->input('search'));
@ -52,7 +55,6 @@ class LocationsController extends Controller
$total = $locations->count();
$locations = $locations->skip($offset)->take($limit)->get();
return (new LocationsTransformer)->transformLocations($locations, $total);
}
@ -74,7 +76,6 @@ class LocationsController extends Controller
return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
}
/**
@ -109,7 +110,13 @@ class LocationsController extends Controller
$location->fill($request->all());
if ($location->save()) {
return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.update.success')));
return response()->json(
Helper::formatStandardApiResponse(
'success',
(new LocationsTransformer)->transformLocation($location),
trans('admin/locations/message.update.success')
)
);
}
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
@ -130,6 +137,5 @@ class LocationsController extends Controller
$this->authorize('delete', $location);
$location->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/locations/message.delete.success')));
}
}

View file

@ -75,7 +75,7 @@ class AssetsController extends Controller
} else {
$company = null;
}
return view('hardware/index')->with('company',$company);
return view('hardware/index')->with('company', $company);
}
/**
@ -94,7 +94,6 @@ class AssetsController extends Controller
}
$this->authorize('view', $asset);
return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch);
}
/**
@ -126,9 +125,7 @@ class AssetsController extends Controller
if ($request->has('model_id')) {
$selected_model = AssetModel::find($request->input('model_id'));
$view->with('selected_model', $selected_model);
} else {
}
return $view;
}
@ -168,7 +165,6 @@ class AssetsController extends Controller
// Create the image (if one was chosen.)
if (Input::has('image')) {
$image = Input::get('image');
// After modification, the image is prefixed by mime info like the following:
@ -201,7 +197,6 @@ class AssetsController extends Controller
->put('default', $messageBag));
return response()->json(['image' => $e->getMessage()], 422);
}
}
@ -211,31 +206,26 @@ class AssetsController extends Controller
// Need to investigate and fix. Using static method for now.
$model = AssetModel::find($request->get('model_id'));
if ($model->fieldset) {
foreach ($model->fieldset->fields as $field) {
if ($field->field_encrypted=='1') {
if (Gate::allows('admin')) {
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt($request->input($field->convertUnicodeDbSlug()));
}
} else {
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
}
}
}
// Was the asset created?
if ($asset->save()) {
$asset->logCreate();
if(request('assigned_user')) {
if (request('assigned_user')) {
$target = User::find(request('assigned_user'));
} elseif(request('assigned_asset')) {
} elseif (request('assigned_asset')) {
$target = Asset::find(request('assigned_asset'));
} elseif(request('assigned_location')) {
} elseif (request('assigned_location')) {
$target = Location::find(request('assigned_location'));
}
if (isset($target)) {
@ -291,7 +281,6 @@ class AssetsController extends Controller
public function update(AssetRequest $request, $assetId = null)
{
// Check if the asset exists
if (!$asset = Asset::find($assetId)) {
// Redirect to the asset management page with error
@ -369,7 +358,6 @@ class AssetsController extends Controller
if (Gate::allows('admin')) {
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt(e($request->input($field->convertUnicodeDbSlug())));
}
} else {
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
}
@ -385,7 +373,6 @@ class AssetsController extends Controller
\Input::flash();
\Session::flash('errors', $asset->getErrors());
return response()->json(['errors' => $asset->getErrors()], 500);
}
/**
@ -447,7 +434,6 @@ class AssetsController extends Controller
->with('users_list', Helper::usersList())
->with('assets_list', Helper::assetsList())
->with('locations_list', Helper::locationsList());
}
/**
@ -469,11 +455,11 @@ class AssetsController extends Controller
}
$this->authorize('checkout', $asset);
if(request('assigned_user')) {
if (request('assigned_user')) {
$target = User::find(request('assigned_user'));
} elseif(request('assigned_asset')) {
} elseif (request('assigned_asset')) {
$target = Asset::find(request('assigned_asset'));
} elseif(request('assigned_location')) {
} elseif (request('assigned_location')) {
$target = Location::find(request('assigned_location'));
}
// $user = User::find(Input::get('assigned_to'));
@ -519,7 +505,6 @@ class AssetsController extends Controller
$this->authorize('checkin', $asset);
return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
}
@ -544,7 +529,7 @@ class AssetsController extends Controller
$this->authorize('checkin', $asset);
$admin = Auth::user();
if($asset->assignedType() == Asset::USER) {
if ($asset->assignedType() == Asset::USER) {
$user = $asset->assignedTo;
}
if (is_null($target = $asset->assignedTo)) {
@ -583,7 +568,7 @@ class AssetsController extends Controller
}
if ($backto=='user') {
return redirect()->to("admin/users/".$user->id.'/view')->with('success', trans('admin/hardware/message.checkin.success'));
return redirect()->route("users.show", $user->id)->with('success', trans('admin/hardware/message.checkin.success'));
}
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkin.success'));
}
@ -607,15 +592,16 @@ class AssetsController extends Controller
$asset = Asset::withTrashed()->find($assetId);
$this->authorize('view', $asset);
$settings = Setting::getSettings();
$audit_log = Actionlog::where('action_type','=','audit')->where('item_id','=',$assetId)->where('item_type','=',Asset::class)->orderBy('created_at','DESC')->first();
$audit_log = Actionlog::where('action_type', '=', 'audit')
->where('item_id', '=', $assetId)
->where('item_type', '=', Asset::class)
->orderBy('created_at', 'DESC')->first();
if (isset($asset)) {
if (!is_null($asset->assetloc)) {
$use_currency = $asset->assetloc->currency;
} else {
if ($settings->default_currency!='') {
$use_currency = $settings->default_currency;
} else {
@ -629,7 +615,7 @@ class AssetsController extends Controller
);
return view('hardware/view', compact('asset', 'qr_code', 'settings'))
->with('use_currency', $use_currency)->with('audit_log',$audit_log);
->with('use_currency', $use_currency)->with('audit_log', $audit_log);
}
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist', compact('id')));
@ -652,8 +638,7 @@ class AssetsController extends Controller
$size = Helper::barcodeDimensions($settings->barcode_type);
$qr_file = public_path().'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png';
if (isset($asset->id,$asset->asset_tag)) {
if (isset($asset->id, $asset->asset_tag)) {
if (file_exists($qr_file)) {
$header = ['Content-type' => 'image/png'];
return response()->file($qr_file, $header);
@ -665,7 +650,6 @@ class AssetsController extends Controller
}
}
}
}
@ -683,8 +667,7 @@ class AssetsController extends Controller
$asset = Asset::find($assetId);
$barcode_file = public_path().'/uploads/barcodes/'.str_slug($settings->alt_barcode).'-'.str_slug($asset->asset_tag).'.png';
if (isset($asset->id,$asset->asset_tag)) {
if (isset($asset->id, $asset->asset_tag)) {
if (file_exists($barcode_file)) {
$header = ['Content-type' => 'image/png'];
return response()->file($barcode_file, $header);
@ -695,7 +678,6 @@ class AssetsController extends Controller
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
}
}
}
/**
@ -762,7 +744,6 @@ class AssetsController extends Controller
*/
public function postImportHistory(Request $request)
{
if (!ini_get("auto_detect_line_endings")) {
ini_set("auto_detect_line_endings", '1');
}
@ -780,9 +761,7 @@ class AssetsController extends Controller
foreach ($results as $row) {
if (is_array($row)) {
$row = array_change_key_case($row, CASE_LOWER);
$asset_tag = Helper::array_smart_fetch($row, "asset tag");
if (!array_key_exists($asset_tag, $item)) {
@ -797,7 +776,6 @@ class AssetsController extends Controller
$item[$asset_tag][$batch_counter]['email'] = Helper::array_smart_fetch($row, "email");
if ($asset = Asset::where('asset_tag', '=', $asset_tag)->first()) {
$item[$asset_tag][$batch_counter]['asset_id'] = $asset->id;
$base_username = User::generateFormattedNameFromFullName(Setting::getSettings()->username_format, $item[$asset_tag][$batch_counter]['name']);
@ -854,12 +832,10 @@ class AssetsController extends Controller
} else {
$status['error'][]['asset'][$asset_tag]['msg'] = 'Asset and user was matched but could not be saved.';
}
} else {
$item[$asset_tag][$batch_counter]['checkedout_to'] = null;
$status['error'][]['user'][Helper::array_smart_fetch($row, "name")]['msg'] = 'User does not exist so no checkin log was created.';
}
} else {
$item[$asset_tag][$batch_counter]['asset_id'] = null;
$status['error'][]['asset'][$asset_tag]['msg'] = 'Asset does not exist so no match was attempted.';
@ -875,7 +851,6 @@ class AssetsController extends Controller
// Only do this if a matching user was found
if ((array_key_exists('checkedout_to', $asset_batch[$x])) && ($asset_batch[$x]['checkedout_to']!='')) {
if (($total_in_batch > 1) && ($x < $total_in_batch) && (array_key_exists($next, $asset_batch))) {
$checkin_date = Carbon::parse($asset_batch[$next]['checkout_date'])->subDay(1)->format('Y-m-d H:i:s');
$asset_batch[$x]['real_checkin'] = $checkin_date;
@ -982,7 +957,6 @@ class AssetsController extends Controller
}
$log->delete();
return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success'));
}
// Prepare the error message
$error = trans('admin/hardware/message.does_not_exist', compact('id'));
@ -1049,25 +1023,19 @@ class AssetsController extends Controller
if ($request->has('bulk_actions')) {
if ($request->input('bulk_actions')=='labels') {
$count = 0;
return view('hardware/labels')
->with('assets', Asset::find($asset_ids))
->with('settings', Setting::getSettings())
->with('count', $count)
->with('settings',
Setting::getSettings()
);
->with('settings', Setting::getSettings());
} elseif ($request->input('bulk_actions')=='delete') {
$assets = Asset::with('assignedTo', 'assetloc')->find($asset_ids);
$assets->each(function($asset) {
$this->authorize('delete',$asset);
$assets->each(function ($asset) {
$this->authorize('delete', $asset);
});
return view('hardware/bulk-delete')->with('assets', $assets);
// Bulk edit
} elseif ($request->input('bulk_actions')=='edit') {
return view('hardware/bulk')
@ -1150,7 +1118,6 @@ class AssetsController extends Controller
DB::table('assets')
->where('id', $key)
->update($update_array);
} // endforeach
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.update.success'));
// no values given, nothing to update
@ -1172,7 +1139,6 @@ class AssetsController extends Controller
{
$this->authorize('delete', Asset::class);
if (Input::has('ids')) {
$assets = Asset::find(Input::get('ids'));
foreach ($assets as $asset) {
@ -1182,7 +1148,6 @@ class AssetsController extends Controller
DB::table('assets')
->where('id', $asset->id)
->update($update_array);
} // endforeach
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.delete.success'));
// no values given, nothing to update
@ -1282,10 +1247,8 @@ class AssetsController extends Controller
$asset->next_audit_date = $request->input('next_audit_date');
if ($asset->save()) {
$asset->logAudit(request('note'),request('location_id'));
$asset->logAudit(request('note'), request('location_id'));
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.audit.success'));
}
}
}

View file

@ -357,12 +357,12 @@ class LicensesController extends Controller
public function getCheckin($seatId = null, $backTo = null)
{
// Check if the asset exists
if (is_null($licenseseat = LicenseSeat::find($seatId))) {
if (is_null($licenseSeat = LicenseSeat::find($seatId))) {
// Redirect to the asset management page with error
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
}
$this->authorize('checkin', $licenseseat);
return view('licenses/checkin', compact('licenseseat'))->with('backto', $backTo);
$this->authorize('checkin', $licenseSeat);
return view('licenses/checkin', compact('licenseSeat'))->with('backto', $backTo);
}
@ -519,13 +519,16 @@ class LicensesController extends Controller
//Log the upload to the log
$license->logUpload($filename, e($request->input('notes')));
}
// This being called from a modal seems to confuse redirect()->back()
// It thinks we should go to the dashboard. As this is only used
// from the modal at present, hardcode the redirect. Longterm
// maybe we evaluate something else.
if ($upload_success) {
return redirect()->back()->with('success', trans('admin/licenses/message.upload.success'));
return redirect()->route('licenses.show', $license->id)->with('success', trans('admin/licenses/message.upload.success'));
}
return redirect()->back()->with('error', trans('admin/licenses/message.upload.error'));
return redirect()->route('licenses.show', $license->id)->with('error', trans('admin/licenses/message.upload.error'));
}
return redirect()->back()->with('error', trans('admin/licenses/message.upload.nofiles'));
return redirect()->route('licenses.show', $license->id)->with('error', trans('admin/licenses/message.upload.nofiles'));
}
// Prepare the error message
$error = trans('admin/licenses/message.does_not_exist', compact('id'));

View file

@ -87,9 +87,8 @@ class SuppliersController extends Controller
$supplier->image = $file_name;
}
// Was it created?
if ($supplier->save()) {
// Redirect to the new supplier page
// Redirect to the nw supplier page
return redirect()->route('suppliers.index')->with('success', trans('admin/suppliers/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($supplier->getErrors());

View file

@ -29,7 +29,6 @@ class ImportsTransformer
'header_row' => $import->header_row,
'first_row' => $import->first_row,
'field_map' => $import->field_map,
'process_url'=> route('api.imports.importFile', $import->id),
];
return $array;

View file

@ -38,8 +38,8 @@ class LocationsTransformer
'state' => e($location->state),
'country' => e($location->country),
'zip' => e($location->zip),
'assets_checkedout' => $location->assets()->count(),
'assets_default' => $location->assignedassets()->count(),
'assets_checkedout' => $location->location_assets_count,
'assets_default' => $location->assigned_assets_count,
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'),

View file

@ -15,18 +15,18 @@ class Supplier extends SnipeModel
protected $rules = array(
'name' => 'required|min:3|max:255|unique_undeleted',
'address' => 'min:3|max:50',
'address2' => 'min:2|max:50',
'city' => 'min:3|max:255',
'state' => 'min:0|max:32',
'country' => 'min:0|max:2',
'fax' => 'min:7|max:35',
'phone' => 'min:7|max:35',
'contact' => 'min:0|max:100',
'notes' => 'min:0|max:255',
'email' => 'email|min:5|max:150',
'zip' => 'min:0|max:10',
'url' => 'min:3|max:250',
'address' => 'max:50|nullable',
'address2' => 'max:50|nullable',
'city' => 'max:255|nullable',
'state' => 'max:32|nullable',
'country' => 'max:3|nullable',
'fax' => 'min:7|max:35|nullable',
'phone' => 'min:7|max:35|nullable',
'contact' => 'max:100|nullable',
'notes' => 'max:255|nullable',
'email' => 'email|max:150|nullable',
'zip' => 'max:10|nullable',
'url' => 'sometimes|nullable|string|max:250',
);
/**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -3,6 +3,10 @@
"/css/AdminLTE.css": "/css/AdminLTE.css",
"/css/app.css": "/css/app.css",
"/css/overrides.css": "/css/overrides.css",
"/vue.js.map": "/vue.js.map",
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map",
"/css/app.css.map": "/css/app.css.map",
"/css/overrides.css.map": "/css/overrides.css.map",
"/public/css/dist/all.css": "/public/css/dist/all.css",
"/public/js/dist/all.js": "/public/js/dist/all.js"
}

52911
build/vue.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -11,6 +11,8 @@
"doctrine/cache": "^1.6",
"doctrine/common": "^2.7",
"doctrine/dbal": "v2.5.13",
"doctrine/inflector": "1.1.*",
"doctrine/instantiator": "1.0.*",
"erusev/parsedown": "^1.6",
"fideloper/proxy": "^3.1",
"intervention/image": "^2.3",
@ -27,10 +29,11 @@
"schuppo/password-strength": "~1.5",
"spatie/laravel-backup": "^3.0.0",
"tecnickcom/tc-lib-barcode": "^1.15",
"tightenco/ziggy": "^0.4.1",
"unicodeveloper/laravel-password": "^1.0",
"watson/validating": "^3.0",
"doctrine/instantiator": "1.0.*",
"doctrine/inflector": "1.2.*"
"phpspec/prophecy": "1.6.2",
"phpdocumentor/reflection-docblock": "3.2.2"
},
"require-dev": {
"fzaninotto/faker": "~1.4",

1064
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -255,7 +255,7 @@ return [
Laravel\Tinker\TinkerServiceProvider::class,
Unicodeveloper\DumbPassword\DumbPasswordServiceProvider::class,
Schuppo\PasswordStrength\PasswordStrengthServiceProvider::class,
Tightenco\Ziggy\ZiggyServiceProvider::class, // Laravel routes in vue
/*
* Application Service Providers...

View file

@ -19,12 +19,14 @@ $factory->defineAs(Actionlog::class, 'asset-checkout', function (Faker\Generator
$company = factory(App\Models\Company::class)->create();
$user = factory(App\Models\User::class)->create(['company_id' => $company->id]);
$target = factory(App\Models\User::class)->create(['company_id' => $company->id]);
// $item = factory(App\Models\Asset::class)->create(['company_id' => $company->id]);
do {
$item = factory(App\Models\Asset::class)->create(['company_id' => $company->id]);
} while (!$item->isValid());
// dd($item);
return [
'user_id' => $user->id,
'action_type' => 'checkout',
'item_id' => factory(App\Models\Asset::class)->create(['company_id' => $company->id])->id,
'item_id' => $item->id,
'item_type' => App\Models\Asset::class,
'target_id' => $target->id,
'target_type' => get_class($target),

Binary file not shown.

BIN
public/js/dist/all.js vendored

Binary file not shown.

View file

@ -67,7 +67,7 @@ tr {
<script>
export default {
props: ['file', 'customFieldUrl'],
props: ['file', 'customFields'],
data() {
return {
activeFile: this.file,
@ -130,14 +130,13 @@ tr {
{id: 'jobtitle', text: 'Job Title' },
{id: 'phone_number', text: 'Phone Number' },
],
customFields: [],
customFields: this.customFields,
},
columnMappings: this.file.field_map || {},
activeColumn: null,
}
},
created() {
this.fetchCustomFields();
window.eventHub.$on('showDetails', this.toggleExtendedDisplay)
this.populateSelect2ActiveItems();
},
@ -155,21 +154,9 @@ tr {
}
},
methods: {
fetchCustomFields() {
this.$http.get(this.customFieldUrl)
.then( ({data}) => {
data = data.rows;
data.forEach((item) => {
this.columnOptions.customFields.push({
'id': item.db_column_name,
'text': item.name,
})
})
});
},
postSave() {
this.statusText = "Processing...";
this.$http.post(this.file.process_url, {
this.$http.post(route('api.imports.importFile', this.file.id), {
'import-update': this.options.update,
'import-type': this.options.importType,
'column-mappings': this.columnMappings

View file

@ -11,8 +11,6 @@ th {
<script>
require('blueimp-file-upload');
export default {
props: ['importUrl'],
/*
* The component's data.
*/
@ -32,13 +30,15 @@ th {
currentPercent: "0",
statusText: '',
visible: false
}
},
customFields: [],
};
},
mounted() {
window.eventHub.$on('importErrors', this.updateImportErrors);
this.fetchFiles();
this.fetchCustomFields();
let vm = this;
$('#fileupload').fileupload({
dataType: 'json',
@ -71,7 +71,7 @@ th {
methods: {
fetchFiles() {
this.$http.get(this.importUrl)
this.$http.get(route('api.imports.index'))
.then( ({data}) => this.files = data, // Success
//Fail
(response) => {
@ -80,8 +80,20 @@ th {
this.alert.message="Something went wrong fetching files...";
});
},
fetchCustomFields() {
this.$http.get(route('api.customfields.index'))
.then( ({data}) => {
data = data.rows;
data.forEach((item) => {
this.customFields.push({
'id': item.db_column_name,
'text': item.name,
})
})
});
},
deleteFile(file, key) {
this.$http.delete(this.importUrl+"/"+file.id)
this.$http.delete(route('api.imports.destroy', file.id))
.then((response) => this.files.splice(key, 1), // Success, remove file from array.
(response) => {// Fail
this.alert.type="danger";
@ -98,7 +110,7 @@ th {
},
updateImportErrors(errors) {
this.importErrors = errors;
}
},
},
computed: {

View file

@ -56,6 +56,7 @@
<script>
export default {
props: ['clientsUrl', 'tokensUrl'],
/*
* The component's data.
*/
@ -91,7 +92,7 @@
* Get all of the authorized tokens for the user.
*/
getTokens() {
this.$http.get('/oauth/tokens')
this.$http.get(this.tokensUrl)
.then(response => {
this.tokens = response.data;
});
@ -101,7 +102,7 @@
* Revoke the given token.
*/
revoke(token) {
this.$http.delete('/oauth/tokens/' + token.id)
this.$http.delete(this.tokensUrl +'/'+ token.id)
.then(response => {
this.getTokens();
});

View file

@ -219,6 +219,7 @@
/*
* The component's data.
*/
props: ['clientsUrl'],
data() {
return {
clients: [],
@ -271,7 +272,7 @@
* Get all of the OAuth clients for the user.
*/
getClients() {
this.$http.get('/oauth/clients')
this.$http.get(this.clientsUrl)
.then(response => {
this.clients = response.data;
});
@ -289,7 +290,7 @@
*/
store() {
this.persistClient(
'post', '/oauth/clients',
'post', this.clientsUrl,
this.createForm, '#modal-create-client'
);
},
@ -310,7 +311,7 @@
*/
update() {
this.persistClient(
'put', '/oauth/clients/' + this.editForm.id,
'put', this.clientsUrl + '/' + this.editForm.id,
this.editForm, '#modal-edit-client'
);
},
@ -319,8 +320,10 @@
* Persist the client to storage using the given form.
*/
persistClient(method, uri, form, modal) {
console.log('persisting');
form.errors = [];
console.log('method: ' + method);
this.$http[method](uri, form)
.then(response => {
this.getClients();
@ -344,7 +347,7 @@
* Destroy the given client.
*/
destroy(client) {
this.$http.delete('/oauth/clients/' + client.id)
this.$http.delete(this.clientsUrl +'/' + client.id)
.then(response => {
this.getClients();
});

View file

@ -160,6 +160,7 @@
<script>
export default {
props: ['tokenUrl', 'scopesUrl'],
/*
* The component's data.
*/
@ -209,7 +210,7 @@
* Get all of the personal access tokens for the user.
*/
getTokens() {
this.$http.get('/oauth/personal-access-tokens')
this.$http.get(this.tokenUrl)
.then(response => {
this.tokens = response.data;
});
@ -219,7 +220,7 @@
* Get all of the available scopes.
*/
getScopes() {
this.$http.get('/oauth/scopes')
this.$http.get(this.scopesUrl)
.then(response => {
this.scopes = response.data;
});
@ -240,7 +241,7 @@
this.form.errors = [];
this.$http.post('/oauth/personal-access-tokens', this.form)
this.$http.post(this.tokenUrl, this.form)
.then(response => {
this.form.name = '';
this.form.scopes = [];
@ -293,7 +294,7 @@
* Revoke the given token.
*/
revoke(token) {
this.$http.delete('/oauth/personal-access-tokens/' + token.id)
this.$http.delete(this.tokenUrl +'/'+ token.id)
.then(response => {
this.getTokens();
});

View file

@ -9,7 +9,10 @@
{{-- Page content --}}
@section('content')
@if (!config('app.lock_passwords'))
<passport-personal-access-tokens></passport-personal-access-tokens>
<passport-personal-access-tokens
token-url="{{ url('oauth/personal-access-tokens') }}"
scopes-url="{{ url('oauth/scopes') }}">
</passport-personal-access-tokens>
@else
<p class="help-block">{{ trans('general.feature_disabled') }}</p>
@endif

View file

@ -4,7 +4,7 @@
<p>{{ trans('mail.a_user_canceled') }} <a href="{{ url('/') }}"> {{ $snipeSettings->site_name }}</a>. </p>
<p>{{ trans('mail.user') }} <a href="{{ url('/') }}/admin/users/{{ $user_id }}/view">{{ $requested_by }}</a><br>
<p>{{ trans('mail.user') }} <a href="{{ route('users.show', $user_id) }}">{{ $requested_by }}</a><br>
{{ trans('mail.item') }} <a href="{{ $item_url }}">{{ $item_name }}</a> ({{ $item_type }}) <br>
{{ trans('mail.canceled') }} {{ $requested_date }}
</p>

View file

@ -4,7 +4,7 @@
<p>{{ trans('mail.a_user_requested') }} <a href="{{ url('/') }}"> {{ $snipeSettings->site_name }}</a>. </p>
<p>{{ trans('mail.user') }} <a href="{{ url('/') }}/admin/users/{{ $user_id }}/view">{{ $requested_by }}</a><br>
<p>{{ trans('mail.user') }} <a href="{{ route('users.show', $user_id) }}">{{ $requested_by }}</a><br>
{{ trans('mail.item') }} <a href="{{ $item_url }}">{{ $item_name }}</a> ({{ $item_type }}) <br>
{{ trans('mail.requested') }} {{ $requested_date }}
@if ($item_quantity > 1)

View file

@ -15,7 +15,7 @@
@for($i=0; $count > $i; $i++)
<tr>
<td>
<a href="{{ url('/') }}/admin/{{ $data[$i]['type'] }}/{{ $data[$i]['id'] }}/view">{{ $data[$i]['name'] }}</a>
<a href="{{ route($data[$i]['type'].'.show', $data[$i]['id']) }}">{{ $data[$i]['name'] }}</a>
</td>
<td>{{ $data[$i]['type'] }}</td>
<td>{{ $data[$i]['remaining'] }}</td>

View file

@ -16,7 +16,7 @@
{{-- Page content --}}
@section('content')
<div id="app">
<importer inline-template import-url="{{route('api.imports.index')}}" v-cloak>
<importer inline-template v-cloak>
<div class="row">
<alert v-show="alert.visible" :alert-type="alert.type" v-on:hide="alert.visible = false">@{{ alert.message }}</alert>
<errors :errors="importErrors"></errors>
@ -65,7 +65,7 @@
<import-file
:key="currentFile.id"
:file="currentFile"
customFieldUrl="{{route('api.customfields.index')}}"
:custom-fields="customFields"
@alert="updateAlert(alert)">
</import-file>
</template>

View file

@ -31,8 +31,6 @@
window.Laravel = { csrfToken: '{{ csrf_token() }}' };
</script>
<style nonce="{{ csrf_token() }}">
@if ($snipeSettings)
@if ($snipeSettings->header_color)
@ -68,8 +66,6 @@
}
</style>
<script nonce="{{ csrf_token() }}">
window.snipeit = {
settings: {
@ -77,7 +73,8 @@
}
};
</script>
<!-- Add laravel route sinto javascript Primarily useful for vue.-->
@routes
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>

View file

@ -6,28 +6,31 @@
@parent
@stop
@section('header_right')
<a href="{{ URL::previous() }}" class="btn btn-primary pull-right">{{ trans('general.back') }}</a>
<a href="{{ URL::previous() }}" class="btn btn-primary pull-right">
{{ trans('general.back') }}</a>
@stop
{{-- Page content --}}
@section('content')
<div class="row form-wrapper">
<div class="row">
<!-- left column -->
<div class="col-md-10 column">
@if ($backto=='user')
<form class="form-horizontal" method="post" action="{{ route('licenses.checkin', array('licenseeat_id'=> $licenseseat->id, 'backto'=>'user')) }}" autocomplete="off">
@else
<form class="form-horizontal" method="post" action="{{ route('licenses.checkin', $licenseseat->id) }}" autocomplete="off">
@endif
<div class="col-md-7">
<form class="form-horizontal" method="post" action="{{ route('licenses.checkin.save', $licenseSeat->id) }}" autocomplete="off">
{{csrf_field()}}
<!-- Asset name -->
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title"> {{ $licenseSeat->license->name }}</h3>
</div>
<div class="box-body">
<!-- license name -->
<div class="form-group">
<label class="col-sm-2 control-label">{{ trans('admin/hardware/form.name') }}</label>
<div class="col-md-6">
<p class="form-control-static">{{ $licenseseat->license->name }}</p>
<p class="form-control-static">{{ $licenseSeat->license->name }}</p>
</div>
</div>
@ -35,7 +38,7 @@
<div class="form-group">
<label class="col-sm-2 control-label">{{ trans('admin/hardware/form.serial') }}</label>
<div class="col-md-6">
<p class="form-control-static">{{ $licenseseat->license->serial }}</p>
<p class="form-control-static">{{ $licenseSeat->license->serial }}</p>
</div>
</div>
@ -43,20 +46,18 @@
<div class="form-group {{ $errors->has('note') ? 'error' : '' }}">
<label for="note" class="col-md-2 control-label">{{ trans('admin/hardware/form.notes') }}</label>
<div class="col-md-7">
<textarea class="col-md-6 form-control" id="note" name="note">{{ Input::old('note', $licenseseat->note) }}</textarea>
<textarea class="col-md-6 form-control" id="note" name="note">{{ Input::old('note', $licenseSeat->note) }}</textarea>
{!! $errors->first('note', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
</div>
</div>
<!-- Form actions -->
<div class="form-group">
<label class="col-md-2 control-label"></label>
<div class="col-md-7">
<div class="box-footer">
<a class="btn btn-link" href="{{ route('licenses.index') }}">{{ trans('button.cancel') }}</a>
<button type="submit" class="btn btn-success"><i class="fa fa-check icon-white"></i> {{ trans('general.checkin') }}</button>
</div>
<button type="submit" class="btn btn-success pull-right"><i class="fa fa-check icon-white"></i> {{ trans('general.checkin') }}</button>
</div>
</div> <!-- /.box-->
</form>
</div> <!-- .col-md-10-->
</div>
</div> <!-- /.col-md-7-->
</div>
@stop

View file

@ -14,8 +14,8 @@
@section('content')
@if (!config('app.lock_passwords'))
<div id="app">
<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-clients clients-url="{{ url('oauth/clients') }}"></passport-clients>
<passport-authorized-clients clients-url="{{ url('oauth/clients') }}" tokens-url="{{ url('oauth/tokens') }}"></passport-authorized-clients>
</div>
@else
<p class="help-block">{{ trans('general.feature_disabled') }}</p>

View file

@ -32,7 +32,7 @@
<div class="panel box box-default">
<div class="box-header with-border">
<h4 class="box-title">
<i class="fa fa-lock"></i> Security
<i class="fa fa-tags"></i> Labels
</h4>
</div>
<div class="box-body">

View file

@ -25,7 +25,7 @@ Route::group([ 'prefix' => 'licenses', 'middleware' => ['auth'] ], function () {
]);
Route::post('{licenseId}/checkin/{backto?}', [
'as' => 'licenses.checkin',
'as' => 'licenses.checkin.save',
'uses' => 'LicensesController@postCheckin'
]);

View file

@ -54,6 +54,7 @@ progress () {
done
}
#Used for Debian and Ubuntu
vhenvfile () {
find /etc/apache2/mods-enabled -maxdepth 1 -name 'rewrite.load' >/dev/null 2>&1
apachefile=/etc/apache2/sites-available/$name.conf
@ -74,16 +75,16 @@ vhenvfile () {
echo >> $hosts "127.0.0.1 $hostname $fqdn"
log "a2ensite $name.conf"
cat > "$webdir/$name/.env" <<-EOF
#Created By Snipe-it Installer
APP_TIMEZONE=$(cat /etc/timezone)
DB_HOST=localhost
DB_DATABASE=snipeit
DB_USERNAME=snipeit
DB_PASSWORD=$mysqluserpw
APP_URL=http://$fqdn
APP_KEY=$random32
EOF
cp $webdir/$name/.env.example $webdir/$name/.env
sed -i '1 i\#Created By Snipe-it Installer' $webdir/$name/.env
sed -i 's,^\(APP_TIMEZONE=\).*,\1'$(cat /etc/timezone)',' $webdir/$name/.env
sed -i 's,^\(DB_HOST=\).*,\1'localhost',' $webdir/$name/.env
sed -i 's,^\(DB_DATABASE=\).*,\1'snipeit',' $webdir/$name/.env
sed -i 's,^\(DB_USERNAME=\).*,\1'snipeit',' $webdir/$name/.env
sed -i 's,^\(DB_PASSWORD=\).*,\1'$mysqluserpw',' $webdir/$name/.env
sed -i 's,^\(APP_URL=\).*,\1'http://$fqdn',' $webdir/$name/.env
sed -i 's,^\(APP_KEY=\).*,\1'$$random32',' $webdir/$name/.env
}
perms () {
@ -173,7 +174,7 @@ echo ""
#Do you want to set your own passwords, or have me generate random ones?
until [[ $ans == "yes" ]] || [[ $ans == "no" ]]; do
echo -n " Q. Do you want me to automatically create the snipe database user password? (y/n) "
echo -n " Q. Do you want to automatically create the database user password? (y/n) "
read setpw
case $setpw in
@ -306,7 +307,7 @@ case $distro in
webdir=/var/www/html
#Allow us to get the mysql engine
echo ""
echo "## Adding IUS, epel-release and mariaDB repos.";
echo "## Adding IUS, epel-release and mariaDB repositories.";
mariadbRepo=/etc/yum.repos.d/MariaDB.repo
touch "$mariadbRepo"
{
@ -322,25 +323,23 @@ case $distro in
log "wget -P "$tmp/" https://centos6.iuscommunity.org/ius-release.rpm"
log "rpm -Uvh "$tmp/ius-release*.rpm""
#Install PHP and other needed stuff.
echo "## Installing PHP and other needed stuff";
PACKAGES="httpd MariaDB-server git unzip php56u php56u-mysqlnd php56u-bcmath php56u-cli php56u-common php56u-embedded php56u-gd php56u-mbstring php56u-mcrypt php56u-ldap"
#Install PHP and other needed stuff
echo "## Installing PHP and other requirements.";
PACKAGES="httpd mariadb-server git unzip php71u php71u-mysqlnd php71u-bcmath php71u-cli php71u-common php71u-embedded php71u-gd php71u-mbstring php71u-mcrypt php71u-ldap php71u-json php71u-simplexml"
for p in $PACKAGES;do
if isinstalled "$p"; then
echo " ## $p already installed"
else
echo -n " ## installing $p ... "
echo -n " ## Installing $p ... "
log "yum -y install $p"
echo "";
fi
done;
echo -e "\n## Downloading Snipe-IT from github and putting it in the web directory.";
echo -e "\n## Cloning Snipe-IT from github to the web directory.";
log "wget -P $tmp/ https://github.com/snipe/snipe-it/archive/$file"
unzip -qo $tmp/$file -d $tmp/
cp -R $tmp/$fileName $webdir/$name
log "git clone https://github.com/snipe/snipe-it $webdir/$name"
# Make mariaDB start on boot and restart the daemon
echo "## Starting the mariaDB server.";
@ -387,17 +386,16 @@ case $distro in
tzone=$(grep ZONE /etc/sysconfig/clock | tr -d '"' | sed 's/ZONE=//g');
echo "## Configuring .env file."
cat > $webdir/$name/.env <<-EOF
#Created By Snipe-it Installer
APP_TIMEZONE=$tzone
DB_HOST=localhost
DB_DATABASE=snipeit
DB_USERNAME=snipeit
DB_PASSWORD=$mysqluserpw
APP_URL=http://$fqdn
APP_KEY=$random32
DB_DUMP_PATH='/usr/bin'
EOF
cp $webdir/$name/.env.example $webdir/$name/.env
sed -i '1 i\#Created By Snipe-it Installer' $webdir/$name/.env
sed -i 's,^\(APP_TIMEZONE=\).*,\1'$tzone',' $webdir/$name/.env
sed -i 's,^\(DB_HOST=\).*,\1'localhost',' $webdir/$name/.env
sed -i 's,^\(DB_DATABASE=\).*,\1'snipeit',' $webdir/$name/.env
sed -i 's,^\(DB_USERNAME=\).*,\1'snipeit',' $webdir/$name/.env
sed -i 's,^\(DB_PASSWORD=\).*,\1'$mysqluserpw',' $webdir/$name/.env
sed -i 's,^\(APP_URL=\).*,\1'http://$fqdn',' $webdir/$name/.env
sed -i 's,^\(APP_KEY=\).*,\1'$$random32',' $webdir/$name/.env
echo "## Configure composer"
cd $webdir/$name
@ -417,8 +415,12 @@ case $distro in
fi
service httpd restart
php artisan key:generate
php artisan passport:install
echo "## Generating the application key."
php artisan key:generate --force
echo "## Artisan Migrate."
php artisan migrate --force
elif [[ "$version" =~ ^7 ]]; then
##################################### Install for Centos/Redhat 7 ##############################################
@ -426,26 +428,26 @@ case $distro in
webdir=/var/www/html
#Allow us to get the mysql engine
echo -e "\n## Add IUS, epel-release and mariaDB repos.";
echo -e "\n## Adding IUS, epel-release and mariaDB repositories.";
log "yum -y install wget epel-release"
log "wget -P $tmp/ https://centos7.iuscommunity.org/ius-release.rpm"
log "rpm -Uvh $tmp/ius-release*.rpm"
#Install PHP and other needed stuff.
echo "## Installing PHP and other needed stuff";
PACKAGES="httpd mariadb-server git unzip php56u php56u-mysqlnd php56u-bcmath php56u-cli php56u-common php56u-embedded php56u-gd php56u-mbstring php56u-mcrypt php56u-ldap"
#Install PHP and other requirements
echo "## Installing PHP and other requirements.";
PACKAGES="httpd mariadb-server git unzip php71u php71u-mysqlnd php71u-bcmath php71u-cli php71u-common php71u-embedded php71u-gd php71u-mbstring php71u-mcrypt php71u-ldap php71u-json php71u-simplexml"
for p in $PACKAGES;do
if isinstalled "$p"; then
echo " ## $p already installed"
else
echo -n " ## installing $p ... "
echo -n " ## Installing $p ... "
log "yum -y install $p"
echo "";
fi
done;
echo -e "\n## Downloading Snipe-IT from github and put it in the web directory.";
echo -e "\n## Cloning Snipe-IT from github to the web directory.";
log "git clone https://github.com/snipe/snipe-it $webdir/$name"
@ -488,7 +490,7 @@ case $distro in
echo "</VirtualHost>"
} >> "$apachefile"
##TODO make sure this isnt already in there
##TODO make sure this isnt already in there
echo "## Setting up hosts file.";
echo >> $hosts "127.0.0.1 $hostname $fqdn"
@ -500,20 +502,16 @@ case $distro in
tzone=$(timedatectl | gawk -F'[: ]' ' $9 ~ /zone/ {print $11}');
echo "## Configuring .env file."
cat > $webdir/$name/.env <<-EOF
#Created By Snipe-it Installer
APP_TIMEZONE=$tzone
DB_HOST=localhost
DB_DATABASE=snipeit
DB_USERNAME=snipeit
DB_PASSWORD=$mysqluserpw
APP_URL=http://$fqdn
APP_KEY=$random32
DB_DUMP_PATH='/usr/bin'
EOF
# Change permissions on directories
cp $webdir/$name/.env.example $webdir/$name/.env
sed -i '1 i\#Created By Snipe-it Installer' $webdir/$name/.env
sed -i 's,^\(APP_TIMEZONE=\).*,\1'$tzone',' $webdir/$name/.env
sed -i 's,^\(DB_HOST=\).*,\1'localhost',' $webdir/$name/.env
sed -i 's,^\(DB_DATABASE=\).*,\1'snipeit',' $webdir/$name/.env
sed -i 's,^\(DB_USERNAME=\).*,\1'snipeit',' $webdir/$name/.env
sed -i 's,^\(DB_PASSWORD=\).*,\1'$mysqluserpw',' $webdir/$name/.env
sed -i 's,^\(APP_URL=\).*,\1'http://$fqdn',' $webdir/$name/.env
sed -i 's,^\(APP_KEY=\).*,\1'$$random32',' $webdir/$name/.env
#Install / configure composer
cd $webdir/$name
@ -521,14 +519,13 @@ case $distro in
curl -sS https://getcomposer.org/installer | php
php composer.phar install --no-dev --prefer-source
#Set permissions
perms
chown -R apache:apache $webdir/$name
# Make SeLinux happy
chcon -R -h -t httpd_sys_script_rw_t $webdir/$name/
#Check if SELinux is enforcing
if [ "$(getenforce)" == "Enforcing" ]; then
#Add SELinux and firewall exception/rules.
#Add SELinux and firewall exception/rules
#Required for ldap integration
setsebool -P httpd_can_connect_ldap on
#Sets SELinux context type so that scripts running in the web server process are allowed read/write access
@ -536,8 +533,15 @@ case $distro in
fi
systemctl restart httpd.service
php artisan key:generate
php artisan passport:install
echo "## Generating the application key."
php artisan key:generate --force
echo "## Artisan Migrate."
php artisan migrate --force
echo "## Creating scheduler cron."
(crontab -l ; echo "* * * * * /usr/bin/php $webdir/$name/artisan schedule:run >> /dev/null 2>&1") | crontab -
else
echo "Unable to Handle Centos Version #. Version Found: " $version
@ -546,7 +550,7 @@ case $distro in
esac
echo ""
echo " ***If you want mail capabilities, edit $webdir/$name/.env and edit based on .env.example***"
echo " ***If you want mail capabilities, edit $webdir/$name/.env***"
echo ""
echo " ***Open http://$fqdn to login to Snipe-IT.***"
echo ""

View file

@ -1,8 +1,8 @@
-- MySQL dump 10.13 Distrib 5.7.18, for Linux (x86_64)
-- MySQL dump 10.13 Distrib 5.7.19, for Linux (x86_64)
--
-- Host: localhost Database: snipeittests
-- ------------------------------------------------------
-- Server version 5.7.18-0ubuntu0.16.10.1
-- Server version 5.7.19-0ubuntu0.17.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@ -1347,7 +1347,7 @@ CREATE TABLE `users` (
PRIMARY KEY (`id`),
KEY `users_activation_code_index` (`activation_code`),
KEY `users_reset_password_code_index` (`reset_password_code`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@ -1392,4 +1392,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2017-05-22 20:08:33
-- Dump completed on 2017-10-01 15:36:56

View file

@ -1,10 +1,16 @@
<?php
namespace Helper;
use Illuminate\Support\Facades\Artisan;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class Api extends \Codeception\Module
{
public function setupDatabase()
{
Artisan::call('migrate');
Artisan::call('db:seed');
}
}

View file

@ -11,3 +11,4 @@ modules:
environment_file: .env.testing
disable_middleware: true
cleanup: true

View file

@ -9,15 +9,16 @@ class ApiAssetsCest
public function _before(ApiTester $I)
{
$I->setupDatabase();
$this->faker = \Faker\Factory::create();
$this->user = \App\Models\User::find(1);
$I->amBearerAuthenticated($I->getToken($this->user));
}
/** @test */
public function indexAssets(ApiTester $I)
{
$I->wantTo('Get a list of assets');
// setup