mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-02-07 13:58:24 +00:00
Base authentication system + layout
This commit is contained in:
parent
73308bc9d6
commit
e9e9d09b37
19 changed files with 1022 additions and 472 deletions
|
|
@ -40,4 +40,11 @@ class Utils
|
|||
|
||||
return $nonce->nonce;
|
||||
}
|
||||
|
||||
public static function bchash(string $username, string $domain, string $password, string $algorithm = 'MD5')
|
||||
{
|
||||
$algos = ['MD5' => 'md5', 'SHA-256' => 'sha256'];
|
||||
|
||||
return hash($algos[$algorithm], $username.':'.$domain.':'.$password);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
47
flexiapi/app/Http/Controllers/AccountController.php
Normal file
47
flexiapi/app/Http/Controllers/AccountController.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
use App\Account;
|
||||
use App\Rules\SIP;
|
||||
use App\Helpers\Utils;
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('account.index', [
|
||||
'account' => $request->user()
|
||||
]);
|
||||
}
|
||||
|
||||
public function authenticate(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'username' => ['required', new SIP],
|
||||
'password' => 'required'
|
||||
]);
|
||||
|
||||
list($username, $domain) = explode('@', $request->get('username'));
|
||||
|
||||
$account = Account::where('username', $username)
|
||||
->where('domain', $domain)
|
||||
->firstOrFail();
|
||||
|
||||
// Try out the passwords
|
||||
foreach ($account->passwords as $password) {
|
||||
if (hash_equals(
|
||||
$password->password,
|
||||
Utils::bchash($username, $domain, $request->get('password'), $password->algorithm)
|
||||
)) {
|
||||
Auth::login($account);
|
||||
return redirect()->route('account.index');
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
10
flexiapi/app/Http/Controllers/AdminController.php
Normal file
10
flexiapi/app/Http/Controllers/AdminController.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AdminController extends Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
14
flexiapi/app/Http/Controllers/Api/ApiController.php
Normal file
14
flexiapi/app/Http/Controllers/Api/ApiController.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ApiController extends Controller
|
||||
{
|
||||
public function documentation(Request $request)
|
||||
{
|
||||
return view('documentation');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2019 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\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Account;
|
||||
|
||||
class DocumentationController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('documentation', [
|
||||
'accounts' => Account::all(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
22
flexiapi/app/Http/Controllers/HomeController.php
Normal file
22
flexiapi/app/Http/Controllers/HomeController.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
use App\Account;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('home');
|
||||
}
|
||||
|
||||
public function logout(Request $request)
|
||||
{
|
||||
Auth::logout();
|
||||
return redirect()->route('home');
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ class Authenticate extends Middleware
|
|||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
return route('home');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
42
flexiapi/app/Rules/SIP.php
Normal file
42
flexiapi/app/Rules/SIP.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SIP implements Rule
|
||||
{
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
// TODO complete me
|
||||
return Str::contains($value, '@');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return 'The :attribute must be a SIP address.';
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,8 @@
|
|||
"php": "^7.2",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"laravel/framework": "^6.2",
|
||||
"laravel/tinker": "^2.0"
|
||||
"laravel/tinker": "^2.0",
|
||||
"laravelcollective/html": "^6.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^1.4",
|
||||
|
|
|
|||
1149
flexiapi/composer.lock
generated
1149
flexiapi/composer.lock
generated
File diff suppressed because it is too large
Load diff
5
flexiapi/resources/views/account/index.blade.php
Normal file
5
flexiapi/resources/views/account/index.blade.php
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
@extends('layouts.account')
|
||||
|
||||
@section('content')
|
||||
{{ $account->identifier }}
|
||||
@endsection
|
||||
|
|
@ -1,33 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
@extends('layouts.main')
|
||||
|
||||
<title>Flexisip API</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-lg pt-3">
|
||||
<h1>Flexisip API</h1>
|
||||
<p>An API to deal with the Flexisip server</p>
|
||||
@section('content')
|
||||
<h1>Flexisip API</h1>
|
||||
<p>An API to deal with the Flexisip server</p>
|
||||
|
||||
<p>The API is available under <code>/api</code></p>
|
||||
<p>A <code>from</code> (consisting of the user SIP address, prefixed with <code>sip:</code>), <code>content-type</code> and <code>accept</code> HTTP headers are required to use the API properly</p>
|
||||
<p>The API is available under <code>/api</code></p>
|
||||
<p>A <code>from</code> (consisting of the user SIP address, prefixed with <code>sip:</code>), <code>content-type</code> and <code>accept</code> HTTP headers are required to use the API properly</p>
|
||||
|
||||
<pre>
|
||||
<pre>
|
||||
<code>> GET /api/{endpoint}
|
||||
> from: sip:foobar@sip.example.org
|
||||
> content-type: application/json
|
||||
> accept: application/json</code></pre>
|
||||
|
||||
<h2>Authentication</h2>
|
||||
<p>Restricted endpoints are protected using a DIGEST authentication mechanism.</p>
|
||||
<h2>Authentication</h2>
|
||||
<p>Restricted endpoints are protected using a DIGEST authentication mechanism.</p>
|
||||
|
||||
<p>To discover the available hashing algorythm you MUST send an unauthenticated request to one of the restricted endpoints.<br />
|
||||
For the moment only DIGEST-MD5 and DIGEST-SHA-256 are supported through the authentication layer.</p>
|
||||
<p>To discover the available hashing algorythm you MUST send an unauthenticated request to one of the restricted endpoints.<br />
|
||||
For the moment only DIGEST-MD5 and DIGEST-SHA-256 are supported through the authentication layer.</p>
|
||||
|
||||
<pre>
|
||||
<pre>
|
||||
<code>> GET /api/{restricted-endpoint}
|
||||
> …
|
||||
|
||||
|
|
@ -36,19 +28,17 @@
|
|||
< www-authenticate: Digest realm=test,qop=auth,algorithm=MD5,nonce="{nonce}",opaque="{opaque}"
|
||||
< www-authenticate: Digest realm=test,qop=auth,algorithm=SHA-256,nonce="{nonce}",opaque="{opaque}"</code></pre>
|
||||
|
||||
<p>You can find more documentation on the related <a href="https://tools.ietf.org/html/rfc7616">IETF RFC-7616</a>.</p>
|
||||
<p>You can find more documentation on the related <a href="https://tools.ietf.org/html/rfc7616">IETF RFC-7616</a>.</p>
|
||||
|
||||
<h2>Endpoints</h2>
|
||||
<h2>Endpoints</h2>
|
||||
|
||||
<p>Current implemented endpoints</p>
|
||||
<p>Current implemented endpoints</p>
|
||||
|
||||
<h4><code>GET /devices</code></h4>
|
||||
<h4><code>GET /devices</code></h4>
|
||||
|
||||
<p>Return the user registered devices.</p>
|
||||
<p>Return the user registered devices.</p>
|
||||
|
||||
<h4><code>DELETE /devices/{uuid}</code></h4>
|
||||
<h4><code>DELETE /devices/{uuid}</code></h4>
|
||||
|
||||
<p>Remove one of the user registered devices.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<p>Remove one of the user registered devices.</p>
|
||||
@endsection
|
||||
|
|
|
|||
26
flexiapi/resources/views/home.blade.php
Normal file
26
flexiapi/resources/views/home.blade.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
@if (Auth::check())
|
||||
<div class="alert alert-primary" role="alert">
|
||||
<a class="float-right" href="{{ route('logout') }}">Logout</a>
|
||||
You are already authenticated
|
||||
</div>
|
||||
@else
|
||||
<div class="card mt-3">
|
||||
<div class="card-body">
|
||||
{!! Form::open(['route' => 'account.authenticate']) !!}
|
||||
<div class="form-group">
|
||||
{!! Form::label('username', 'Username') !!}
|
||||
{!! Form::text('username', old('username'), ['class' => 'form-control', 'placeholder' => 'username@sip.linphone.org', 'required']) !!}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{!! Form::label('password', 'Password') !!}
|
||||
{!! Form::password('password', ['class' => 'form-control', 'placeholder' => 'myPassword', 'required']) !!}
|
||||
</div>
|
||||
{!! Form::submit('Authenticate', ['class' => 'btn btn-primary']) !!}
|
||||
{!! Form::close() !!}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
25
flexiapi/resources/views/layouts/account.blade.php
Normal file
25
flexiapi/resources/views/layouts/account.blade.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
@extends('layouts.base')
|
||||
|
||||
@section('body')
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="collapse navbar-collapse" >
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/">FlexiAPI</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('account.index') }}">My Account</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="{{ route('logout') }}">Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-lg pt-3">
|
||||
@include('parts.errors')
|
||||
@yield('content')
|
||||
</div>
|
||||
@endsection
|
||||
13
flexiapi/resources/views/layouts/base.blade.php
Normal file
13
flexiapi/resources/views/layouts/base.blade.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Flexisip API</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
@yield('body')
|
||||
</body>
|
||||
</html>
|
||||
25
flexiapi/resources/views/layouts/main.blade.php
Normal file
25
flexiapi/resources/views/layouts/main.blade.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
@extends('layouts.base')
|
||||
|
||||
@section('body')
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="collapse navbar-collapse" >
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/">FlexiAPI</a>
|
||||
</li>
|
||||
@if (isset($user) && get_class($user) == 'App\Account')
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="{{ route('account.index') }}">My Account</a>
|
||||
</li>
|
||||
@endif
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('api') }}">API</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-lg pt-3">
|
||||
@include('parts.errors')
|
||||
@yield('content')
|
||||
</div>
|
||||
@endsection
|
||||
9
flexiapi/resources/views/parts/errors.blade.php
Normal file
9
flexiapi/resources/views/parts/errors.blade.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
@if (isset($errors) && $errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul class="mb-0">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
Route::get('/', 'Api\ApiController@documentation')->name('api');
|
||||
|
||||
Route::middleware('auth:api')->get('/user', function (Request $request) {
|
||||
return $request->user();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -17,4 +17,11 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
Route::get('/', 'DocumentationController@index');
|
||||
Route::get('/', 'HomeController@index')->name('home');
|
||||
Route::get('logout', 'HomeController@logout')->name('logout');
|
||||
|
||||
Route::post('account/authenticate', 'AccountController@authenticate')->name('account.authenticate');
|
||||
|
||||
Route::group(['middleware' => 'auth'], function () {
|
||||
Route::get('account', 'AccountController@index')->name('account.index');
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue