Merge branch 'api' into 'main'

basic Api

See merge request ase22ws/abschlussprojekt-device-manager-timon-lorenz!5
This commit is contained in:
lot17014 2023-04-03 17:27:02 +02:00
commit 0e750a88d6
8 changed files with 665 additions and 13 deletions

View File

@ -0,0 +1,263 @@
Can you generate me a swagger document for the following api?
Route::post('/login', function (Request $request) {
$fields = $request->validate(
[
'user' => 'required',
'password' => 'required'
]
);
$user = User::where('rz_username', $fields['user'])->first();
if (!$user || !Hash::check($fields['password'], $user->hashed_password)) {
return response([
'message' => 'Bad login'
], 401);
}
$token = $user->createToken('token');
return ['token' => $token->plainTextToken];
});
Route::middleware('auth:sanctum')->get('/export', function () {
return response()->json([
'Devices' => Device::all(),
'PurchasingInformations' => PurchasingInformation::all(),
'OwnerTransactions' => OwnerTransaction::all(),
'LocationTransactions' => LocationTransaction::all()
]);
});
Route::middleware('auth:sanctum')->post('/import', function (Request $request) {
$data = $request->json()->all();
$devices = $data['devices'];
$purchasingInformations = $data['purchasing_information'];
$ownerTransactions = $data['owner_transactions'];
$locationTransactions = $data['location_transactions'];
//$response = {};
foreach ($devices as $device) {
$deviceInsert = DB::table('devices')->insertOrIgnore([
'device_id' => $device['device_id'],
'title' => $device['title'],
'device_type' => $device['device_type'],
'description' => $device['description'] ?? '',
'accessories' => $device['accessories'] ?? '',
'rz_username_buyer' => $device['rz_username_buyer'],
'serial_number' => $device['serial_number'],
'image_url' => $device['image_url']
]);
// insertOrIgnore returns 0 if statement was ignored
if ($deviceInsert != 0) {
// save insert for later
}
}
foreach ($purchasingInformations as $purchasing) {
$purchasingInsert = DB::table('purchasing_information')->insertOrIgnore([
'purchasing_information_id' => $purchasing['purchasing_information_id'],
'price' => $purchasing['price'],
'timestamp_warranty_end' => $purchasing['timestamp_warranty_end'],
'timestamp_purchase' => $purchasing['timestamp_purchase'],
'cost_centre' => $purchasing['cost_centre'],
'seller' => $purchasing['seller'] ?? '',
'device_id' => $purchasing['device_id']
]);
// insertOrIgnore returns 0 if statement was ignored
if ($purchasingInsert != 0) {
// save insert for later
}
}
foreach ($ownerTransactions as $owner) {
$ownerInsert = DB::table('owner_transactions')->insertOrIgnore([
'owner_transaction_id' => $owner['owner_transaction_id'],
'rz_username' => $owner['rz_username'],
'timestamp_owner_since' => $owner['timestamp_owner_since'],
'device_id' => $owner['device_id']
]);
// insertOrIgnore returns 0 if statement was ignored
if ($ownerInsert != 0) {
// save insert for later
}
}
foreach ($locationTransactions as $location) {
$locationInsert = DB::table('location_transactions')->insertOrIgnore([
'location_transaction_id' => $location['location_transaction_id'],
'room_code' => $location['room_code'],
'timestamp_located_since' => $location['timestamp_located_since'],
'device_id' => $location['device_id']
]);
// insertOrIgnore returns 0 if statement was ignored
if ($locationInsert != 0) {
// save insert for later
}
}
return $request->json()->all();
});
Sure! Here's a Swagger document for the provided API:
yaml
swagger: '2.0'
info:
title: My API
version: '1.0'
basePath: /
schemes:
- http
consumes:
- application/json
produces:
- application/json
paths:
/login:
post:
summary: Authenticate user
description: Authenticate user with username and password
parameters:
- in: body
name: body
description: User credentials
required: true
schema:
type: object
properties:
user:
type: string
password:
type: string
responses:
'200':
description: Authentication successful
schema:
type: object
properties:
token:
type: string
'401':
description: Authentication failed
schema:
type: object
properties:
message:
type: string
/export:
get:
summary: Export data
description: Get all devices, purchasing information, owner transactions, and location transactions
responses:
'200':
description: Data retrieved successfully
schema:
type: object
properties:
Devices:
type: array
items:
$ref: '#/definitions/Device'
PurchasingInformations:
type: array
items:
$ref: '#/definitions/PurchasingInformation'
OwnerTransactions:
type: array
items:
$ref: '#/definitions/OwnerTransaction'
LocationTransactions:
type: array
items:
$ref: '#/definitions/LocationTransaction'
'401':
description: Authentication failed
schema:
type: object
properties:
message:
type: string
/import:
post:
summary: Import data
description: Import device, purchasing information, owner transaction, and location transaction data
parameters:
- in: body
name: body
description: Data to import
required: true
schema:
type: object
properties:
devices:
type: array
items:
$ref: '#/definitions/Device'
purchasing_information:
type: array
items:
$ref: '#/definitions/PurchasingInformation'
owner_transactions:
type: array
items:
$ref: '#/definitions/OwnerTransaction'
location_transactions:
type: array
items:
$ref: '#/definitions/LocationTransaction'
responses:
'200':
description: Data imported successfully
schema:
type: object
properties:
devices:
type: array
items:
type: string
purchasing_information:
type: array
items:
type: string
owner_transactions:
type: array
items:
type: string
location_transactions:
type: array
items:
type: string
'401':
description: Authentication failed
schema:
type: object
properties:
message:
type: string
definitions:
Device:
type: object
properties:
device_id:
type: integer
title:
type: string
device_type:
type: string
description:
type: string
accessories:
type: string
rz_username_buyer:
type: string
serial_number:
type: string
image_url:
type: string
PurchasingInformation:
type: object
properties:
purchasing_information_id:
type: integer
price

