mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-17 10:08:05 +00:00
Fix #102 Implement AccountCreationRequestToken
This commit is contained in:
parent
716789592e
commit
8570aaae15
33 changed files with 424 additions and 107 deletions
|
|
@ -108,62 +108,62 @@ class Account extends Authenticatable
|
|||
|
||||
public function activationExpiration()
|
||||
{
|
||||
return $this->hasOne('App\ActivationExpiration');
|
||||
return $this->hasOne(ActivationExpiration::class);
|
||||
}
|
||||
|
||||
public function admin()
|
||||
{
|
||||
return $this->hasOne('App\Admin');
|
||||
return $this->hasOne(Admin::class);
|
||||
}
|
||||
|
||||
public function alias()
|
||||
{
|
||||
return $this->hasOne('App\Alias');
|
||||
return $this->hasOne(Alias::class);
|
||||
}
|
||||
|
||||
public function apiKey()
|
||||
{
|
||||
return $this->hasOne('App\ApiKey');
|
||||
return $this->hasOne(ApiKey::class);
|
||||
}
|
||||
|
||||
public function externalAccount()
|
||||
{
|
||||
return $this->hasOne('App\ExternalAccount');
|
||||
return $this->hasOne(ExternalAccount::class);
|
||||
}
|
||||
|
||||
public function contacts()
|
||||
{
|
||||
return $this->belongsToMany('App\Account', 'contacts', 'account_id', 'contact_id');
|
||||
return $this->belongsToMany(Account::class, 'contacts', 'account_id', 'contact_id');
|
||||
}
|
||||
|
||||
public function emailChanged()
|
||||
{
|
||||
return $this->hasOne('App\EmailChanged');
|
||||
return $this->hasOne(EmailChanged::class);
|
||||
}
|
||||
|
||||
public function nonces()
|
||||
{
|
||||
return $this->hasMany('App\DigestNonce');
|
||||
return $this->hasMany(DigestNonce::class);
|
||||
}
|
||||
|
||||
public function authTokens()
|
||||
{
|
||||
return $this->hasMany('App\AuthToken');
|
||||
return $this->hasMany(AuthToken::class);
|
||||
}
|
||||
|
||||
public function passwords()
|
||||
{
|
||||
return $this->hasMany('App\Password');
|
||||
return $this->hasMany(Password::class);
|
||||
}
|
||||
|
||||
public function phoneChangeCode()
|
||||
{
|
||||
return $this->hasOne('App\PhoneChangeCode');
|
||||
return $this->hasOne(PhoneChangeCode::class);
|
||||
}
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany('App\AccountType');
|
||||
return $this->belongsToMany(AccountType::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,6 +30,6 @@ class AccountAction extends Model
|
|||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Account');
|
||||
return $this->belongsTo(Account::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
35
flexiapi/app/AccountCreationRequestToken.php
Normal file
35
flexiapi/app/AccountCreationRequestToken.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class AccountCreationRequestToken extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $hidden = ['id', 'updated_at', 'created_at'];
|
||||
|
||||
public function accountCreationToken()
|
||||
{
|
||||
return $this->belongsTo(AccountCreationToken::class, 'acc_creation_token_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -25,4 +25,11 @@ use Illuminate\Database\Eloquent\Model;
|
|||
class AccountCreationToken extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $hidden = ['id', 'updated_at', 'created_at'];
|
||||
|
||||
public function accountCreationRequestToken()
|
||||
{
|
||||
return $this->hasOne(AccountCreationRequestToken::class, 'acc_creation_token_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,6 @@ class AccountType extends Model
|
|||
|
||||
public function accounts()
|
||||
{
|
||||
return $this->belongsToMany('App\Account');
|
||||
return $this->belongsToMany(Account::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class ActivationExpiration extends Model
|
|||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Account');
|
||||
return $this->belongsTo(Account::class);
|
||||
}
|
||||
|
||||
public function isExpired()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Account;
|
||||
|
||||
use App\AccountCreationRequestToken;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Rules\AccountCreationRequestToken as RulesAccountCreationRequestToken;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CreationRequestTokenController extends Controller
|
||||
{
|
||||
public function check(Request $request, string $creationRequestToken)
|
||||
{
|
||||
$request->merge(['account_creation_request_token' => $creationRequestToken]);
|
||||
$request->validate([
|
||||
'account_creation_request_token' => [
|
||||
'required',
|
||||
new RulesAccountCreationRequestToken
|
||||
]
|
||||
]);
|
||||
|
||||
$accountCreationRequestToken = AccountCreationRequestToken::where('token', $request->get('account_creation_request_token'))->firstOrFail();
|
||||
|
||||
return view('account.creation_request_token.check', [
|
||||
'account_creation_request_token' => $accountCreationRequestToken
|
||||
]);
|
||||
}
|
||||
|
||||
public function validateToken(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'account_creation_request_token' => [
|
||||
'required',
|
||||
new RulesAccountCreationRequestToken
|
||||
],
|
||||
'g-recaptcha-response' => 'required|captcha',
|
||||
]);
|
||||
|
||||
$accountCreationRequestToken = AccountCreationRequestToken::where('token', $request->get('account_creation_request_token'))->firstOrFail();
|
||||
$accountCreationRequestToken->validated_at = Carbon::now();
|
||||
$accountCreationRequestToken->save();
|
||||
|
||||
return view('account.creation_request_token.valid');
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
|
@ -253,20 +253,15 @@ class AccountController extends Controller
|
|||
'password' => 'required|filled',
|
||||
'dtmf_protocol' => 'nullable|in:' . Account::dtmfProtocolsRule(),
|
||||
'account_creation_token' => [
|
||||
'required_without:token',
|
||||
'required',
|
||||
new RulesAccountCreationToken
|
||||
],
|
||||
'email' => config('app.account_email_unique')
|
||||
? 'nullable|email|unique:accounts,email'
|
||||
: 'nullable|email',
|
||||
// For retro-compatibility
|
||||
'token' => [
|
||||
'required_without:account_creation_token',
|
||||
new RulesAccountCreationToken
|
||||
],
|
||||
]);
|
||||
|
||||
$token = AccountCreationToken::where('token', $request->get('token') ?? $request->get('account_creation_token'))->first();
|
||||
$token = AccountCreationToken::where('token', $request->get('account_creation_token'))->first();
|
||||
$token->used = true;
|
||||
$token->save();
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use App\AuthToken;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use App\AuthToken;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -17,13 +17,13 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class AccountContactController extends Controller
|
||||
class ContactController extends Controller
|
||||
{
|
||||
private $selected = ['id', 'username', 'domain', 'activated', 'dtmf_protocol'];
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use App\AccountCreationRequestToken;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class CreationRequestToken extends Controller
|
||||
{
|
||||
public function create(Request $request)
|
||||
{
|
||||
$creationRequestToken = new AccountCreationRequestToken;
|
||||
$creationRequestToken->token = Str::random(WebAuthenticateController::$emailCodeSize);
|
||||
$creationRequestToken->save();
|
||||
|
||||
return $creationRequestToken;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,8 +17,9 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use App\AccountCreationRequestToken;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -27,8 +28,9 @@ use Illuminate\Support\Facades\Log;
|
|||
use App\AccountCreationToken;
|
||||
use App\Libraries\FlexisipPusherConnector;
|
||||
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
|
||||
use App\Rules\AccountCreationRequestToken as RulesAccountCreationRequestToken;
|
||||
|
||||
class AccountCreationTokenController extends Controller
|
||||
class CreationTokenController extends Controller
|
||||
{
|
||||
public function sendByPush(Request $request)
|
||||
{
|
||||
|
|
@ -55,4 +57,32 @@ class AccountCreationTokenController extends Controller
|
|||
|
||||
abort(503, "Token not sent");
|
||||
}
|
||||
|
||||
public function usingAccountRequestToken(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'account_creation_request_token' => [
|
||||
'required',
|
||||
new RulesAccountCreationRequestToken
|
||||
]
|
||||
]);
|
||||
|
||||
$creationRequestToken = AccountCreationRequestToken::where('token', $request->get('account_creation_request_token'))
|
||||
->where('used', false)
|
||||
->first();
|
||||
|
||||
if ($creationRequestToken && $creationRequestToken->validated_at != null) {
|
||||
$accountCreationToken = new AccountCreationToken;
|
||||
$accountCreationToken->token = Str::random(WebAuthenticateController::$emailCodeSize);
|
||||
$accountCreationToken->save();
|
||||
|
||||
$creationRequestToken->used = true;
|
||||
$creationRequestToken->acc_creation_token_id = $accountCreationToken->id;
|
||||
$creationRequestToken->save();
|
||||
|
||||
return $accountCreationToken;
|
||||
}
|
||||
|
||||
return abort(403);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Account;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
|
@ -29,7 +29,7 @@ use App\Libraries\OvhSMS;
|
|||
use App\PhoneChangeCode;
|
||||
use App\Alias;
|
||||
|
||||
class AccountPhoneController extends Controller
|
||||
class PhoneController extends Controller
|
||||
{
|
||||
public function requestUpdate(Request $request)
|
||||
{
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
38
flexiapi/app/Rules/AccountCreationRequestToken.php
Normal file
38
flexiapi/app/Rules/AccountCreationRequestToken.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
use App\AccountCreationRequestToken as AppAccountCreationRequestToken;
|
||||
use App\Http\Controllers\Account\AuthenticateController;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
class AccountCreationRequestToken implements Rule
|
||||
{
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
return AppAccountCreationRequestToken::where('token', $value)->where('used', false)->exists()
|
||||
&& strlen($value) == AuthenticateController::$emailCodeSize;
|
||||
}
|
||||
|
||||
public function message()
|
||||
{
|
||||
return 'Please provide a valid account_creation_request_token';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,21 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,21 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2023 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
use App\AccountCreationToken;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class MakePnAttributesNullableAccountCreationTokensTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('account_creation_tokens', function (Blueprint $table) {
|
||||
$table->string('pn_provider')->nullable(true)->change();
|
||||
$table->string('pn_param')->nullable(true)->change();
|
||||
$table->string('pn_prid')->nullable(true)->change();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
AccountCreationToken::whereNull('pn_provider')->delete();
|
||||
|
||||
Schema::table('account_creation_tokens', function (Blueprint $table) {
|
||||
$table->string('pn_provider')->nullable(false)->change();
|
||||
$table->string('pn_param')->nullable(false)->change();
|
||||
$table->string('pn_prid')->nullable(false)->change();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateAccountCreationRequestTokensTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('account_creation_request_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('token', 16)->index();
|
||||
$table->boolean('used')->default(false);
|
||||
$table->dateTime('validated_at')->nullable();
|
||||
|
||||
$table->bigInteger('acc_creation_token_id')->unsigned()->nullable();
|
||||
$table->foreign('acc_creation_token_id')->references('id')
|
||||
->on('account_creation_tokens')->onDelete('cascade');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('account_creation_request_tokens');
|
||||
}
|
||||
}
|
||||
4
flexiapi/public/css/style.css
vendored
4
flexiapi/public/css/style.css
vendored
|
|
@ -29,6 +29,10 @@ body > div {
|
|||
max-width: 800px;
|
||||
}
|
||||
|
||||
.container.large {
|
||||
max-width: 1024px;
|
||||
}
|
||||
|
||||
body > footer::before {
|
||||
background-color: white;
|
||||
background-position: bottom center;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
<div class="card mt-3">
|
||||
<div class="card-body">
|
||||
{!! Form::open(['route' => 'account.creation_request_token.validate']) !!}
|
||||
{!! Form::hidden('account_creation_request_token', $account_creation_request_token->token) !!}
|
||||
@include('parts.captcha')
|
||||
{!! Form::submit('I\'m not a robot', ['class' => 'btn btn-primary btn-centered']) !!}
|
||||
{!! Form::close() !!}
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
<h3 class="text-center mt-5">Thanks for the validation</h3>
|
||||
<p class="text-center">You can now continue your registration process in the application</p>
|
||||
@endsection
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
@extends('layouts.main')
|
||||
@extends('layouts.main', ['large' => true])
|
||||
|
||||
@section('content')
|
||||
{{-- This view is only a wrapper for the markdown page --}}
|
||||
|
|
|
|||
|
|
@ -78,9 +78,19 @@ You can find more documentation on the related [IETF RFC-7616](https://tools.iet
|
|||
<span class="badge badge-success">Public</span>
|
||||
Returns `pong`
|
||||
|
||||
## Account Creation Request Tokens
|
||||
|
||||
An `account_creation_request_token` is a unique token that can be validated and then used to generate a valid `account_creation_token`.
|
||||
|
||||
### `POST /account_creation_request_tokens`
|
||||
<span class="badge badge-success">Public</span>
|
||||
|
||||
Create and return an `account_creation_request_token` that should then be validated to be used.
|
||||
|
||||
|
||||
## Account Creation Tokens
|
||||
|
||||
An account creation token is a unique token that allow the creation of a **unique** account.
|
||||
An `account_creation_token` is a unique token that allow the creation of a **unique** account.
|
||||
|
||||
### `POST /account_creation_tokens/send-by-push`
|
||||
<span class="badge badge-success">Public</span>
|
||||
|
|
@ -94,6 +104,16 @@ JSON parameters:
|
|||
* `pn_param` the push notification parameter
|
||||
* `pn_prid` the push notification unique id
|
||||
|
||||
### `POST /account_creation_tokens/using-account-creation-request-token`
|
||||
<span class="badge badge-success">Public</span>
|
||||
Create an `account_creation_token` using an `account_creation_request_token`.
|
||||
Return an `account_creation_token`.
|
||||
Return `403` if the `account_creation_request_token` provided is not valid or expired otherwise.
|
||||
|
||||
JSON parameters:
|
||||
|
||||
* `account_creation_request_token` required
|
||||
|
||||
### `POST /account_creation_tokens`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
@endsection
|
||||
|
||||
@section('body')
|
||||
<div class="container pt-4">
|
||||
<div class="container @if (isset($large) && $large) large @endif pt-4">
|
||||
@include('parts.errors')
|
||||
@yield('content')
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,59 +26,60 @@ Route::middleware('auth:api')->get('/user', function (Request $request) {
|
|||
});
|
||||
|
||||
Route::get('ping', 'Api\PingController@ping');
|
||||
Route::post('account_creation_tokens/send-by-push', 'Api\AccountCreationTokenController@sendByPush');
|
||||
// Old URL, for retro-compatibility
|
||||
Route::post('tokens', 'Api\AccountCreationTokenController@sendByPush');
|
||||
|
||||
Route::get('accounts/{sip}/info', 'Api\AccountController@info');
|
||||
Route::post('account_creation_request_tokens', 'Api\Account\CreationRequestToken@create');
|
||||
Route::post('account_creation_tokens/send-by-push', 'Api\Account\CreationTokenController@sendByPush');
|
||||
Route::post('account_creation_tokens/using-account-creation-request-token', 'Api\Account\CreationTokenController@usingAccountRequestToken');
|
||||
Route::post('accounts/with-account-creation-token', 'Api\Account\AccountController@store');
|
||||
|
||||
Route::post('accounts/with-account-creation-token', 'Api\AccountController@store');
|
||||
// Old URL, for retro-compatibility
|
||||
Route::post('accounts/with-token', 'Api\AccountController@store');
|
||||
Route::get('accounts/{sip}/info', 'Api\Account\AccountController@info');
|
||||
|
||||
Route::post('accounts/{sip}/activate/email', 'Api\AccountController@activateEmail');
|
||||
Route::post('accounts/{sip}/activate/phone', 'Api\AccountController@activatePhone');
|
||||
Route::post('accounts/{sip}/activate/email', 'Api\Account\AccountController@activateEmail');
|
||||
Route::post('accounts/{sip}/activate/phone', 'Api\Account\AccountController@activatePhone');
|
||||
|
||||
// /!\ Dangerous endpoints
|
||||
Route::post('accounts/public', 'Api\AccountController@storePublic');
|
||||
Route::get('accounts/{sip}/recover/{recovery_key}', 'Api\AccountController@recoverUsingKey');
|
||||
Route::post('accounts/recover-by-phone', 'Api\AccountController@recoverByPhone');
|
||||
Route::get('accounts/{phone}/info-by-phone', 'Api\AccountController@phoneInfo');
|
||||
Route::post('accounts/public', 'Api\Account\AccountController@storePublic');
|
||||
Route::get('accounts/{sip}/recover/{recovery_key}', 'Api\Account\AccountController@recoverUsingKey');
|
||||
Route::post('accounts/recover-by-phone', 'Api\Account\AccountController@recoverByPhone');
|
||||
Route::get('accounts/{phone}/info-by-phone', 'Api\Account\AccountController@phoneInfo');
|
||||
|
||||
Route::post('accounts/auth_token', 'Api\AuthTokenController@store');
|
||||
Route::post('accounts/auth_token', 'Api\Account\AuthTokenController@store');
|
||||
|
||||
Route::get('accounts/me/api_key/{auth_token}', 'Api\ApiKeyController@generateFromToken')->middleware('cookie', 'cookie.encrypt');
|
||||
Route::get('accounts/me/api_key/{auth_token}', 'Api\Account\ApiKeyController@generateFromToken')->middleware('cookie', 'cookie.encrypt');
|
||||
|
||||
Route::group(['middleware' => ['auth.digest_or_key']], function () {
|
||||
Route::get('statistic/month', 'Api\StatisticController@month');
|
||||
Route::get('statistic/week', 'Api\StatisticController@week');
|
||||
Route::get('statistic/day', 'Api\StatisticController@day');
|
||||
|
||||
Route::get('accounts/auth_token/{auth_token}/attach', 'Api\AuthTokenController@attach');
|
||||
Route::get('accounts/auth_token/{auth_token}/attach', 'Api\Account\AuthTokenController@attach');
|
||||
|
||||
Route::get('accounts/me/api_key', 'Api\ApiKeyController@generate')->middleware('cookie', 'cookie.encrypt');
|
||||
Route::get('accounts/me/api_key', 'Api\Account\ApiKeyController@generate')->middleware('cookie', 'cookie.encrypt');
|
||||
|
||||
Route::get('accounts/me', 'Api\AccountController@show');
|
||||
Route::delete('accounts/me', 'Api\AccountController@delete');
|
||||
Route::get('accounts/me/provision', 'Api\AccountController@provision');
|
||||
Route::get('accounts/me', 'Api\Account\AccountController@show');
|
||||
Route::delete('accounts/me', 'Api\Account\AccountController@delete');
|
||||
Route::get('accounts/me/provision', 'Api\Account\AccountController@provision');
|
||||
|
||||
Route::post('accounts/me/phone/request', 'Api\AccountPhoneController@requestUpdate');
|
||||
Route::post('accounts/me/phone', 'Api\AccountPhoneController@update');
|
||||
Route::post('accounts/me/phone/request', 'Api\Account\PhoneController@requestUpdate');
|
||||
Route::post('accounts/me/phone', 'Api\Account\PhoneController@update');
|
||||
|
||||
Route::get('accounts/me/devices', 'Api\DeviceController@index');
|
||||
Route::delete('accounts/me/devices/{uuid}', 'Api\DeviceController@destroy');
|
||||
Route::get('accounts/me/devices', 'Api\Account\DeviceController@index');
|
||||
Route::delete('accounts/me/devices/{uuid}', 'Api\Account\DeviceController@destroy');
|
||||
|
||||
Route::post('accounts/me/email/request', 'Api\EmailController@requestUpdate');
|
||||
Route::post('accounts/me/password', 'Api\PasswordController@update');
|
||||
Route::post('accounts/me/email/request', 'Api\Account\EmailController@requestUpdate');
|
||||
Route::post('accounts/me/password', 'Api\Account\PasswordController@update');
|
||||
|
||||
Route::get('accounts/me/contacts/{sip}', 'Api\AccountContactController@show');
|
||||
Route::get('accounts/me/contacts', 'Api\AccountContactController@index');
|
||||
Route::get('accounts/me/contacts/{sip}', 'Api\Account\ContactController@show');
|
||||
Route::get('accounts/me/contacts', 'Api\Account\ContactController@index');
|
||||
|
||||
Route::group(['middleware' => ['auth.admin']], function () {
|
||||
if (!empty(config('app.linphone_daemon_unix_pipe'))) {
|
||||
Route::post('messages', 'Api\MessageController@send');
|
||||
Route::post('messages', 'Api\Admin\MessageController@send');
|
||||
}
|
||||
|
||||
// Account creation token
|
||||
Route::post('account_creation_tokens', 'Api\Admin\AccountCreationTokenController@create');
|
||||
|
||||
// Accounts
|
||||
Route::get('accounts/{id}/activate', 'Api\Admin\AccountController@activate');
|
||||
Route::get('accounts/{id}/deactivate', 'Api\Admin\AccountController@deactivate');
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ if (config('app.web_panel')) {
|
|||
Route::get('authenticate/qrcode/{token?}', 'Account\AuthenticateController@loginAuthToken')->name('account.authenticate.auth_token');
|
||||
}
|
||||
|
||||
Route::get('creation_token/check/{token}', 'Account\CreationRequestTokenController@check')->name('account.creation_request_token.check');
|
||||
Route::post('creation_token/validate', 'Account\CreationRequestTokenController@validateToken')->name('account.creation_request_token.validate');
|
||||
|
||||
Route::group(['middleware' => 'auth.digest_or_key'], function () {
|
||||
Route::get('provisioning/me', 'Account\ProvisioningController@me')->name('provisioning.me');
|
||||
|
||||
|
|
|
|||
|
|
@ -19,17 +19,23 @@
|
|||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\AccountCreationRequestToken;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
use App\AccountCreationToken;
|
||||
use App\Admin;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class ApiAccountCreationTokenTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected $tokenRoute = '/api/account_creation_tokens/send-by-push';
|
||||
protected $tokenRequestRoute = '/api/account_creation_request_tokens';
|
||||
protected $tokenUsingCreationTokenRoute = '/api/account_creation_tokens/using-account-creation-request-token';
|
||||
protected $accountRoute = '/api/accounts/with-account-creation-token';
|
||||
protected $adminRoute = '/api/account_creation_tokens';
|
||||
protected $method = 'POST';
|
||||
|
||||
protected $pnProvider = 'provider';
|
||||
|
|
@ -52,51 +58,24 @@ class ApiAccountCreationTokenTest extends TestCase
|
|||
$response->assertStatus(503);
|
||||
}
|
||||
|
||||
/**
|
||||
* For retro-compatibility only
|
||||
*/
|
||||
public function testRetrocopatibilityToken()
|
||||
public function testAdminEndpoint()
|
||||
{
|
||||
$token = AccountCreationToken::factory()->create();
|
||||
$admin = Admin::factory()->create();
|
||||
$admin->account->generateApiKey();
|
||||
|
||||
$response = $this->json($this->method, '/api/tokens', [
|
||||
'pn_provider' => $token->pn_provider,
|
||||
'pn_param' => $token->pn_param,
|
||||
'pn_prid' => $token->pn_prid
|
||||
$response = $this->keyAuthenticated($admin->account)
|
||||
->json($this->method, $this->adminRoute)
|
||||
->assertStatus(201);
|
||||
|
||||
$this->assertDatabaseHas('account_creation_tokens', [
|
||||
'token' => $response->json()['token']
|
||||
]);
|
||||
$response->assertStatus(503);
|
||||
}
|
||||
|
||||
public function testInvalidToken()
|
||||
{
|
||||
$token = AccountCreationToken::factory()->create();
|
||||
|
||||
// Valid token
|
||||
$response = $this->json($this->method, '/api/accounts/with-token', [
|
||||
'username' => 'username',
|
||||
'algorithm' => 'SHA-256',
|
||||
'password' => '2',
|
||||
'token' => $token->token
|
||||
]);
|
||||
$response->assertStatus(200);
|
||||
|
||||
// Expired token
|
||||
$response = $this->json($this->method, '/api/accounts/with-token', [
|
||||
'username' => 'username2',
|
||||
'algorithm' => 'SHA-256',
|
||||
'password' => '2',
|
||||
'token' => $token->token
|
||||
]);
|
||||
$response->assertStatus(422);
|
||||
}
|
||||
|
||||
/**
|
||||
* For retrocompatibility only
|
||||
*/
|
||||
public function testRetrocompatibilityInvalidToken()
|
||||
{
|
||||
$token = AccountCreationToken::factory()->create();
|
||||
|
||||
// Invalid token
|
||||
$response = $this->json($this->method, $this->accountRoute, [
|
||||
'username' => 'username',
|
||||
|
|
@ -125,9 +104,6 @@ class ApiAccountCreationTokenTest extends TestCase
|
|||
$response->assertStatus(422);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test username blacklist
|
||||
*/
|
||||
public function testBlacklistedUsername()
|
||||
{
|
||||
$token = AccountCreationToken::factory()->create();
|
||||
|
|
@ -165,4 +141,34 @@ class ApiAccountCreationTokenTest extends TestCase
|
|||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testAccountCreationRequestToken()
|
||||
{
|
||||
$response = $this->json($this->method, $this->tokenRequestRoute);
|
||||
$response->assertStatus(201);
|
||||
$creationRequestToken = $response->json()['token'];
|
||||
|
||||
// Validate the creation request token
|
||||
AccountCreationRequestToken::where('token', $creationRequestToken)->update(['validated_at' => Carbon::now()]);
|
||||
|
||||
$response = $this->json($this->method, $this->tokenUsingCreationTokenRoute, [
|
||||
'account_creation_request_token' => $creationRequestToken
|
||||
])->assertStatus(201);
|
||||
|
||||
$creationToken = $response->json()['token'];
|
||||
|
||||
$this->assertDatabaseHas('account_creation_request_tokens', [
|
||||
'token' => $creationRequestToken,
|
||||
'used' => true
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('account_creation_tokens', [
|
||||
'token' => $creationToken
|
||||
]);
|
||||
|
||||
$this->assertSame(
|
||||
AccountCreationRequestToken::where('token', $creationRequestToken)->first()->accountCreationToken->id,
|
||||
AccountCreationToken::where('token', $creationToken)->first()->id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue