Simple API Call gets redirected - nextcloud

I'm creating a Nextcloud-App (using Nextcloud 20). I want a simple call to my external service. Due to CSP restrictions (set by default by netxcloud), I simply can't.
Everytime I request my URL, using window.OC.generateUrl('/apps/[MYAPP]/video/trim'); I get a redirect response (code 302), instead of a success (code 200). What did I miss?
I registered my route:
// [MYAPP]/appinfo/routes.php
return [
'routes' => [
['name' => 'video#trim', 'url' => '/trim', 'verb' => 'POST']
]
];
I've build my controller:
// [MYAPP]/lib/controller/VideoController.php
namespace OCA\[MYAPP]\Controller;
use OCP\IRequest;
use GuzzleHttp\Client;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
class VideoController extends Controller
{
/**
* #NoAdminRequired
*/
public function trim(string $title, string $content)
{
$client = new Client([
'base_uri' => 'http://localhost:3000/push',
'timeout' => 2.0,
]);
$response = $client->request('POST', ['json' => $content]);
return new DataResponse(['foo' => 'bar']);
}
}
I'm POSTing my request to it. In console I see a redirect to Location http://localhost:9000/apps/dashboard/.
// js
const opts = {}; // my payload
const url = window.OC.generateUrl('/apps/[MYAPP]/video/trim');
fetch(url, {method: 'post', body: JSON.stringify(opts)})
.catch((err) => console.error(err))
.then((response) => response.json())
.then((data) => console.log(data));

I finally found the problem in routes.php!
Since I'm generating the URL for /apps/[MYAPP]/video/trim, the url in routes.php should look like /video/trim instead of /trim.
// [MYAPP]/appinfo/routes.php
return [
'routes' => [
['name' => 'video#trim', 'url' => '/video/trim', 'verb' => 'POST']
]
];

Related

SERVICE UNAVAILABLE error at REST API calling

My API route in routes/api.php file is like below.
Route::post('/register', [RegisterController::class, 'register']);
My register function of RegisterController is like below
public function register(RegistrationValidate $request)
{
$user = User::create([
'username' => request('username'),
'email' => request('email'),
'full_name' => request('full_name'),
'store_name' => request('store_name'),
'store_logo' => $fileName,
'password' => Hash::make(request('password')),
]);
$token = $user->createToken($this->clientToken())->accessToken;
return response()->json([
'user' => $user,
'token' => $token,
], 201);
}
I am getting SERVICE UNAVAILABLE error like below
I used php artisan up command and clear the cache. But the result is as like before.

Laravel HTTP Client Retrieve REST API Access Token

Trying to retrieve an access token from MS Azure
something like this:
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Client\Response;
class HttpController extends Controller
{
public function index()
{
$url = "https://login.microsoftonline.com/[tenantId]/oauth2/token";
$response = HTTP::post($url,
[
'grant_type' => 'client_credentials',
'client_Id' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
'client_secret' => '***************************',
'resource' => 'https://management.azure.com',
]);
dd($response);
}
}
get the following error:
"error": "invalid_request",
"error_description": "AADSTS900144: The request body must contain the following parameter: 'grant_type'
$response = HTTP::asForm()->post($url,
[
'grant_type' => 'client_credentials',
'client_Id' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
'client_secret' => '***************************',
'resource' => 'https://management.azure.com',
]
);

Method Illuminate\Auth\RequestGuard::attempt does not exist

I am new to both laravel and lumen.
I was creating a login api with oauth2.0 in lumen 5.6, i have installed passport and generated token.
Below is my login controller function and it is working fine. It returns token.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Route;
//use Illuminate\Support\Facades\DB;
use App\User;
use Auth;
public function login(Request $request)
{
global $app;
$proxy = Request::create(
'/oauth/token',
'post',
[
'grant_type' => env('API_GRAND_TYPE'),
'client_id' => env('API_CLIENT_ID'),
'client_secret' => env('API_CLIENT_SECRET'),
'username' => $request->username,
'password' => $request->password,
]
);
return $app->dispatch($proxy);
}
Since i have to check user status apart from username and password, i need to check the user credential first. so i do like this.
public function login(Request $request)
{
$credentials = $request->only('username', 'password');
if (Auth::attempt($credentials)) {
return ['result' => 'ok'];
}
return ['result' => 'not ok'];
}
Here i am getting this error.
Method Illuminate\Auth\RequestGuard::attempt does not exist.
So i tried Auth::check instead of Auth::attempt.
Now there is no error but it always return false even though the credentials are valid.
I searched a lot for a solution but i didn't get.
The function guard is only available for routes with web middleware
public function login() {
if(Auth::guard('web')->attempt(['email' => $email, 'password' => $password], false, false)) {requests
// good
} else {
// invalid credentials, act accordingly
}
}
Changing default guard to "web" fixed my problem.
config/auth.php:
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
using jwt it's worked for me
1-Auth::attempt($credentials)
just replace line 1 to line 2
2-$token = Auth::guard('api')->attempt($credentials)