View File

@ -0,0 +1,42 @@
Route::post('/import', function (Request $request) {
$data = $request->json()->all();
$devices = $data['devices'];
foreach ($devices as $device) {
Device::create([
'device_id' => $device['device_id'],
'title' => $device['title'],
'device_type' => $device['device_type'],
'description' => $device['description'],
'accessories' => $device['accessories'],
'rz_username_buyer' => $device['rz_username_buyer'],
'serial_number' => $device['serial_number'],
'image_url' => $device['image_url'],
]);
}
but 'description' is not always given. How do i solv it in php?
You can use the null coalescing operator (??) in PHP to provide a default value when the 'description' field is not present in the input data.
Here's an example of how you can modify the code to use the null coalescing operator:
php
Route::post('/import', function (Request $request) {
$data = $request->json()->all();
$devices = $data['devices'];
foreach ($devices as $device) {
Device::create([
'device_id' => $device['device_id'],
'title' => $device['title'],
'device_type' => $device['device_type'],
'description' => $device['description'] ?? '', // provide an empty string as the default value
'accessories' => $device['accessories'],
'rz_username_buyer' => $device['rz_username_buyer'],
'serial_number' => $device['serial_number'],
'image_url' => $device['image_url'],
]);
}
});
In the example above, the null coalescing operator is used to check whether the 'description' field exists in the input data. If it does not exist, an empty string is provided as the default value. This way, even if the 'description' field is not present in the input data, the code will still run without errors.

View File

@ -0,0 +1,55 @@
I have this methode:
Route::get('/export', function () {
return response()->json([
'Devices' => Device::all(),
'purchasingInformations' => PurchasingInformation::all(),
'OwnerTransactions' => OwnerTransaction::all(),
'LocationTransactions' => LocationTransaction::all()
]);
});
but i want to use the id of for example the devices as key for my json
To use the id of the Device model as a key in your JSON response, you can modify your code to map each device to an array with the device id as the key. Here's an example:
php
Route::get('/export', function () {
$devices = Device::all()->mapWithKeys(function ($device) {
return [$device->id => $device];
});
return response()->json([
'Devices' => $devices,
'purchasingInformations' => PurchasingInformation::all(),
'OwnerTransactions' => OwnerTransaction::all(),
'LocationTransactions' => LocationTransaction::all()
]);
});
In this modified code, we first retrieve all Device models using the all() method. We then call the mapWithKeys method on the resulting collection to transform it into an associative array where the device id is the key and the device model is the value.
We then pass this modified $devices variable to the JSON response, so that the devices will be outputted with their ids as keys. The other collections are passed as is without modification.
Note that if you have multiple models with the same id, the later models will overwrite the earlier ones in the JSON response.
-------------
can i also do it without an key, just the objects?
Yes, you can also return an array of objects without using keys. Here's an example:
scss
Route::get('/export', function () {
return response()->json([
'Devices' => Device::all()->toArray(),
'purchasingInformations' => PurchasingInformation::all()->toArray(),
'OwnerTransactions' => OwnerTransaction::all()->toArray(),
'LocationTransactions' => LocationTransaction::all()->toArray()
]);
});
In this code, we're using the toArray() method to convert each collection of models to an array of objects. These arrays are then included in the JSON response with their corresponding names as keys.
This will return an array of objects without keys. However, keep in mind that if you have multiple models with the same primary key value, their data will be merged into a single object in the JSON response, which may not be what you intended.

View File

@ -116,7 +116,8 @@ latest: 15.04.2023
Laravel is a full feature framework
### security
coss-side-scripting disabled
- coss-side-scripting disabled
- SQL injection attacks
## ChatGPT
see ChatGPT folder

View File

@ -16,10 +16,11 @@ class DeviceFactory extends Factory
*/
public function definition(): array
{
$device_type = $this->faker->randomElement(['projektor','computer','laptop','mikrofon','whiteboard','unbekannt']);
return [
'device_id' => $this->faker->uuid(),
'title' => $this->faker->word(),
'device_type' => $this->faker->domainWord(),
'device_type' => $device_type,
'description' => $this->faker->sentence(),
'accessories' => $this->faker->word(),
'rz_username_buyer' => $this->faker->name(),

View File

@ -13,7 +13,9 @@ public function up(): void
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->id();
$table->morphs('tokenable');
$table->string('tokenable_type');
$table->string('tokenable_id');
$table->index(["tokenable_type", "tokenable_id"]);
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();

View File

@ -1,6 +1,14 @@
<?php
use App\Models\Device;
use App\Models\LocationTransaction;
use App\Models\OwnerTransaction;
use App\Models\PurchasingInformation;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Route;
/*
@ -14,17 +22,98 @@
|
*/
Route::get('deviceList', function() {
return response()->json([
'devices' => [
[
'title' => 'Device One'
],
[
'title' => 'Device Two'
]
Route::post('/login', function (Request $request) {
$fields = $request->validate(
[
'user' => 'required',
'password' => 'required'
]
]);
);
$user = User::where('rz_username', $fields['user'])->first();
if (!$user || !Hash::check($fields['password'], $user->hashed_password)) {
return response([
'message' => 'Bad login'
], 401);
}
$token = $user->createToken('token');
return ['token' => $token->plainTextToken];
});
Route::middleware('auth:sanctum')->get('/export', function () {
return response()->json([
'Devices' => Device::all(),
'PurchasingInformations' => PurchasingInformation::all(),
'OwnerTransactions' => OwnerTransaction::all(),
'LocationTransactions' => LocationTransaction::all()
]);
});
Route::middleware('auth:sanctum')->post('/import', function (Request $request) {
$data = $request->json()->all();
$devices = $data['devices'];
$purchasingInformations = $data['purchasing_information'];
$ownerTransactions = $data['owner_transactions'];
$locationTransactions = $data['location_transactions'];
//$response = {};
foreach ($devices as $device) {
$deviceInsert = DB::table('devices')->insertOrIgnore([
'device_id' => $device['device_id'],
'title' => $device['title'],
'device_type' => $device['device_type'],
'description' => $device['description'] ?? '',
'accessories' => $device['accessories'] ?? '',
'rz_username_buyer' => $device['rz_username_buyer'],
'serial_number' => $device['serial_number'],
'image_url' => $device['image_url']
]);
// insertOrIgnore returns 0 if statement was ignored
if ($deviceInsert != 0) {
// save insert for later
}
}
foreach ($purchasingInformations as $purchasing) {
$purchasingInsert = DB::table('purchasing_information')->insertOrIgnore([
'purchasing_information_id' => $purchasing['purchasing_information_id'],
'price' => $purchasing['price'],
'timestamp_warranty_end' => $purchasing['timestamp_warranty_end'],
'timestamp_purchase' => $purchasing['timestamp_purchase'],
'cost_centre' => $purchasing['cost_centre'],
'seller' => $purchasing['seller'] ?? '',
'device_id' => $purchasing['device_id']
]);
// insertOrIgnore returns 0 if statement was ignored
if ($purchasingInsert != 0) {
// save insert for later
}
}
foreach ($ownerTransactions as $owner) {
$ownerInsert = DB::table('owner_transactions')->insertOrIgnore([
'owner_transaction_id' => $owner['owner_transaction_id'],
'rz_username' => $owner['rz_username'],
'timestamp_owner_since' => $owner['timestamp_owner_since'],
'device_id' => $owner['device_id']
]);
// insertOrIgnore returns 0 if statement was ignored
if ($ownerInsert != 0) {
// save insert for later
}
}
foreach ($locationTransactions as $location) {
$locationInsert = DB::table('location_transactions')->insertOrIgnore([
'location_transaction_id' => $location['location_transaction_id'],
'room_code' => $location['room_code'],
'timestamp_located_since' => $location['timestamp_located_since'],
'device_id' => $location['device_id']
]);
// insertOrIgnore returns 0 if statement was ignored
if ($locationInsert != 0) {
// save insert for later
}
}
// ToDo: return only inserted
return $request->json()->all();
});
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {

199
device-app/swagger.yml Normal file
View File

@ -0,0 +1,199 @@
swagger: '2.0'
info:
title: Device Manager API
version: '1.0'
basePath: /api
schemes:
- http
consumes:
- application/json
produces:
- application/json
paths:
/login:
post:
summary: Authenticate user
description: Authenticate user with username and password
parameters:
- in: body
name: body
description: User credentials
required: true
schema:
type: object
properties:
user:
type: string
password:
type: string
responses:
'200':
description: Authentication successful
schema:
type: object
properties:
token:
type: string
'401':
description: Authentication failed
schema:
type: object
properties:
message:
type: string
/export:
get:
summary: Export data
description: Get all devices, purchasing information, owner transactions, and location transactions
responses:
'200':
description: Data retrieved successfully
schema:
type: object
properties:
Devices:
type: array
items:
$ref: '#/definitions/Device'
PurchasingInformations:
type: array
items:
$ref: '#/definitions/PurchasingInformation'
OwnerTransactions:
type: array
items:
$ref: '#/definitions/OwnerTransactions'
LocationTransactions:
type: array
items:
$ref: '#/definitions/LocationTransactions'
'401':
description: Authentication failed
schema:
type: object
properties:
message:
type: string
/import:
post:
summary: Import data
description: Import device, purchasing information, owner transaction, and location transaction data
parameters:
- in: body
name: body
description: Data to import
required: true
schema:
type: object
properties:
devices:
type: array
items:
$ref: '#/definitions/Device'
purchasing_information:
type: array
items:
$ref: '#/definitions/PurchasingInformation'
owner_transactions:
type: array
items:
$ref: '#/definitions/OwnerTransactions'
location_transactions:
type: array
items:
$ref: '#/definitions/LocationTransactions'
responses:
'200':
description: Data imported successfully
schema:
type: object
properties:
devices:
type: array
items:
type: string
purchasing_information:
type: array
items:
type: string
owner_transactions:
type: array
items:
type: string
location_transactions:
type: array
items:
type: string
'401':
description: Authentication failed
schema:
type: object
properties:
message:
type: string
definitions:
Device:
type: object
properties:
device_id:
type: string
title:
type: string
device_type:
type: string
description:
type: string
accessories:
type: string
rz_username_buyer:
type: string
serial_number:
type: string
image_url:
type: string
PurchasingInformation:
type: object
properties:
purchasing_information_id:
type: string
price:
type: string
timestamp_warranty_end:
type: string
timestamp_purchase:
type: string
cost_centre:
type: integer
seller:
type: string
device_id:
type: string
OwnerTransactions:
type: object
properties:
owner_transaction_id:
type: string
rz_username:
type: string
timestamp_owner_since:
type: string
device_id:
type: string
LocationTransactions:
type: object
properties:
location_transaction_id:
type: string
room_code:
type: string
timestamp_located_since:
type: string
device_id:
type: string