Working on the API

This commit is contained in:
Hillel Coren 2015-11-02 20:43:22 +02:00
parent c130e67e54
commit 6130626422
9 changed files with 50 additions and 37 deletions

View File

@ -7,7 +7,7 @@ use Input;
use App\Models\Client;
use App\Models\Account;
use App\Ninja\Repositories\AccountRepository;
use Illuminate\Http\Request;
use League\Fractal;
use League\Fractal\Resource\Item;
use League\Fractal\Manager;
@ -23,6 +23,19 @@ class AccountApiController extends Controller
$this->accountRepo = $accountRepo;
}
public function login(Request $request)
{
if ( ! env(API_SECRET) || $request->api_secret !== env(API_SECRET)) {
return 'Invalid secret';
}
if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
return $this->accountRepo->createToken($request->token_name);
} else {
return 'Invalid credentials';
}
}
public function index()
{
$manager = new Manager();

View File

@ -98,13 +98,6 @@ class AuthController extends Controller {
$users = $this->accountRepo->loadAccounts(Auth::user()->id);
}
Session::put(SESSION_USER_ACCOUNTS, $users);
if ($request->create_token) {
if ( ! env(API_SECRET) || $request->api_secret !== env(API_SECRET)) {
return 'Invalid secret';
}
return $this->accountRepo->createToken($request->token_name);
}
} elseif ($user) {
$user->failed_logins = $user->failed_logins + 1;
$user->save();

View File

@ -109,6 +109,7 @@ class DashboardController extends BaseController
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
->leftJoin('invoices', 'invoices.id', '=', 'payments.invoice_id')
->where('payments.account_id', '=', Auth::user()->account_id)
->where('payments.deleted_at', '=', null)
->where('clients.deleted_at', '=', null)
->where('contacts.deleted_at', '=', null)
->where('contacts.is_primary', '=', true)

View File

@ -528,7 +528,7 @@ class PaymentController extends BaseController
if (method_exists($gateway, 'completePurchase') && !$accountGateway->isGateway(GATEWAY_TWO_CHECKOUT)) {
$details = $this->paymentService->getPaymentDetails($invitation, $accountGateway);
$response = $gateway->completePurchase($details)->send();
$ref = $response->getTransactionReference();
$ref = $response->getTransactionReference() ?: $token;
if ($response->isSuccessful()) {
$payment = $this->paymentService->createPayment($invitation, $ref, $payerId);

View File

@ -21,33 +21,38 @@ class ApiCheck {
*/
public function handle($request, Closure $next)
{
$loggingIn = $request->is('api/v1/login');
$headers = Utils::getApiHeaders();
// check for a valid token
$token = AccountToken::where('token', '=', Request::header('X-Ninja-Token'))->first(['id', 'user_id']);
if ($token) {
Auth::loginUsingId($token->user_id);
Session::set('token_id', $token->id);
if ($loggingIn) {
// do nothing
} else {
sleep(3);
return Response::make('Invalid token', 403, $headers);
// check for a valid token
$token = AccountToken::where('token', '=', Request::header('X-Ninja-Token'))->first(['id', 'user_id']);
if ($token) {
Auth::loginUsingId($token->user_id);
Session::set('token_id', $token->id);
} else {
sleep(3);
return Response::make('Invalid token', 403, $headers);
}
}
if (!Utils::isNinja()) {
if (!Utils::isNinja() && !$loggingIn) {
return $next($request);
}
if (!Utils::isPro()) {
if (!Utils::isPro() && !$loggingIn) {
return Response::make('API requires pro plan', 403, $headers);
} else {
$accountId = Auth::user()->account->id;
$key = Auth::check() ? Auth::user()->account->id : $request->getClientIp();
// http://stackoverflow.com/questions/1375501/how-do-i-throttle-my-sites-api-users
$hour = 60 * 60;
$hour_limit = 100; # users are limited to 100 requests/hour
$hour_throttle = Cache::get("hour_throttle:{$accountId}", null);
$last_api_request = Cache::get("last_api_request:{$accountId}", 0);
$hour_throttle = Cache::get("hour_throttle:{$key}", null);
$last_api_request = Cache::get("last_api_request:{$key}", 0);
$last_api_diff = time() - $last_api_request;
if (is_null($hour_throttle)) {
@ -66,11 +71,10 @@ class ApiCheck {
return Response::make("Please wait {$wait} second(s)", 403, $headers);
}
Cache::put("hour_throttle:{$accountId}", $new_hour_throttle, 10);
Cache::put("last_api_request:{$accountId}", time(), 10);
Cache::put("hour_throttle:{$key}", $new_hour_throttle, 10);
Cache::put("last_api_request:{$key}", time(), 10);
}
return $next($request);
}

View File

@ -7,6 +7,7 @@ class VerifyCsrfToken extends BaseVerifier {
private $openRoutes = [
'signup/register',
'api/v1/login',
'api/v1/clients',
'api/v1/invoices',
'api/v1/quotes',
@ -34,12 +35,6 @@ class VerifyCsrfToken extends BaseVerifier {
}
}
if ($request->is('login')) {
if (env(API_SECRET) && $request->api_secret === env(API_SECRET)) {
return $next($request);
}
}
return parent::handle($request, $next);
}

View File

@ -186,10 +186,11 @@ Route::group(['middleware' => 'auth'], function() {
get('/resend_confirmation', 'AccountController@resendConfirmation');
});
// Route group for API
// Route groups for API
Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function()
{
Route::resource('ping', 'ClientApiController@ping');
Route::post('login', 'AccountApiController@login');
Route::get('accounts', 'AccountApiController@index');
Route::resource('clients', 'ClientApiController');
Route::get('quotes/{client_id?}', 'QuoteApiController@index');

View File

@ -459,8 +459,14 @@ class AccountRepository
public function createToken($name)
{
$name = trim($name) ?: 'TOKEN';
if ($token = AccountToken::scope()->whereName($name)->first()) {
return $token->token;
}
$token = AccountToken::createNew();
$token->name = trim($name) ?: 'TOKEN';
$token->name = $name;
$token->token = str_random(RANDOM_KEY_LENGTH);
$token->save();

View File

@ -39,15 +39,15 @@ If you'd like to use our code to sell your own invoicing app email us for detail
* [Support Forum](https://www.invoiceninja.com/forums/forum/support/)
* [Feature Roadmap](https://trello.com/b/63BbiVVe/)
### Recommended Providers
* [Stripe](https://stripe.com/)
* [Postmark](https://postmarkapp.com/)
### Contributors
* [Troels Liebe Bentsen](https://github.com/tlbdk)
* [Jeramy Simpson](https://github.com/JeramyMywork) - [MyWork](https://www.mywork.com.au)
* [Sigitas Limontas](https://lt.linkedin.com/in/sigitaslimontas)
### Recommended Providers
* [Stripe](https://stripe.com/)
* [Postmark](https://postmarkapp.com/)
### Frameworks/Libraries
* [laravel/laravel](https://github.com/laravel/laravel) - A PHP Framework For Web Artisans
* [twbs/bootstrap](https://github.com/twbs/bootstrap) - Sleek, intuitive, and powerful front-end framework for faster and easier web development.