How to use API Routes in Laravel 5.3

In Laravel 5.3 API routes were moved into the api.php file. But how can I call a route in api.php file? I tried to create a route like this:
Route::get('/test',function(){
return "ok";
});
I tried the following URLs but both returned the NotFoundHttpException exception:
http://localhost:8080/test/public/test
http://localhost:8080/test/public/api/test
How can I call this API route?
You call it by
http://localhost:8080/api/test
^^^
If you look in app/Providers/RouteServiceProvider.php you'd see that by default it sets the api prefix for API routes, which you can change of course if you want to.
protected function mapApiRoutes()
{
Route::group([
'middleware' => 'api',
'namespace' => $this->namespace,
'prefix' => 'api',
], function ($router) {
require base_path('routes/api.php');
});
}
routes/api.php
Route::get('/test', function () {
return response('Test API', 200)
->header('Content-Type', 'application/json');
});
Mapping is defined in service provider App\Providers\RouteServiceProvider
protected function mapApiRoutes(){
Route::group([
'middleware' => ['api', 'auth:api'],
'namespace' => $this->namespace,
'prefix' => 'api',
], function ($router) {
require base_path('routes/api.php');
});
}

Unable to get to route behind auth middleware for two routes

My two routes 'admin.media.begin-destroy' and 'admin.media.destroy' fails when middleware => 'auth'.
When trying to access the route 'admin.media.begin-destroy' I will get presented with the login page from the authentication controller, and I cannot get away from that without trying to access another page.
on my development machine it works fine both with and without auth middleware
Here are my routes that are protected:
Route::group(['prefix' => 'admin', 'middleware' => 'auth'], function() {
Route::get('/', ['as' => 'admin.dashboard', 'uses' => 'Admin\DashboardController#index']);
Route::get('show/{show}/toggle',['as' => 'admin.show.toggle','uses'=>'Admin\ShowController#toggle']);
Route::resource('show', 'Admin\ShowController');
// The admin.media.begin-destroy and admin.media.destroy fails when middleware => 'auth'
Route::get('media/begin-destroy-ddd/{id}', ['as' => 'admin.media.begin-destroy', 'uses' => 'Admin\MediaController#beginDestroy']);
Route::resource('media', 'Admin\MediaController', ['only' => ['index', 'create', 'store', 'destroy']]);
Route::get('order', ['as'=> 'admin.order.index', 'uses' => 'Admin\OrderController#index']);
Route::get('order/list-for-modification', ['as' => 'admin.order.list-for-modification', 'uses' => 'Admin\OrderController#listModify']);
Route::get('order/{order}/begin-destroy', ['as' => 'admin.order.begin-destroy', 'uses' => 'Admin\OrderController#beginDestroy']);
Route::delete('order/{order}/destroy', ['as' => 'admin.order.destroy', 'uses' => 'Admin\OrderController#destroy']);
});
The controller method for 'admin.media.begin-destroy' and 'admin.media.destroy' are super simple:
public function beginDestroy($filename)
{
return view('admin.media.begin-destroy', compact('filename'));
}
/**
* Remove the specified resource from storage.
*
* #param int $filename
* #return Response
*/
public function destroy($filename)
{
Storage::disk('free-media')->delete($filename);
return redirect()->route('admin.media.index');
}
I am very puzzled why this doesn't work.
Edit!---
Trying to work me around the problem I
/ Moved the problematic routes into its own group with no middleware
Route::group(['prefix' => 'admin'], function() {
Route::get('media/begin-destroy/{id}', ['as' => 'admin.media.begin-destroy', 'uses' => 'Admin\MediaController#beginDestroy']);
Route::resource('media', 'Admin\MediaController', ['only' => ['index', 'create', 'store', 'destroy']]);
});
/ Added the middleware registration in the Admin\Mediacontroller Constructor, I cannot add beginDestroy, because it will fail for unknown reason
public function __construct()
{
$this->middleware('auth', ['except' => ['beginDestroy']]);
}
// In beginDestroy, I then check for the user, and the User is not logged in WTF
public function beginDestroy($filename)
{
if (Auth::check())
{
return view('admin.media.begin-destroy', compact('filename'));
}
// I end up here.
return "Un-authorized";
}
for this particular use case, it is OK for me to disable the check in beginDestroy, because in the actual destroy code, the auth works again, but what is happening ?
Changing the Route to have the filename passed using good old question mark made the difference!
This is really more of a workaround than an answer, and I still have no idea why it doesn't work the other way, anyway, here is my workaround that did the trick.
// This works
Route::get('media/begin-destroy',
['as' => 'admin.media.begin-destroy',
'uses' => 'Admin\MediaController#beginDestroy']);
// This does not work!
// For reason beyond me, the 'auth' middleware fails here
// and Auth::check() also fails
// (Yes ofcourse I updated the signature accordingly in beginDestroy)
Route::get('media/begin-destroy/{filename}',
['as' => 'admin.media.begin-destroy',
'uses' => 'Admin\MediaController#beginDestroy']);