Commit 31b5158f by Palti Sinaga

Merge branch 'master' of https://gitlab.del.ac.id/juliper19/pa2d4ti06

# Conflicts: # resources/views/vendor/adminlte/layouts/pages/Homestay.blade.php
parents 9ca0c2fa abb3f8ad
APP_ENV=local
APP_KEY=base64:PYpgHHGl4uu9e47KBcSblh6QGgp48HawdpFxrzqzxm0=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=p2d4ti06_test
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_KEY=
PUSHER_SECRET=
/node_modules /node_modules
/public/storage /public/storage
/storage/*.key
/.idea /.idea
Homestead.json Homestead.json
Homestead.yaml Homestead.yaml
.env
...@@ -18,6 +18,11 @@ use App\RequestFasilitas; ...@@ -18,6 +18,11 @@ use App\RequestFasilitas;
class AdminController extends Controller class AdminController extends Controller
{ {
public function __construct(){
$this->middleware('auth');
$this->middleware('dinaspariwisata');
}
public function index() public function index()
{ {
return view('adminlte::home'); return view('adminlte::home');
...@@ -51,6 +56,24 @@ class AdminController extends Controller ...@@ -51,6 +56,24 @@ class AdminController extends Controller
public function store(Request $request) public function store(Request $request)
{ {
$this->validate($request,[
'name' => 'required|min:5|max:35',
'username' => 'required|min:5|max:35',
'email' => 'required|email|unique:users',
'password' => 'required|min:6|max:20',
'password_confirmation' => 'required|min:3|max:20|same:password',
],[
'name.required' => ' Nama Harus di isi',
'name.min' => ' Nama minimal 5 characters.',
'name.max' => ' Nama maksimal 35 characters.',
'username.required' => ' Username Harus di isi',
'username.min' => ' Usename minimal 5 characters.',
'username.max' => ' Username maksimal 35 characters.',
'password.required' => 'Password Harus di isi',
'password_confirmation.required' => 'Password Confirmasi Harus di isi',
]);
$data = $request->all(); $data = $request->all();
$user = new User(); $user = new User();
$user->name = $data['name']; $user->name = $data['name'];
......
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Notifications\Messages\NexmoMessage;
use SimpleSoftwareIO\SMS\Drivers\NexmoSMS;
use Nexmo;
use App\Feedback;
use App\Homestay;
use App\ListBook;
use App\Room;
use App\Transaksi;
use Illuminate\Support\Facades\Auth;
use App\User;
use App\Customer;
use Illuminate\Support\Facades\DB;
use Illuminate\Contracts\Auth\Guard;
use DateTime;
use PhpParser\Node\Stmt\Const_;
use Psy\Command\ListCommand\ConstantEnumerator;
class CobaController extends Controller
{
public function route(){
Nexmo::message()->send([
'to' => '6282272194654',
'from' => 'ASDASD',
'text' => 'Hi ini hanya sebuah test no more'
]);
return view('welcome');
}
public function detailhomestay($id){
$data = DB::table('homestay')
->join('pemilikhomestay','homestay.idPemilik','=','pemilikhomestay.id')
->select('pemilikhomestay.*','homestay.*')
->where('homestay.id','=',$id)
->get();
$daftarBook = DB::table('daftar_book')
->select('daftar_book.*')
->where('daftar_book.homestay','=',$id)
->get();
$now = new DateTime();
$nowCurrent = $now->format('Y-m-d');
//dd($nowCurrent);
$dataJumlahKamar = ListBook::all()->where('tanggal_mulai',$nowCurrent);
$avilableRoom = 0;
if($dataJumlahKamar->count() == null){
//dd('disini aja');
$avilableRoom = $data[0]->jumlahKamar;
}else{
//dd($dataJumlahKamar);
$avilableRoom = $dataJumlahKamar[0]->jumlah_kamar;
}
$dataKamar = DB::table('kamar')
->select('kamar.*')
->where('kamar.idHomestay','=',$id)
->get();
//dd("masuk agan",$id,$dataKamar);
return view('adminlte::layouts.pages.Homestay')->with('data',$data[0])->with('daftarBook',$daftarBook)->with('dataKamar',$dataKamar)->with('avilable',$avilableRoom);
}
}
...@@ -16,10 +16,19 @@ use Illuminate\Contracts\Auth\Guard; ...@@ -16,10 +16,19 @@ use Illuminate\Contracts\Auth\Guard;
use DateTime; use DateTime;
use PhpParser\Node\Stmt\Const_; use PhpParser\Node\Stmt\Const_;
use Psy\Command\ListCommand\ConstantEnumerator; use Psy\Command\ListCommand\ConstantEnumerator;
use Illuminate\Notifications\Messages\NexmoMessage;
use SimpleSoftwareIO\SMS\Drivers\NexmoSMS;
use Nexmo\Laravel\Facade\Nexmo;
class CustomerController extends Controller class CustomerController extends Controller
{ {
public function __construct(){
//$this->middleware('auth');
$this->middleware('customer');
}
public function cancelPemesanan($id){ public function cancelPemesanan($id){
$dataTrsaksi = Transaksi::find($id); $dataTrsaksi = Transaksi::find($id);
...@@ -163,45 +172,6 @@ class CustomerController extends Controller ...@@ -163,45 +172,6 @@ class CustomerController extends Controller
return view('adminlte::layouts.customers.editprofiles')->with('data',$data); return view('adminlte::layouts.customers.editprofiles')->with('data',$data);
} }
public function detailhomestay($id){
$data = DB::table('homestay')
->join('pemilikhomestay','homestay.idPemilik','=','pemilikhomestay.id')
->select('pemilikhomestay.*','homestay.*')
->where('homestay.id','=',$id)
->get();
$daftarBook = DB::table('daftar_book')
->select('daftar_book.*')
->where('daftar_book.homestay','=',$id)
->get();
$now = new DateTime();
$nowCurrent = $now->format('Y-m-d');
//dd($nowCurrent);
$dataJumlahKamar = ListBook::all()->where('tanggal_mulai',$nowCurrent);
$avilableRoom = 0;
if($dataJumlahKamar->count() == null){
//dd('disini aja');
$avilableRoom = $data[0]->jumlahKamar;
}else{
//dd($dataJumlahKamar);
$avilableRoom = $dataJumlahKamar[0]->jumlah_kamar;
}
$dataKamar = DB::table('kamar')
->select('kamar.*')
->where('kamar.idHomestay','=',$id)
->get();
//dd("masuk agan",$id,$dataKamar);
return view('adminlte::layouts.pages.Homestay')->with('data',$data[0])->with('daftarBook',$daftarBook)->with('dataKamar',$dataKamar)->with('avilable',$avilableRoom);
}
public function updateProfile(Request $request,$id){ public function updateProfile(Request $request,$id){
$cus = Customer::find($id); $cus = Customer::find($id);
$dataUs = User::find(Auth::user()->id); $dataUs = User::find(Auth::user()->id);
...@@ -233,10 +203,23 @@ class CustomerController extends Controller ...@@ -233,10 +203,23 @@ class CustomerController extends Controller
} }
public function booking(Request $request){ public function booking(Request $request){
$this->validate($request,[
'tanggal' => 'required',
'jumlah_hari' => 'required|numeric',
'jumlah_kamar' => 'required|numeric',
],[
'tanggal.required' => 'Tanggal Harus di isi',
'jumlah_kamar.required' => ' Jumlah Kamar Harus di isi',
'jumlah_kamar.numeric' => ' Jumlah Kamr harus berupa Angka',
'jumlah_hari.required' => ' Lama menginap harus Diisi',
'jumlah_hari.numeric' => ' Lama menginap harus berupa Angka',
]);
if(Auth::guest()){ if(Auth::guest()){
return view('adminlte::errors.Account'); return view('adminlte::errors.Account');
} }
$lb = new ListBook(); $lb = new ListBook();
$dataHomestay = DB::table('homestay') $dataHomestay = DB::table('homestay')
...@@ -245,6 +228,14 @@ class CustomerController extends Controller ...@@ -245,6 +228,14 @@ class CustomerController extends Controller
->where('homestay.id','=',$request['id']) ->where('homestay.id','=',$request['id'])
->get(); ->get();
$dataPemilik = DB::table('homestay')
->join('pemilikhomestay','homestay.idPemilik','pemilikhomestay.id')
->select('pemilikhomestay.noTelepon')
->where('homestay.id','=',$request['id'])
->get();
//dd("masuk dis ");
$homestayJumlahKamar = DB::table('homestay')->select('homestay.jumlahKamar')->where('homestay.id','=',$request['id'])->get(); $homestayJumlahKamar = DB::table('homestay')->select('homestay.jumlahKamar')->where('homestay.id','=',$request['id'])->get();
$dataBookingMulai = DB::table('daftar_book') $dataBookingMulai = DB::table('daftar_book')
...@@ -345,8 +336,9 @@ class CustomerController extends Controller ...@@ -345,8 +336,9 @@ class CustomerController extends Controller
->where('transaksi.tanggal_mulai','=',$request['tanggal']) ->where('transaksi.tanggal_mulai','=',$request['tanggal'])
->where('transaksi.tanggal_berakhir','=',$baru) ->where('transaksi.tanggal_berakhir','=',$baru)
->get(); ->get();
//Insert Table Daftar Booking //Insert Table Daftar Booking
$lb->homestay = $request['id']; $lb->homestay = $request['id'];
$lb->id_transaksi = $dataTrans[0]->id; $lb->id_transaksi = $dataTrans[0]->id;
...@@ -359,8 +351,16 @@ class CustomerController extends Controller ...@@ -359,8 +351,16 @@ class CustomerController extends Controller
$lb->save(); $lb->save();
return redirect()->action('CustomerController@detailhomestay', ['id' => $request['id']]); Nexmo::message()->send([
'to' => $dataPemilik[0]->noTelepon,
'from' => 'ASDASD',
'text' => 'Hi ini hanya sebuah test no more'
]);
return redirect()->action('CobaController@detailhomestay', ['id' => $request['id']]);
} }
} }
...@@ -17,6 +17,11 @@ use Illuminate\Support\Facades\DB; ...@@ -17,6 +17,11 @@ use Illuminate\Support\Facades\DB;
class OwnerController extends Controller class OwnerController extends Controller
{ {
public function __construct(){
$this->middleware('auth');
$this->middleware('owner');
}
public function index() public function index()
{ {
return view('adminlte::layouts.owner.home'); return view('adminlte::layouts.owner.home');
...@@ -66,14 +71,10 @@ class OwnerController extends Controller ...@@ -66,14 +71,10 @@ class OwnerController extends Controller
} }
public function profile(){ public function profile(){
$users = User::find(Auth::user()->id);
//dd($users->name);
//$data = Owner::where('nama',$users->name);
$users = User::find(Auth::user()->id);
$data = DB::table('pemilikhomestay')->where('nama', $users->name)->first(); $data = DB::table('pemilikhomestay')->where('nama', $users->name)->first();
//dd($data);
return view('adminlte::layouts.owner.profil')->with('data',$data); return view('adminlte::layouts.owner.profil')->with('data',$data);
} }
...@@ -94,6 +95,19 @@ class OwnerController extends Controller ...@@ -94,6 +95,19 @@ class OwnerController extends Controller
} }
public function updateHomestay(Request $request,$id){ public function updateHomestay(Request $request,$id){
$this->validate($request,[
'namaUpdate' => 'required|string',
'alamatUpdate' => 'required|string',
'hargaUpdate' => 'required|numeric',
],[
'namaUpdate.required' => ' Nama Homestay Harus di isi',
'alamatUpdate.required' => 'Alamat Harus Diisi',
'hargaUpdate.required' => ' Harga Harus di isi',
'hargaUpdate.numeric' => ' Harga Harus Berupa Angka',
]);
$updateHomestay = Homestay::find($id); $updateHomestay = Homestay::find($id);
$updateHomestay->namaHomestay = $request['namaUpdate']; $updateHomestay->namaHomestay = $request['namaUpdate'];
...@@ -183,6 +197,21 @@ class OwnerController extends Controller ...@@ -183,6 +197,21 @@ class OwnerController extends Controller
$lb = new ListBook(); $lb = new ListBook();
$this->validate($request,[
'nama' => 'required|string',
'jumlah_kamar' => 'required|numeric',
'tanggal_mulai' => 'required',
'lama_menginap' => 'required|numeric',
],[
'nama.required' => 'Nama Harus di isi',
'jumlah_kamar.required' => ' Jumlah Kamar Harus di isi',
'jumlah_kamar.numeric' => ' Jumlah Bed harus berupa Angka',
'tanggal_mulai.required' => ' Jumlah Bed harus Diis',
'lama_menginap.required' => ' Lama menginap harus Diisi',
'lama_menginap.numeric' => ' Lama menginap harus berupa Angka',
]);
$dataPemilik = DB::table('pemilikhomestay') $dataPemilik = DB::table('pemilikhomestay')
->select('pemilikhomestay.id') ->select('pemilikhomestay.id')
->where('pemilikhomestay.id_Akun','=',Auth::user()->id) ->where('pemilikhomestay.id_Akun','=',Auth::user()->id)
...@@ -210,6 +239,14 @@ class OwnerController extends Controller ...@@ -210,6 +239,14 @@ class OwnerController extends Controller
} }
public function updateRoom(Request $request, $id){ public function updateRoom(Request $request, $id){
$this->validate($request,[
'jumlah_bed' => 'required|numeric',
],[
'jumlah_bed.required' => ' Jumlah Bed Harus di isi',
'jumlah_bed.numeric' => ' Jumlah Bed harus berupa Angka',
]);
$dataKamar = Room::find($id); $dataKamar = Room::find($id);
$dataKamar->jumlah_bed = $request['jumlah_bed']; $dataKamar->jumlah_bed = $request['jumlah_bed'];
...@@ -276,6 +313,17 @@ class OwnerController extends Controller ...@@ -276,6 +313,17 @@ class OwnerController extends Controller
public function storeRequest(Request $request){ public function storeRequest(Request $request){
$this->validate($request,[
'namaRequestFasilitas' => 'required|string',
'deskripsi' => 'required|string',
'jumlah' => 'required|numeric',
],[
'namaRequestFasilitas.required' => ' Nama Fasilitas Harus di isi',
'deskripsi.required' => 'Deskripsi Harus Diisi',
'jumlah.required' => ' Jumlah Harus di isi',
'jumlah.numeric' => ' Harus Angka',
]);
$idPemilik = DB::table('users') $idPemilik = DB::table('users')
->join('pemilikhomestay','users.id','=','pemilikhomestay.id_Akun') ->join('pemilikhomestay','users.id','=','pemilikhomestay.id_Akun')
->select('pemilikhomestay.id') ->select('pemilikhomestay.id')
...@@ -310,6 +358,15 @@ class OwnerController extends Controller ...@@ -310,6 +358,15 @@ class OwnerController extends Controller
public function storePengajuan(Request $request){ public function storePengajuan(Request $request){
$this->validate($request,[
'namaHomestay' => 'required',
'jumlahKamar' => 'required|numeric',
],[
'namaHomestay.required' => ' Nama Homestay Harus Diisi Harus di isi',
'jumlahKamar.required' => ' Jumlah Kamar harus di isi.',
'jumlahKamar.numeric' => ' Jumlah Kamar Harus Berupa angka',
]);
$idPemilik = DB::table('users') $idPemilik = DB::table('users')
->join('pemilikhomestay','users.id','=','pemilikhomestay.id_Akun') ->join('pemilikhomestay','users.id','=','pemilikhomestay.id_Akun')
->select('pemilikhomestay.id') ->select('pemilikhomestay.id')
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Http; namespace App\Http;
use App\Http\Middleware\DinasPariwisata;
use Illuminate\Foundation\Http\Kernel as HttpKernel; use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel class Kernel extends HttpKernel
...@@ -52,5 +53,8 @@ class Kernel extends HttpKernel ...@@ -52,5 +53,8 @@ class Kernel extends HttpKernel
'can' => \Illuminate\Auth\Middleware\Authorize::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'dinaspariwisata' => \App\Http\Middleware\DinasPariwisata::class,
'customer' => \App\Http\Middleware\Customer::class,
'owner' => \App\Http\Middleware\Owner::class,
]; ];
} }
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class Customer
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check()){
if(Auth::user()->role !='Customer'){
dd('masuk');
if(Auth::user()->role == 'Owner'){
return redirect('owner');
}elseif(Auth::user()->role=='DinasPariwisata'){
return redirect('/home');
}else{
return redirect('');
}
}
}else{
return redirect('');
}
return $next($request);
}
}
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class DinasPariwisata
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check()){
if(Auth::user()->role != 'DinasPariwisata'){
if(Auth::user()->role =='Owner'){
return redirect('owner');
}else if(Auth::user()->role=='Customer'){
return redirect('');
}else{
return redirect('/home');
}
}
}
return $next($request);
}
}
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class Owner
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check()){
if(Auth::user()->role != 'Owner'){
dd('masuk');
if(Auth::user()->role == 'Customer'){
return redirect('');
}elseif(Auth::user()->role == 'DinasPariwisata'){
return redirect('/');
}else{
return redirect('owner');
}
}
}
return $next($request);
}
}
...@@ -6,7 +6,11 @@ ...@@ -6,7 +6,11 @@
"type": "project", "type": "project",
"require": { "require": {
"php": ">=5.6.4", "php": ">=5.6.4",
"laravel/framework": "5.3.*" "laravel/framework": "5.3.*",
"simplesoftwareio/simple-sms": "~2",
"nexmo/client": "@beta",
"nexmo/laravel": "1.0.0-beta3",
"acacha/admin-lte-template-laravel": "3.*"
}, },
"require-dev": { "require-dev": {
"fzaninotto/faker": "~1.4", "fzaninotto/faker": "~1.4",
...@@ -45,7 +49,6 @@ ...@@ -45,7 +49,6 @@
] ]
}, },
"config": { "config": {
"preferred-install": "dist", "preferred-install": "dist"
"sort-packages": true
} }
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -162,12 +162,13 @@ return [ ...@@ -162,12 +162,13 @@ return [
Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class, Illuminate\View\ViewServiceProvider::class,
Acacha\AdminLTETemplateLaravel\Providers\AdminLTETemplateServiceProvider::class,
/* /*
* Package Service Providers... * Package Service Providers...
*/ */
Nexmo\Laravel\NexmoServiceProvider::class,
Acacha\AdminLTETemplateLaravel\Providers\AdminLTETemplateServiceProvider::class,
// //
/* /*
...@@ -226,7 +227,9 @@ return [ ...@@ -226,7 +227,9 @@ return [
'URL' => Illuminate\Support\Facades\URL::class, 'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class, 'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class, 'View' => Illuminate\Support\Facades\View::class,
'AdminLTE' => Acacha\AdminLTETemplateLaravel\Facades\AdminLTE::class, 'AdminLTE' => Acacha\AdminLTETemplateLaravel\Facades\AdminLTE::class,
'Nexmo' => \Nexmo\Laravel\Facade\Nexmo::class,
], ],
......
<?php
return [
/*
|--------------------------------------------------------------------------
| API Credentials
|--------------------------------------------------------------------------
|
| If you're using API credentials, change these settings. Get your
| credentials from https://dashboard.nexmo.com | 'Settings'.
|
*/
'api_key' => '30f1d367',
'api_secret' => '4db245505ec9c5fe',
/*
|--------------------------------------------------------------------------
| Signature Secret
|--------------------------------------------------------------------------
|
| If you're using a signature secret, use this section.
|
*/
//'api_key' => 'API_KEY',
//'signature_secret' => 'SECRET'
];
\ No newline at end of file
...@@ -8,12 +8,32 @@ require('laravel-elixir-vue-2'); ...@@ -8,12 +8,32 @@ require('laravel-elixir-vue-2');
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| Elixir provides a clean, fluent API for defining some basic Gulp tasks | Elixir provides a clean, fluent API for defining some basic Gulp tasks
| for your Laravel application. By default, we are compiling the Sass | for your Laravel application. By default, we are compiling the Less
| file for your application as well as publishing vendor resources. | file for our application, as well as publishing vendor resources.
| |
*/ */
elixir((mix) => { elixir(function(mix) {
//app.scss includes app css, Boostrap and Ionicons
mix.sass('app.scss') mix.sass('app.scss')
.webpack('app.js'); .less('./node_modules/admin-lte/build/less/AdminLTE.less', './public/css/adminlte-less.css')
.less('adminlte-app.less')
.less('./node_modules/toastr/toastr.less')
.styles([
'./public/css/app.css',
'./node_modules/admin-lte/dist/css/skins/_all-skins.css',
'./public/css/adminlte-less.css',
'./public/css/adminlte-app.css',
'./node_modules/icheck/skins/square/blue.css',
'./public/css/toastr.css',
])
.copy('node_modules/font-awesome/fonts/*.*','public/fonts/')
.copy('node_modules/ionicons/dist/fonts/*.*','public/fonts/')
.copy('node_modules/admin-lte/bootstrap/fonts/*.*','public/fonts/bootstrap')
.copy('node_modules/admin-lte/dist/css/skins/*.*','public/css/skins')
.copy('node_modules/admin-lte/dist/img','public/img')
.copy('node_modules/admin-lte/plugins','public/plugins')
.copy('node_modules/icheck/skins/square/blue.png','public/css')
.copy('node_modules/icheck/skins/square/blue@2x.png','public/css')
.webpack('app.js');
}); });
...@@ -8,11 +8,17 @@ ...@@ -8,11 +8,17 @@
"bootstrap-sass": "^3.3.7", "bootstrap-sass": "^3.3.7",
"gulp": "^3.9.1", "gulp": "^3.9.1",
"jquery": "^3.1.0", "jquery": "^3.1.0",
"laravel-elixir": "^6.0.0-14", "laravel-elixir": "^6.0.0-9",
"laravel-elixir-vue-2": "^0.2.0", "laravel-elixir-vue-2": "^0.2.0",
"laravel-elixir-webpack-official": "^1.0.2", "laravel-elixir-webpack-official": "^1.0.2",
"lodash": "^4.16.2", "lodash": "^4.16.2",
"vue": "^2.0.1", "vue": "^2.0.1",
"vue-resource": "^1.0.3" "vue-resource": "^1.0.3",
"admin-lte": "^2.3.6",
"bootstrap-less": "^3.3.8",
"font-awesome": "^4.6.3",
"icheck": "^1.0.2",
"ionicons": "^3.0.0",
"toastr": "^2.1.2"
} }
} }
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
</testsuites> </testsuites>
<filter> <filter>
<whitelist processUncoveredFilesFromWhitelist="true"> <whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory> <directory suffix=".php">app/</directory>
</whitelist> </whitelist>
</filter> </filter>
<php> <php>
...@@ -23,5 +23,9 @@ ...@@ -23,5 +23,9 @@
<env name="CACHE_DRIVER" value="array"/> <env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/> <env name="QUEUE_DRIVER" value="sync"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="MAIL_DRIVER" value="log"/>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
</php> </php>
</phpunit> </phpunit>
<p align="center"><img src="https://laravel.com/assets/img/components/logo-laravel.svg"></p> # Laravel PHP Framework
<p align="center"> [![Build Status](https://travis-ci.org/laravel/framework.svg)](https://travis-ci.org/laravel/framework)
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a> [![Total Downloads](https://poser.pugx.org/laravel/framework/d/total.svg)](https://packagist.org/packages/laravel/framework)
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/d/total.svg" alt="Total Downloads"></a> [![Latest Stable Version](https://poser.pugx.org/laravel/framework/v/stable.svg)](https://packagist.org/packages/laravel/framework)
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/v/stable.svg" alt="Latest Stable Version"></a> [![Latest Unstable Version](https://poser.pugx.org/laravel/framework/v/unstable.svg)](https://packagist.org/packages/laravel/framework)
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/license.svg" alt="License"></a> [![License](https://poser.pugx.org/laravel/framework/license.svg)](https://packagist.org/packages/laravel/framework)
</p>
## About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as authentication, routing, sessions, queueing, and caching.
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as: Laravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb inversion of control container, expressive migration system, and tightly integrated unit testing support give you the tools you need to build any application with which you are tasked.
- [Simple, fast routing engine](https://laravel.com/docs/routing). ## Official Documentation
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb combination of simplicity, elegance, and innovation give you tools you need to build any application with which you are tasked. Documentation for the framework can be found on the [Laravel website](http://laravel.com/docs).
## Learning Laravel
Laravel has the most extensive and thorough documentation and video tutorial library of any modern web application framework. The [Laravel documentation](https://laravel.com/docs) is thorough, complete, and makes it a breeze to get started learning the framework.
If you're not in the mood to read, [Laracasts](https://laracasts.com) contains over 900 video tutorials on a range of topics including Laravel, modern PHP, unit testing, JavaScript, and more. Boost the skill level of yourself and your entire team by digging into our comprehensive video library.
## Contributing ## Contributing
......
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Login</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password" required>
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Login
</button>
<a class="btn btn-link" href="{{ url('/password/reset') }}">
Forgot Your Password?
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
@extends('layouts.app')
<!-- Main Content -->
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Reset Password</div>
<div class="panel-body">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<form class="form-horizontal" role="form" method="POST" action="{{ url('/password/email') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required>
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Send Password Reset Link
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Reset Password</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/password/reset') }}">
{{ csrf_field() }}
<input type="hidden" name="token" value="{{ $token }}">
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ $email or old('email') }}" required autofocus>
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password" required>
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
<label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
@if ($errors->has('password_confirmation'))
<span class="help-block">
<strong>{{ $errors->first('password_confirmation') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Reset Password
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Register</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/register') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="name" class="col-md-4 control-label">Name</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus>
@if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('name') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required>
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password" required>
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Register
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Dashboard</div>
<div class="panel-body">
You are logged in!
</div>
</div>
</div>
</div>
</div>
@endsection
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Styles -->
<link href="/css/app.css" rel="stylesheet">
<!-- Scripts -->
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
</head>
<body>
<div id="app">
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<!-- Collapsed Hamburger -->
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- Branding Image -->
<a class="navbar-brand" href="{{ url('/') }}">
{{ config('app.name', 'Laravel') }}
</a>
</div>
<div class="collapse navbar-collapse" id="app-navbar-collapse">
<!-- Left Side Of Navbar -->
<ul class="nav navbar-nav">
&nbsp;
</ul>
<!-- Right Side Of Navbar -->
<ul class="nav navbar-nav navbar-right">
<!-- Authentication Links -->
@if (Auth::guest())
<li><a href="{{ url('/login') }}">Login</a></li>
<li><a href="{{ url('/register') }}">Register</a></li>
@else
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
{{ Auth::user()->name }} <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li>
<a href="{{ url('/logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
Logout
</a>
<form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display: none;">
{{ csrf_field() }}
</form>
</li>
</ul>
</li>
@endif
</ul>
</div>
</div>
</nav>
@yield('content')
</div>
<!-- Scripts -->
<script src="/js/app.js"></script>
</body>
</html>
...@@ -9,15 +9,16 @@ ...@@ -9,15 +9,16 @@
</div> </div>
<div class="box-body"> <div class="box-body">
<div id="app"> <div id="app">
@if (count($errors) > 0) @if(count($errors))
<div class="alert alert-danger"> <div class="alert alert-danger">
<strong>Whoops!</strong> {{ trans('adminlte_lang::message.someproblems') }}<br><br> <strong>Whoops!</strong> There were some problems with your input.
<ul> <br/>
@foreach ($errors->all() as $error) <ul>
<li>{{ $error }}</li> @foreach($errors->all() as $error)
@endforeach <li>{{ $error }}</li>
</ul> @endforeach
</div> </ul>
</div>
@endif @endif
<div class="register-box-body "> <div class="register-box-body ">
<form action="{{ url('admin') }}" method="post"> <form action="{{ url('admin') }}" method="post">
......
...@@ -17,14 +17,14 @@ ...@@ -17,14 +17,14 @@
@endforeach @endforeach
</ul> </ul>
</div> </div>
@endif
@if(session()->has('message')) @if(session()->has('message'))
<div class="alert alert-info"> <div class="alert alert-info">
{{session()->get('message')}} {{session()->get('message')}}
</div> </div>
@endif @endif
@endif
</div> </div>
<div class="box-body"> <div class="box-body">
<form action="{{ url('reqFasilitas') }}" method="post" enctype="multipart/form-data" name="myForm" onsubmit="return(validate())"> <form action="{{ url('reqFasilitas') }}" method="post" enctype="multipart/form-data" name="myForm" onsubmit="return(validate())">
......
...@@ -10,9 +10,25 @@ ...@@ -10,9 +10,25 @@
<!-- //Banner --> <!-- //Banner -->
<!-- Booking --> <!-- Booking -->
<<<<<<< HEAD
<div class="details agileits w3layouts" style="margin-top: 30px; padding:0px"> <div class="details agileits w3layouts" style="margin-top: 30px; padding:0px">
=======
<div class="details agileits w3layouts" style="margin-top: 10px; padding:0px">
<br>
>>>>>>> abb3f8ad79338fdd1749e923bb009509d54fe16c
<div class="container"> <div class="container">
<br> @if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Whoops!</strong> {{ trans('adminlte_lang::message.someproblems') }}<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
</div>
<br><br>
<div class="col-md-12 col-sm-12 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft"> <div class="col-md-12 col-sm-12 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft">
<form action="{{url('book')}}" method="post"> <form action="{{url('book')}}" method="post">
...@@ -20,13 +36,13 @@ ...@@ -20,13 +36,13 @@
<input type="hidden" name="id" value="{{$data->id}}"> <input type="hidden" name="id" value="{{$data->id}}">
<div class="col-md-2 col-sm-2 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft"></div> <div class="col-md-2 col-sm-2 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft"></div>
<div class="col-md-3 col-sm-3 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft"> <div class="col-md-3 col-sm-3 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft">
<input class="date agileits w3layouts" id="datepicker1" name="tanggal" type="text" value=" Tanggal Check in" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = '';}" required=""> <input class="date agileits w3layouts" id="datepicker1" name="tanggal" type="text" value=" Tanggal Check in" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = '';}">
</div> </div>
<div class="col-md-2 col-sm-2 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft"> <div class="col-md-2 col-sm-2 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft">
<input type="text" class="text wow agileits w3layouts slideInLeft" name="jumlah_hari" placeholder="Lama Menginap" required="" style="background-color: white; color: black"> <input type="text" class="text wow agileits w3layouts slideInLeft" name="jumlah_hari" placeholder="Lama Menginap" style="background-color: white; color: black">
</div> </div>
<div class="col-md-2 col-sm-2 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft"> <div class="col-md-2 col-sm-2 agileits w3layouts contact-grid contact-grid-2 wow slideInLeft">
<input type="text" class="text wow agileits w3layouts slideInLeft" name="jumlah_kamar" placeholder="Jumlah Kamar" required="" style="background-color: white; color: black"> <input type="text" class="text wow agileits w3layouts slideInLeft" name="jumlah_kamar" placeholder="Jumlah Kamar" style="background-color: white; color: black">
</div> </div>
<div class="book"> <div class="book">
<input type="submit" class="more_btn wow agileits w3layouts slideInLeft" value="Book Now"> <input type="submit" class="more_btn wow agileits w3layouts slideInLeft" value="Book Now">
......
<?php
if (! empty($greeting)) {
echo $greeting, "\n\n";
} else {
echo $level == 'error' ? 'Whoops!' : 'Hello!', "\n\n";
}
if (! empty($introLines)) {
echo implode("\n", $introLines), "\n\n";
}
if (isset($actionText)) {
echo "{$actionText}: {$actionUrl}", "\n\n";
}
if (! empty($outroLines)) {
echo implode("\n", $outroLines), "\n\n";
}
echo 'Regards,', "\n";
echo config('app.name'), "\n";
@if ($paginator->hasPages())
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled"><span class="page-link">&laquo;</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">&laquo;</a></li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="page-item disabled"><span class="page-link">{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="page-item active"><span class="page-link">{{ $page }}</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item"><a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">&raquo;</a></li>
@else
<li class="page-item disabled"><span class="page-link">&raquo;</span></li>
@endif
</ul>
@endif
@if ($paginator->hasPages())
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled"><span>&laquo;</span></li>
@else
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">&laquo;</a></li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="disabled"><span>{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="active"><span>{{ $page }}</span></li>
@else
<li><a href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">&raquo;</a></li>
@else
<li class="disabled"><span>&raquo;</span></li>
@endif
</ul>
@endif
@if ($paginator->hasPages())
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled"><span class="page-link">&laquo;</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">&laquo;</a></li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item"><a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">&raquo;</a></li>
@else
<li class="page-item disabled"><span class="page-link">&raquo;</span></li>
@endif
</ul>
@endif
@if ($paginator->hasPages())
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled"><span>&laquo;</span></li>
@else
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">&laquo;</a></li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">&raquo;</a></li>
@else
<li class="disabled"><span>&raquo;</span></li>
@endif
</ul>
@endif
...@@ -18,30 +18,30 @@ Route::get('/', function () { ...@@ -18,30 +18,30 @@ Route::get('/', function () {
}); });
Route::get('test', function(){ Route::get('test', function(){
return view('index'); return view('index');
}); });
//test saja //test saja
Route::get('editprofiles', function(){ Route::get('editprofiles', function(){
return view('editprofiles'); return view('editprofiles');
}); });
//web //web
Route::get('history', function(){ Route::get('history', function(){
return view('History'); return view('History');
}); });
Route::get('profiles', function(){ Route::get('profiles', function(){
return view('profiles'); return view('profiles');
}); });
Route::group(['middleware' => 'auth'], function () { Route::group(['middleware' => 'auth'], function () {
}); });
Route::get('adminlte', function(){ Route::get('adminlte', function(){
return view('welcome'); return view('welcome');
}); });
//Coba cart //Coba cart
...@@ -49,61 +49,78 @@ Route::get('chartjs', 'OwnerController@chartjs'); ...@@ -49,61 +49,78 @@ Route::get('chartjs', 'OwnerController@chartjs');
// //
Route::get('AddBook', function(){ Route::get('AddBook', function(){
return view('adminlte::layouts.owner.AddBookManual'); return view('adminlte::layouts.owner.AddBookManual');
}); });
Route::get('DataPemesanan', function(){ Route::get('DataPemesanan', function(){
return view('adminlte::layouts.admin.dataPemesanan'); return view('adminlte::layouts.admin.dataPemesanan');
}); });
Route::post('feedback/{id}','CustomerController@sendFeedback'); Route::group(['middleware' => 'owner'], function () {
Route::get('listPemesanan','AdminController@listPesanan'); Route::put('editRoom/{id}','OwnerController@updateRoom');
Route::put('editRoom/{id}','OwnerController@updateRoom'); Route::post('addManual','OwnerController@addBookManual');
Route::post('addManual','OwnerController@addBookManual'); Route::put('konfirmasiPemesanan/{id}','OwnerController@konfirmasiPemesanan');
Route::get('editRoom/{id}','OwnerController@editRoom') ;
Route::put('konfirmasiPemesanan/{id}','OwnerController@konfirmasiPemesanan'); Route::get('daftarBooking','OwnerController@listOfBook');
Route::get('editRoom/{id}','OwnerController@editRoom') ; Route::get('daftarKamar','OwnerController@daftarKamar');
Route::get('daftarBooking','OwnerController@listOfBook'); Route::get('pesanan','OwnerController@listTransaction');
Route::get('daftarKamar','OwnerController@daftarKamar'); Route::get('reqFasilitas','OwnerController@requestFasilitas');
Route::get('pesanan','OwnerController@listTransaction'); Route::post('reqFasilitas','OwnerController@storeRequest');
Route::put('upload/{id}','CustomerController@upload'); Route::get('updateHomestay','OwnerController@update');
Route::get('detailhomestay/{id}','CustomerController@detailhomestay'); Route::put('updateHomestay/{id}','OwnerController@updateHomestay');
Route::get('customerHistory','CustomerController@history'); Route::delete('batalkanPemesanan/{id}','CustomerController@cancelPemesanan');
Route::get('daftar','CustomerController@register'); Route::get('profile','OwnerController@profile');
Route::post('daftar','CustomerController@registerStore'); Route::get('profiledit/{id}','OwnerController@profileEdit');
Route::post('book','CustomerController@booking'); Route::put('profileupdate/{id}','OwnerController@updateProfil');
Route::get('buktipembayaran/{id}','CustomerController@bukti'); route::get('profile','OwnerController@profile');
Route::get('editProfileCustomer/{id}','CustomerController@editProfile'); Route::get('profile/{id}/profiledit','OwnerController@editProfile');
Route::put('editProfileCustomer/{id}','CustomerController@updateProfile'); Route::get('profileUpdate/{id}','OwnerController@updatePro');
Route::resource('admin', 'AdminController'); Route::resource('owner','OwnerController');
Route::get('listowner','AdminController@listOwner'); Route::get('pengajuanHomestay','OwnerController@pengajuan');
Route::resource('owner','OwnerController'); Route::post('pengajuanHomestay','OwnerController@storePengajuan');
Route::get('customerProfile','CustomerController@profile'); Route::get('listPengajuan','OwnerController@listPengajuan');
route::get('profile','OwnerController@profile'); Route::get('listPengajuanFasilitas','OwnerController@listPengajuanFasilitas');
Route::get('profile/{id}/profiledit','OwnerController@editProfile'); Route::get('listFeedback','OwnerController@feddback');
Route::get('profileUpdate/{id}','OwnerController@updatePro'); });
Route::get('requestHomestay','AdminController@RequestHomestay');
Route::get('requestFasilitas','AdminController@RequestFasilitas'); Route::get('detailhomestay/{id}','CobaController@detailhomestay');
Route::get('pengajuanHomestay','OwnerController@pengajuan');
Route::post('pengajuanHomestay','OwnerController@storePengajuan'); Route::group(['middleware' => 'customer'], function () {
Route::get('listPengajuan','OwnerController@listPengajuan'); Route::put('upload/{id}','CustomerController@upload');
Route::get('listPengajuanFasilitas','OwnerController@listPengajuanFasilitas'); Route::get('customerHistory','CustomerController@history');
Route::put('requestFasilitas/{id}','AdminController@UpdateRequestFasilitas'); Route::get('daftar','CustomerController@register');
Route::put('requestFasilitass/{id}','AdminController@UpdateRequestFasilitass'); Route::post('daftar','CustomerController@registerStore');
Route::put('listPengajuanHomestay/{id}','AdminController@AccPengajuanHomestay'); Route::post('book','CustomerController@booking');
Route::get('buktipembayaran/{id}','CustomerController@bukti');
Route::get('editProfileCustomer/{id}','CustomerController@editProfile');
Route::get('reqFasilitas','OwnerController@requestFasilitas'); Route::put('editProfileCustomer/{id}','CustomerController@updateProfile');
Route::post('reqFasilitas','OwnerController@storeRequest'); Route::get('customerProfile','CustomerController@profile');
Route::get('updateHomestay','OwnerController@update'); Route::post('feedback/{id}','CustomerController@sendFeedback');
Route::put('updateHomestay/{id}','OwnerController@updateHomestay'); });
Route::delete('batalkanPemesanan/{id}','CustomerController@cancelPemesanan');
Route::get('profile','OwnerController@profile');
Route::get('profiledit/{id}','OwnerController@profileEdit'); Route::group(['middleware' => 'dinaspariwisata'], function () {
Route::put('profileupdate/{id}','OwnerController@updateProfil'); Route::resource('admin', 'AdminController');
Route::get('listowner','AdminController@listOwner');
Route::get('listPemesanan','AdminController@listPesanan');
Route::get('requestHomestay','AdminController@RequestHomestay');
Route::get('requestFasilitas','AdminController@RequestFasilitas');
Route::put('requestFasilitas/{id}','AdminController@UpdateRequestFasilitas');
Route::put('requestFasilitass/{id}','AdminController@UpdateRequestFasilitass');
Route::put('listPengajuanHomestay/{id}','AdminController@AccPengajuanHomestay');
});
/*Route::get('UpdateHomestay', function(){ /*Route::get('UpdateHomestay', function(){
return view('adminlte::layouts.owner.UpdateHomestay'); return view('adminlte::layouts.owner.UpdateHomestay');
});*/ });*/
Route::get('listFeedback','OwnerController@feddback');
...@@ -1112,7 +1112,7 @@ img { ...@@ -1112,7 +1112,7 @@ img {
height: auto; height: auto;
} }
.img-circle { .img-circle {
border-radius: 30%; border-radius: 50%;
} }
hr { hr {
margin-top: 20px; margin-top: 20px;
......
...@@ -127,15 +127,4 @@ return [ ...@@ -127,15 +127,4 @@ return [
'password' => 'Password', 'password' => 'Password',
'retrypepassword' => 'Retype password', 'retrypepassword' => 'Retype password',
'fullname' => 'Full Name', 'fullname' => 'Full Name',
'username' => 'Username',
'addOwner' => 'Add Owner Homestay',
'homestay' => 'Homestay',
'role' => 'Role',
'username' => 'Username',
'listOwner' => 'List Owner',
'profile' => 'Profile',
'namaHomestay' => 'Nama Homestay',
'addRoom' => 'Tambah Kamar',
]; ];
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
</div> </div>
</form> </form>
@include('adminlte::auth.partials.social_login')
<a href="{{ url('/password/reset') }}">{{ trans('adminlte_lang::message.forgotpassword') }}</a><br> <a href="{{ url('/password/reset') }}">{{ trans('adminlte_lang::message.forgotpassword') }}</a><br>
<a href="{{ url('/register') }}" class="text-center">{{ trans('adminlte_lang::message.registermember') }}</a> <a href="{{ url('/register') }}" class="text-center">{{ trans('adminlte_lang::message.registermember') }}</a>
......
...@@ -11,13 +11,13 @@ return array( ...@@ -11,13 +11,13 @@ return array(
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php', '2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php', '5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php', 'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'e7223560d890eab89cda23685e711e2c' => $vendorDir . '/psy/psysh/src/Psy/functions.php', 'e7223560d890eab89cda23685e711e2c' => $vendorDir . '/psy/psysh/src/Psy/functions.php',
'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php', 'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php', '58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'bccfaf6207f67190a92f35585e9a78b2' => $vendorDir . '/twilio/sdk/Services/Twilio.php', 'bccfaf6207f67190a92f35585e9a78b2' => $vendorDir . '/twilio/sdk/Services/Twilio.php',
'a1944ad99b2c9dde1f8975eab6b29a40' => $vendorDir . '/acacha/helpers/src/helpers.php', 'a1944ad99b2c9dde1f8975eab6b29a40' => $vendorDir . '/acacha/helpers/src/helpers.php',
); );
...@@ -7,6 +7,7 @@ $baseDir = dirname($vendorDir); ...@@ -7,6 +7,7 @@ $baseDir = dirname($vendorDir);
return array( return array(
'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'), 'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'),
'Zend\\Diactoros\\' => array($vendorDir . '/zendframework/zend-diactoros/src'),
'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'), 'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
'Symfony\\Polyfill\\Util\\' => array($vendorDir . '/symfony/polyfill-util'), 'Symfony\\Polyfill\\Util\\' => array($vendorDir . '/symfony/polyfill-util'),
...@@ -31,9 +32,15 @@ return array( ...@@ -31,9 +32,15 @@ return array(
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'), 'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
'Nexmo\\Laravel\\' => array($vendorDir . '/nexmo/laravel/src'),
'Nexmo\\' => array($vendorDir . '/nexmo/client/src'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'), 'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
'Lcobucci\\JWT\\' => array($vendorDir . '/lcobucci/jwt/src'),
'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'), 'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'),
'Http\\Promise\\' => array($vendorDir . '/php-http/promise/src'),
'Http\\Client\\' => array($vendorDir . '/php-http/httplug/src'),
'Http\\Adapter\\Guzzle6\\' => array($vendorDir . '/php-http/guzzle6-adapter/src'),
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
......
# CHANGELOG # CHANGELOG
## 1.4.2 - 2017-03-20
* Reverted BC break to `Uri::resolve` and `Uri::removeDotSegments` by removing
calls to `trigger_error` when deprecated methods are invoked.
## 1.4.1 - 2017-02-27 ## 1.4.1 - 2017-02-27
* Reverted BC break by reintroducing behavior to automagically fix a URI with a * Reverted BC break by reintroducing behavior to automagically fix a URI with a
......
...@@ -265,6 +265,12 @@ class Uri implements UriInterface ...@@ -265,6 +265,12 @@ class Uri implements UriInterface
*/ */
public static function removeDotSegments($path) public static function removeDotSegments($path)
{ {
@trigger_error(
'GuzzleHttp\Psr7\Uri::removeDotSegments is deprecated since version 1.4. ' .
'Use GuzzleHttp\Psr7\UriResolver::removeDotSegments instead.',
E_USER_DEPRECATED
);
return UriResolver::removeDotSegments($path); return UriResolver::removeDotSegments($path);
} }
...@@ -281,6 +287,11 @@ class Uri implements UriInterface ...@@ -281,6 +287,11 @@ class Uri implements UriInterface
*/ */
public static function resolve(UriInterface $base, $rel) public static function resolve(UriInterface $base, $rel)
{ {
@trigger_error(
'GuzzleHttp\Psr7\Uri::resolve is deprecated since version 1.4. Use GuzzleHttp\Psr7\UriResolver::resolve instead.',
E_USER_DEPRECATED
);
if (!($rel instanceof UriInterface)) { if (!($rel instanceof UriInterface)) {
$rel = new self($rel); $rel = new self($rel);
} }
......
build:
environment:
mysql: false
postgresql: false
redis: false
rabbitmq: false
php:
version: 5.6
tools:
php_sim: true
php_pdepend: true
php_analyzer: true
php_changetracking: true
php_code_sniffer:
config:
standard: "PSR2"
php_mess_detector: true
checks:
php:
code_rating: true
duplication: true
argument_type_checks: true
assignment_of_null_return: true
avoid_conflicting_incrementers: true
avoid_useless_overridden_methods: true
catch_class_exists: true
closure_use_modifiable: true
closure_use_not_conflicting: true
deprecated_code_usage: true
method_calls_on_non_object: true
missing_arguments: true
no_duplicate_arguments: true
no_non_implemented_abstract_methods: true
no_property_on_interface: true
parameter_non_unique: true
precedence_in_conditions: true
precedence_mistakes: true
require_php_tag_first: true
security_vulnerabilities: true
sql_injection_vulnerabilities: true
too_many_arguments: true
unreachable_code: true
unused_methods: true
unused_parameters: true
unused_properties: true
unused_variables: true
use_statement_alias_conflict: true
useless_calls: true
variable_existence: true
verify_access_scope_valid: true
verify_argument_usable_as_reference: true
verify_property_names: true
filter:
excluded_paths:
- test/*
language: php
php:
- 5.5
- 5.6
- 7.0
- hhvm
- hhvm-nightly
matrix:
allow_failures:
- php: hhvm-nightly
before_script:
- composer selfupdate
- composer install --prefer-dist -o
Copyright (c) 2014-2015, Luís Otávio Cobucci Oblonczyk
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the {organization} nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# JWT
[![Gitter](https://img.shields.io/badge/GITTER-JOIN%20CHAT%20%E2%86%92-brightgreen.svg?style=flat-square)](https://gitter.im/lcobucci/jwt?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Total Downloads](https://img.shields.io/packagist/dt/lcobucci/jwt.svg?style=flat-square)](https://packagist.org/packages/lcobucci/jwt) [![Latest Stable Version](https://img.shields.io/packagist/v/lcobucci/jwt.svg?style=flat-square)](https://packagist.org/packages/lcobucci/jwt)
![Branch master](https://img.shields.io/badge/branch-master-brightgreen.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/lcobucci/jwt/master.svg?style=flat-square)](http://travis-ci.org/#!/lcobucci/jwt)
[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/lcobucci/jwt/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/lcobucci/jwt/?branch=master)
[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/lcobucci/jwt/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/lcobucci/jwt/?branch=master)
A simple library to work with JSON Web Token and JSON Web Signature (requires PHP 5.5+).
The implementation is based on the [current draft](http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32).
## Installation
Package is available on [Packagist](http://packagist.org/packages/lcobucci/jwt),
you can install it using [Composer](http://getcomposer.org).
```shell
composer require lcobucci/jwt
```
### Dependencies
- PHP 5.5+
- OpenSSL Extension
## Basic usage
### Creating
Just use the builder to create a new JWT/JWS tokens:
```php
use Lcobucci\JWT\Builder;
$token = (new Builder())->setIssuer('http://example.com') // Configures the issuer (iss claim)
->setAudience('http://example.org') // Configures the audience (aud claim)
->setId('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
->setIssuedAt(time()) // Configures the time that the token was issue (iat claim)
->setNotBefore(time() + 60) // Configures the time that the token can be used (nbf claim)
->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim)
->set('uid', 1) // Configures a new claim, called "uid"
->getToken(); // Retrieves the generated token
$token->getHeaders(); // Retrieves the token headers
$token->getClaims(); // Retrieves the token claims
echo $token->getHeader('jti'); // will print "4f1g23a12aa"
echo $token->getClaim('iss'); // will print "http://example.com"
echo $token->getClaim('uid'); // will print "1"
echo $token; // The string representation of the object is a JWT string (pretty easy, right?)
```
### Parsing from strings
Use the parser to create a new token from a JWT string (using the previous token as example):
```php
use Lcobucci\JWT\Parser;
$token = (new Parser())->parse((string) $token); // Parses from a string
$token->getHeaders(); // Retrieves the token header
$token->getClaims(); // Retrieves the token claims
echo $token->getHeader('jti'); // will print "4f1g23a12aa"
echo $token->getClaim('iss'); // will print "http://example.com"
echo $token->getClaim('uid'); // will print "1"
```
### Validating
We can easily validate if the token is valid (using the previous token as example):
```php
use Lcobucci\JWT\ValidationData;
$data = new ValidationData(); // It will use the current time to validate (iat, nbf and exp)
$data->setIssuer('http://example.com');
$data->setAudience('http://example.org');
$data->setId('4f1g23a12aa');
var_dump($token->validate($data)); // false, because we created a token that cannot be used before of `time() + 60`
$data->setCurrentTime(time() + 60); // changing the validation time to future
var_dump($token->validate($data)); // true, because validation information is equals to data contained on the token
$data->setCurrentTime(time() + 4000); // changing the validation time to future
var_dump($token->validate($data)); // false, because token is expired since current time is greater than exp
```
## Token signature
We can use signatures to be able to verify if the token was not modified after its generation. This library implements Hmac, RSA and ECDSA signatures (using 256, 384 and 512).
### Hmac
Hmac signatures are really simple to be used:
```php
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;
$signer = new Sha256();
$token = (new Builder())->setIssuer('http://example.com') // Configures the issuer (iss claim)
->setAudience('http://example.org') // Configures the audience (aud claim)
->setId('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
->setIssuedAt(time()) // Configures the time that the token was issue (iat claim)
->setNotBefore(time() + 60) // Configures the time that the token can be used (nbf claim)
->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim)
->set('uid', 1) // Configures a new claim, called "uid"
->sign($signer, 'testing') // creates a signature using "testing" as key
->getToken(); // Retrieves the generated token
var_dump($token->verify($signer, 'testing 1')); // false, because the key is different
var_dump($token->verify($signer, 'testing')); // true, because the key is the same
```
### RSA and ECDSA
RSA and ECDSA signatures are based on public and private keys so you have to generate using the private key and verify using the public key:
```php
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Keychain; // just to make our life simpler
use Lcobucci\JWT\Signer\Rsa\Sha256; // you can use Lcobucci\JWT\Signer\Ecdsa\Sha256 if you're using ECDSA keys
$signer = new Sha256();
$keychain = new Keychain();
$token = (new Builder())->setIssuer('http://example.com') // Configures the issuer (iss claim)
->setAudience('http://example.org') // Configures the audience (aud claim)
->setId('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
->setIssuedAt(time()) // Configures the time that the token was issue (iat claim)
->setNotBefore(time() + 60) // Configures the time that the token can be used (nbf claim)
->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim)
->set('uid', 1) // Configures a new claim, called "uid"
->sign($signer, $keychain->getPrivateKey('file://{path to your private key}')) // creates a signature using your private key
->getToken(); // Retrieves the generated token
var_dump($token->verify($signer, $keychain->getPublicKey('file://{path to your public key}')); // true when the public key was generated by the private one =)
```
**It's important to say that if you're using RSA keys you shouldn't invoke ECDSA signers (and vice-versa), otherwise ```sign()``` and ```verify()``` will raise an exception!**
{
"name": "lcobucci/jwt",
"description": "A simple library to work with JSON Web Token and JSON Web Signature",
"type": "library",
"authors": [
{
"name": "Luís Otávio Cobucci Oblonczyk",
"email": "lcobucci@gmail.com",
"role": "Developer"
}
],
"keywords": [
"JWT",
"JWS"
],
"license": [
"BSD-3-Clause"
],
"require": {
"php": ">=5.5",
"ext-openssl": "*"
},
"require-dev": {
"phpunit/phpunit": "~4.5",
"squizlabs/php_codesniffer": "~2.3",
"phpmd/phpmd": "~2.2",
"phpunit/php-invoker": "~1.1",
"mikey179/vfsStream": "~1.5",
"mdanter/ecc": "~0.3.1"
},
"suggest":{
"mdanter/ecc": "Required to use Elliptic Curves based algorithms."
},
"autoload": {
"psr-4": {
"Lcobucci\\JWT\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Lcobucci\\JWT\\": [
"test/unit",
"test/functional"
]
}
},
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
verbose="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestSize="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutTodoAnnotatedTests="true"
checkForUnintentionallyCoveredCode="true"
forceCoversAnnotation="true">
<testsuites>
<testsuite name="Unit Test Suite">
<directory>test/unit</directory>
</testsuite>
<testsuite name="Integration Test Suite">
<directory>test/functional</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
<blacklist>
<directory suffix=".php">vendor</directory>
</blacklist>
</filter>
</phpunit>
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT;
use BadMethodCallException;
use Lcobucci\JWT\Claim\Factory as ClaimFactory;
use Lcobucci\JWT\Parsing\Encoder;
/**
* This class makes easier the token creation process
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
class Builder
{
/**
* The token header
*
* @var array
*/
private $headers;
/**
* The token claim set
*
* @var array
*/
private $claims;
/**
* The token signature
*
* @var Signature
*/
private $signature;
/**
* The data encoder
*
* @var Encoder
*/
private $encoder;
/**
* The factory of claims
*
* @var ClaimFactory
*/
private $claimFactory;
/**
* Initializes a new builder
*
* @param Encoder $encoder
* @param ClaimFactory $claimFactory
*/
public function __construct(
Encoder $encoder = null,
ClaimFactory $claimFactory = null
) {
$this->encoder = $encoder ?: new Encoder();
$this->claimFactory = $claimFactory ?: new ClaimFactory();
$this->headers = ['typ'=> 'JWT', 'alg' => 'none'];
$this->claims = [];
}
/**
* Configures the audience
*
* @param string $audience
* @param boolean $replicateAsHeader
*
* @return Builder
*/
public function setAudience($audience, $replicateAsHeader = false)
{
return $this->setRegisteredClaim('aud', (string) $audience, $replicateAsHeader);
}
/**
* Configures the expiration time
*
* @param int $expiration
* @param boolean $replicateAsHeader
*
* @return Builder
*/
public function setExpiration($expiration, $replicateAsHeader = false)
{
return $this->setRegisteredClaim('exp', (int) $expiration, $replicateAsHeader);
}
/**
* Configures the token id
*
* @param string $id
* @param boolean $replicateAsHeader
*
* @return Builder
*/
public function setId($id, $replicateAsHeader = false)
{
return $this->setRegisteredClaim('jti', (string) $id, $replicateAsHeader);
}
/**
* Configures the time that the token was issued
*
* @param int $issuedAt
* @param boolean $replicateAsHeader
*
* @return Builder
*/
public function setIssuedAt($issuedAt, $replicateAsHeader = false)
{
return $this->setRegisteredClaim('iat', (int) $issuedAt, $replicateAsHeader);
}
/**
* Configures the issuer
*
* @param string $issuer
* @param boolean $replicateAsHeader
*
* @return Builder
*/
public function setIssuer($issuer, $replicateAsHeader = false)
{
return $this->setRegisteredClaim('iss', (string) $issuer, $replicateAsHeader);
}
/**
* Configures the time before which the token cannot be accepted
*
* @param int $notBefore
* @param boolean $replicateAsHeader
*
* @return Builder
*/
public function setNotBefore($notBefore, $replicateAsHeader = false)
{
return $this->setRegisteredClaim('nbf', (int) $notBefore, $replicateAsHeader);
}
/**
* Configures the subject
*
* @param string $subject
* @param boolean $replicateAsHeader
*
* @return Builder
*/
public function setSubject($subject, $replicateAsHeader = false)
{
return $this->setRegisteredClaim('sub', (string) $subject, $replicateAsHeader);
}
/**
* Configures a registed claim
*
* @param string $name
* @param mixed $value
* @param boolean $replicate
*
* @return Builder
*/
protected function setRegisteredClaim($name, $value, $replicate)
{
$this->set($name, $value);
if ($replicate) {
$this->headers[$name] = $this->claims[$name];
}
return $this;
}
/**
* Configures a header item
*
* @param string $name
* @param mixed $value
*
* @return Builder
*
* @throws BadMethodCallException When data has been already signed
*/
public function setHeader($name, $value)
{
if ($this->signature) {
throw new BadMethodCallException('You must unsign before make changes');
}
$this->headers[(string) $name] = $this->claimFactory->create($name, $value);
return $this;
}
/**
* Configures a claim item
*
* @param string $name
* @param mixed $value
*
* @return Builder
*
* @throws BadMethodCallException When data has been already signed
*/
public function set($name, $value)
{
if ($this->signature) {
throw new BadMethodCallException('You must unsign before making changes');
}
$this->claims[(string) $name] = $this->claimFactory->create($name, $value);
return $this;
}
/**
* Signs the data
*
* @param Signer $signer
* @param string $key
*
* @return Builder
*/
public function sign(Signer $signer, $key)
{
$signer->modifyHeader($this->headers);
$this->signature = $signer->sign(
$this->getToken()->getPayload(),
$key
);
return $this;
}
/**
* Removes the signature from the builder
*
* @return Builder
*/
public function unsign()
{
$this->signature = null;
return $this;
}
/**
* Returns the resultant token
*
* @return Token
*/
public function getToken()
{
$payload = [
$this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->headers)),
$this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->claims))
];
if ($this->signature !== null) {
$payload[] = $this->encoder->base64UrlEncode($this->signature);
}
return new Token($this->headers, $this->claims, $this->signature, $payload);
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT;
use JsonSerializable;
/**
* Basic interface for token claims
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.0.0
*/
interface Claim extends JsonSerializable
{
/**
* Returns the claim name
*
* @return string
*/
public function getName();
/**
* Returns the claim value
*
* @return string
*/
public function getValue();
/**
* Returns the string representation of the claim
*
* @return string
*/
public function __toString();
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Claim;
use Lcobucci\JWT\Claim;
/**
* The default claim
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.0.0
*/
class Basic implements Claim
{
/**
* @var string
*/
private $name;
/**
* @var mixed
*/
private $value;
/**
* Initializes the claim
*
* @param string $name
* @param mixed $value
*/
public function __construct($name, $value)
{
$this->name = $name;
$this->value = $value;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->name;
}
/**
* {@inheritdoc}
*/
public function getValue()
{
return $this->value;
}
/**
* {@inheritdoc}
*/
public function jsonSerialize()
{
return $this->value;
}
/**
* {@inheritdoc}
*/
public function __toString()
{
return (string) $this->value;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Claim;
use Lcobucci\JWT\Claim;
use Lcobucci\JWT\ValidationData;
/**
* Validatable claim that checks if value is strictly equals to the given data
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.0.0
*/
class EqualsTo extends Basic implements Claim, Validatable
{
/**
* {@inheritdoc}
*/
public function validate(ValidationData $data)
{
if ($data->has($this->getName())) {
return $this->getValue() === $data->get($this->getName());
}
return true;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Claim;
use Lcobucci\JWT\Claim;
/**
* Class that create claims
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.0.0
*/
class Factory
{
/**
* The list of claim callbacks
*
* @var array
*/
private $callbacks;
/**
* Initializes the factory, registering the default callbacks
*
* @param array $callbacks
*/
public function __construct(array $callbacks = [])
{
$this->callbacks = array_merge(
[
'iat' => [$this, 'createLesserOrEqualsTo'],
'nbf' => [$this, 'createLesserOrEqualsTo'],
'exp' => [$this, 'createGreaterOrEqualsTo'],
'iss' => [$this, 'createEqualsTo'],
'aud' => [$this, 'createEqualsTo'],
'sub' => [$this, 'createEqualsTo'],
'jti' => [$this, 'createEqualsTo']
],
$callbacks
);
}
/**
* Create a new claim
*
* @param string $name
* @param mixed $value
*
* @return Claim
*/
public function create($name, $value)
{
if (!empty($this->callbacks[$name])) {
return call_user_func($this->callbacks[$name], $name, $value);
}
return $this->createBasic($name, $value);
}
/**
* Creates a claim that can be compared (greator or equals)
*
* @param string $name
* @param mixed $value
*
* @return GreaterOrEqualsTo
*/
private function createGreaterOrEqualsTo($name, $value)
{
return new GreaterOrEqualsTo($name, $value);
}
/**
* Creates a claim that can be compared (greator or equals)
*
* @param string $name
* @param mixed $value
*
* @return LesserOrEqualsTo
*/
private function createLesserOrEqualsTo($name, $value)
{
return new LesserOrEqualsTo($name, $value);
}
/**
* Creates a claim that can be compared (equals)
*
* @param string $name
* @param mixed $value
*
* @return EqualsTo
*/
private function createEqualsTo($name, $value)
{
return new EqualsTo($name, $value);
}
/**
* Creates a basic claim
*
* @param string $name
* @param mixed $value
*
* @return Basic
*/
private function createBasic($name, $value)
{
return new Basic($name, $value);
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Claim;
use Lcobucci\JWT\Claim;
use Lcobucci\JWT\ValidationData;
/**
* Validatable claim that checks if value is greater or equals the given data
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.0.0
*/
class GreaterOrEqualsTo extends Basic implements Claim, Validatable
{
/**
* {@inheritdoc}
*/
public function validate(ValidationData $data)
{
if ($data->has($this->getName())) {
return $this->getValue() >= $data->get($this->getName());
}
return true;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Claim;
use Lcobucci\JWT\Claim;
use Lcobucci\JWT\ValidationData;
/**
* Validatable claim that checks if value is lesser or equals to the given data
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.0.0
*/
class LesserOrEqualsTo extends Basic implements Claim, Validatable
{
/**
* {@inheritdoc}
*/
public function validate(ValidationData $data)
{
if ($data->has($this->getName())) {
return $this->getValue() <= $data->get($this->getName());
}
return true;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Claim;
use Lcobucci\JWT\ValidationData;
/**
* Basic interface for validatable token claims
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.0.0
*/
interface Validatable
{
/**
* Returns if claim is valid according with given data
*
* @param ValidationData $data
*
* @return boolean
*/
public function validate(ValidationData $data);
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT;
use InvalidArgumentException;
use Lcobucci\JWT\Claim\Factory as ClaimFactory;
use Lcobucci\JWT\Parsing\Decoder;
/**
* This class parses the JWT strings and convert them into tokens
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
class Parser
{
/**
* The data decoder
*
* @var Decoder
*/
private $decoder;
/**
* The claims factory
*
* @var ClaimFactory
*/
private $claimFactory;
/**
* Initializes the object
*
* @param Decoder $decoder
* @param ClaimFactory $claimFactory
*/
public function __construct(
Decoder $decoder = null,
ClaimFactory $claimFactory = null
) {
$this->decoder = $decoder ?: new Decoder();
$this->claimFactory = $claimFactory ?: new ClaimFactory();
}
/**
* Parses the JWT and returns a token
*
* @param string $jwt
*
* @return Token
*/
public function parse($jwt)
{
$data = $this->splitJwt($jwt);
$header = $this->parseHeader($data[0]);
$claims = $this->parseClaims($data[1]);
$signature = $this->parseSignature($header, $data[2]);
foreach ($claims as $name => $value) {
if (isset($header[$name])) {
$header[$name] = $value;
}
}
if ($signature === null) {
unset($data[2]);
}
return new Token($header, $claims, $signature, $data);
}
/**
* Splits the JWT string into an array
*
* @param string $jwt
*
* @return array
*
* @throws InvalidArgumentException When JWT is not a string or is invalid
*/
protected function splitJwt($jwt)
{
if (!is_string($jwt)) {
throw new InvalidArgumentException('The JWT string must have two dots');
}
$data = explode('.', $jwt);
if (count($data) != 3) {
throw new InvalidArgumentException('The JWT string must have two dots');
}
return $data;
}
/**
* Parses the header from a string
*
* @param string $data
*
* @return array
*
* @throws InvalidArgumentException When an invalid header is informed
*/
protected function parseHeader($data)
{
$header = (array) $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data));
if (isset($header['enc'])) {
throw new InvalidArgumentException('Encryption is not supported yet');
}
return $header;
}
/**
* Parses the claim set from a string
*
* @param string $data
*
* @return array
*/
protected function parseClaims($data)
{
$claims = (array) $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data));
foreach ($claims as $name => &$value) {
$value = $this->claimFactory->create($name, $value);
}
return $claims;
}
/**
* Returns the signature from given data
*
* @param array $header
* @param string $data
*
* @return Signature
*/
protected function parseSignature(array $header, $data)
{
if ($data == '' || !isset($header['alg']) || $header['alg'] == 'none') {
return null;
}
$hash = $this->decoder->base64UrlDecode($data);
return new Signature($hash);
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Parsing;
use RuntimeException;
/**
* Class that decodes data according with the specs of RFC-4648
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*
* @link http://tools.ietf.org/html/rfc4648#section-5
*/
class Decoder
{
/**
* Decodes from JSON, validating the errors (will return an associative array
* instead of objects)
*
* @param string $json
* @return mixed
*
* @throws RuntimeException When something goes wrong while decoding
*/
public function jsonDecode($json)
{
$data = json_decode($json);
if (json_last_error() != JSON_ERROR_NONE) {
throw new RuntimeException('Error while decoding to JSON: ' . json_last_error_msg());
}
return $data;
}
/**
* Decodes from base64url
*
* @param string $data
* @return string
*/
public function base64UrlDecode($data)
{
if ($remainder = strlen($data) % 4) {
$data .= str_repeat('=', 4 - $remainder);
}
return base64_decode(strtr($data, '-_', '+/'));
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Parsing;
use RuntimeException;
/**
* Class that encodes data according with the specs of RFC-4648
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*
* @link http://tools.ietf.org/html/rfc4648#section-5
*/
class Encoder
{
/**
* Encodes to JSON, validating the errors
*
* @param mixed $data
* @return string
*
* @throws RuntimeException When something goes wrong while encoding
*/
public function jsonEncode($data)
{
$json = json_encode($data);
if (json_last_error() != JSON_ERROR_NONE) {
throw new RuntimeException('Error while encoding to JSON: ' . json_last_error_msg());
}
return $json;
}
/**
* Encodes to base64url
*
* @param string $data
* @return string
*/
public function base64UrlEncode($data)
{
return str_replace('=', '', strtr(base64_encode($data), '+/', '-_'));
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT;
/**
* This class represents a token signature
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
class Signature
{
/**
* The resultant hash
*
* @var string
*/
protected $hash;
/**
* Initializes the object
*
* @param string $hash
*/
public function __construct($hash)
{
$this->hash = $hash;
}
/**
* Verifies if the current hash matches with with the result of the creation of
* a new signature with given data
*
* @param Signer $signer
* @param string $payload
* @param string $key
*
* @return boolean
*/
public function verify(Signer $signer, $payload, $key)
{
return $signer->verify($this->hash, $payload, $key);
}
/**
* Returns the current hash as a string representation of the signature
*
* @return string
*/
public function __toString()
{
return $this->hash;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT;
use InvalidArgumentException;
use Lcobucci\JWT\Signer\Key;
/**
* Basic interface for token signers
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
interface Signer
{
/**
* Returns the algorithm id
*
* @return string
*/
public function getAlgorithmId();
/**
* Apply changes on headers according with algorithm
*
* @param array $headers
*/
public function modifyHeader(array &$headers);
/**
* Returns a signature for given data
*
* @param string $payload
* @param Key|string $key
*
* @return Signature
*
* @throws InvalidArgumentException When given key is invalid
*/
public function sign($payload, $key);
/**
* Returns if the expected hash matches with the data and key
*
* @param string $expected
* @param string $payload
* @param Key|string $key
*
* @return boolean
*
* @throws InvalidArgumentException When given key is invalid
*/
public function verify($expected, $payload, $key);
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer;
use Lcobucci\JWT\Signature;
use Lcobucci\JWT\Signer;
/**
* Base class for signers
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
abstract class BaseSigner implements Signer
{
/**
* {@inheritdoc}
*/
public function modifyHeader(array &$headers)
{
$headers['alg'] = $this->getAlgorithmId();
}
/**
* {@inheritdoc}
*/
public function sign($payload, $key)
{
return new Signature($this->createHash($payload, $this->getKey($key)));
}
/**
* {@inheritdoc}
*/
public function verify($expected, $payload, $key)
{
return $this->doVerify($expected, $payload, $this->getKey($key));
}
/**
* @param Key|string $key
*
* @return Key
*/
private function getKey($key)
{
if (is_string($key)) {
$key = new Key($key);
}
return $key;
}
/**
* Creates a hash with the given data
*
* @param string $payload
* @param Key $key
*
* @return string
*/
abstract public function createHash($payload, Key $key);
/**
* Creates a hash with the given data
*
* @param string $payload
* @param Key $key
*
* @return boolean
*/
abstract public function doVerify($expected, $payload, Key $key);
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer;
use Lcobucci\JWT\Signer\Ecdsa\KeyParser;
use Mdanter\Ecc\Crypto\Signature\Signature;
use Mdanter\Ecc\Crypto\Signature\Signer;
use Mdanter\Ecc\EccFactory;
use Mdanter\Ecc\Math\MathAdapterInterface as Adapter;
use Mdanter\Ecc\Random\RandomGeneratorFactory;
use Mdanter\Ecc\Random\RandomNumberGeneratorInterface;
/**
* Base class for ECDSA signers
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
abstract class Ecdsa extends BaseSigner
{
/**
* @var Adapter
*/
private $adapter;
/**
* @var Signer
*/
private $signer;
/**
* @var KeyParser
*/
private $parser;
/**
* @param Adapter $adapter
* @param EcdsaSigner $signer
* @param KeyParser $parser
*/
public function __construct(Adapter $adapter = null, Signer $signer = null, KeyParser $parser = null)
{
$this->adapter = $adapter ?: EccFactory::getAdapter();
$this->signer = $signer ?: EccFactory::getSigner($this->adapter);
$this->parser = $parser ?: new KeyParser($this->adapter);
}
/**
* {@inheritdoc}
*/
public function createHash(
$payload,
Key $key,
RandomNumberGeneratorInterface $generator = null
) {
$privateKey = $this->parser->getPrivateKey($key);
$generator = $generator ?: RandomGeneratorFactory::getRandomGenerator();
return $this->createSignatureHash(
$this->signer->sign(
$privateKey,
$this->createSigningHash($payload),
$generator->generate($privateKey->getPoint()->getOrder())
)
);
}
/**
* Creates a binary signature with R and S coordinates
*
* @param Signature $signature
*
* @return string
*/
private function createSignatureHash(Signature $signature)
{
$length = $this->getSignatureLength();
return pack(
'H*',
sprintf(
'%s%s',
str_pad($this->adapter->decHex($signature->getR()), $length, '0', STR_PAD_LEFT),
str_pad($this->adapter->decHex($signature->getS()), $length, '0', STR_PAD_LEFT)
)
);
}
/**
* Creates a hash using the signer algorithm with given payload
*
* @param string $payload
*
* @return int|string
*/
private function createSigningHash($payload)
{
return $this->adapter->hexDec(hash($this->getAlgorithm(), $payload));
}
/**
* {@inheritdoc}
*/
public function doVerify($expected, $payload, Key $key)
{
return $this->signer->verify(
$this->parser->getPublicKey($key),
$this->extractSignature($expected),
$this->createSigningHash($payload)
);
}
/**
* Extracts R and S values from given data
*
* @param string $value
*
* @return \Mdanter\Ecc\Crypto\Signature\Signature
*/
private function extractSignature($value)
{
$length = $this->getSignatureLength();
$value = unpack('H*', $value)[1];
return new Signature(
$this->adapter->hexDec(substr($value, 0, $length)),
$this->adapter->hexDec(substr($value, $length))
);
}
/**
* Returns the lenght of signature parts
*
* @return int
*/
abstract public function getSignatureLength();
/**
* Returns the name of algorithm to be used to create the signing hash
*
* @return string
*/
abstract public function getAlgorithm();
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Ecdsa;
use InvalidArgumentException;
use Lcobucci\JWT\Signer\Key;
use Mdanter\Ecc\Math\MathAdapterInterface;
use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer;
use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer;
use Mdanter\Ecc\Serializer\PrivateKey\PrivateKeySerializerInterface;
use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer;
use Mdanter\Ecc\Serializer\PublicKey\PublicKeySerializerInterface;
/**
* Base class for ECDSA signers
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 3.0.4
*/
class KeyParser
{
/**
* @var PrivateKeySerializerInterface
*/
private $privateKeySerializer;
/**
* @var PublicKeySerializerInterface
*/
private $publicKeySerializer;
/**
* @param MathAdapterInterface $adapter
* @param PrivateKeySerializerInterface $privateKeySerializer
* @param PublicKeySerializerInterface $publicKeySerializer
*/
public function __construct(
MathAdapterInterface $adapter,
PrivateKeySerializerInterface $privateKeySerializer = null,
PublicKeySerializerInterface $publicKeySerializer = null
) {
$this->privateKeySerializer = $privateKeySerializer ?: new PemPrivateKeySerializer(new DerPrivateKeySerializer($adapter));
$this->publicKeySerializer = $publicKeySerializer ?: new PemPublicKeySerializer(new DerPublicKeySerializer($adapter));
}
/**
* Parses a public key from the given PEM content
*
* @param Key $key
*
* @return \Mdanter\Ecc\Crypto\Key\PublicKeyInterface
*/
public function getPublicKey(Key $key)
{
return $this->publicKeySerializer->parse($this->getKeyContent($key, 'PUBLIC KEY'));
}
/**
* Parses a private key from the given PEM content
*
* @param Key $key
*
* @return \Mdanter\Ecc\Crypto\Key\PrivateKeyInterface
*/
public function getPrivateKey(Key $key)
{
return $this->privateKeySerializer->parse($this->getKeyContent($key, 'EC PRIVATE KEY'));
}
/**
* Extracts the base 64 value from the PEM certificate
*
* @param Key $key
* @param string $header
*
* @return string
*
* @throws InvalidArgumentException When given key is not a ECDSA key
*/
private function getKeyContent(Key $key, $header)
{
$match = null;
preg_match(
'/[\-]{5}BEGIN ' . $header . '[\-]{5}(.*)[\-]{5}END ' . $header . '[\-]{5}/',
str_replace([PHP_EOL, "\n", "\r"], '', $key->getContent()),
$match
);
if (isset($match[1])) {
return $match[1];
}
throw new InvalidArgumentException('This is not a valid ECDSA key.');
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Ecdsa;
use Lcobucci\JWT\Signer\Ecdsa;
/**
* Signer for ECDSA SHA-256
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
class Sha256 extends Ecdsa
{
/**
* {@inheritdoc}
*/
public function getAlgorithmId()
{
return 'ES256';
}
/**
* {@inheritdoc}
*/
public function getAlgorithm()
{
return 'sha256';
}
/**
* {@inheritdoc}
*/
public function getSignatureLength()
{
return 64;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Ecdsa;
use Lcobucci\JWT\Signer\Ecdsa;
/**
* Signer for ECDSA SHA-384
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
class Sha384 extends Ecdsa
{
/**
* {@inheritdoc}
*/
public function getAlgorithmId()
{
return 'ES384';
}
/**
* {@inheritdoc}
*/
public function getAlgorithm()
{
return 'sha384';
}
/**
* {@inheritdoc}
*/
public function getSignatureLength()
{
return 96;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Ecdsa;
use Lcobucci\JWT\Signer\Ecdsa;
/**
* Signer for ECDSA SHA-512
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
class Sha512 extends Ecdsa
{
/**
* {@inheritdoc}
*/
public function getAlgorithmId()
{
return 'ES512';
}
/**
* {@inheritdoc}
*/
public function getAlgorithm()
{
return 'sha512';
}
/**
* {@inheritdoc}
*/
public function getSignatureLength()
{
return 132;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer;
/**
* Base class for hmac signers
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
abstract class Hmac extends BaseSigner
{
/**
* {@inheritdoc}
*/
public function createHash($payload, Key $key)
{
return hash_hmac($this->getAlgorithm(), $payload, $key->getContent(), true);
}
/**
* {@inheritdoc}
*/
public function doVerify($expected, $payload, Key $key)
{
if (!is_string($expected)) {
return false;
}
$callback = function_exists('hash_equals') ? 'hash_equals' : [$this, 'hashEquals'];
return call_user_func($callback, $expected, $this->createHash($payload, $key));
}
/**
* PHP < 5.6 timing attack safe hash comparison
*
* @param string $expected
* @param string $generated
*
* @return boolean
*/
public function hashEquals($expected, $generated)
{
$expectedLength = strlen($expected);
if ($expectedLength !== strlen($generated)) {
return false;
}
$res = 0;
for ($i = 0; $i < $expectedLength; ++$i) {
$res |= ord($expected[$i]) ^ ord($generated[$i]);
}
return $res === 0;
}
/**
* Returns the algorithm name
*
* @return string
*/
abstract public function getAlgorithm();
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Hmac;
use Lcobucci\JWT\Signer\Hmac;
/**
* Signer for HMAC SHA-256
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
class Sha256 extends Hmac
{
/**
* {@inheritdoc}
*/
public function getAlgorithmId()
{
return 'HS256';
}
/**
* {@inheritdoc}
*/
public function getAlgorithm()
{
return 'sha256';
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Hmac;
use Lcobucci\JWT\Signer\Hmac;
/**
* Signer for HMAC SHA-384
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
class Sha384 extends Hmac
{
/**
* {@inheritdoc}
*/
public function getAlgorithmId()
{
return 'HS384';
}
/**
* {@inheritdoc}
*/
public function getAlgorithm()
{
return 'sha384';
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Hmac;
use Lcobucci\JWT\Signer\Hmac;
/**
* Signer for HMAC SHA-512
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
class Sha512 extends Hmac
{
/**
* {@inheritdoc}
*/
public function getAlgorithmId()
{
return 'HS512';
}
/**
* {@inheritdoc}
*/
public function getAlgorithm()
{
return 'sha512';
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer;
use InvalidArgumentException;
/**
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 3.0.4
*/
final class Key
{
/**
* @var string
*/
private $content;
/**
* @var string
*/
private $passphrase;
/**
* @param string $content
* @param string $passphrase
*/
public function __construct($content, $passphrase = null)
{
$this->setContent($content);
$this->passphrase = $passphrase;
}
/**
* @param string $content
*
* @throws InvalidArgumentException
*/
private function setContent($content)
{
if (strpos($content, 'file://') === 0) {
$content = $this->readFile($content);
}
$this->content = $content;
}
/**
* @param string $content
*
* @return string
*
* @throws \InvalidArgumentException
*/
private function readFile($content)
{
$file = substr($content, 7);
if (!is_readable($file)) {
throw new \InvalidArgumentException('You must inform a valid key file');
}
return file_get_contents($file);
}
/**
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* @return string
*/
public function getPassphrase()
{
return $this->passphrase;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer;
/**
* A utilitarian class that encapsulates the retrieval of public and private keys
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*
* @deprecated Since we've removed OpenSSL from ECDSA there's no reason to use this class
*/
class Keychain
{
/**
* Returns a private key from file path or content
*
* @param string $key
* @param string $passphrase
*
* @return Key
*/
public function getPrivateKey($key, $passphrase = null)
{
return new Key($key, $passphrase);
}
/**
* Returns a public key from file path or content
*
* @param string $certificate
*
* @return Key
*/
public function getPublicKey($certificate)
{
return new Key($certificate);
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer;
use InvalidArgumentException;
/**
* Base class for RSASSA-PKCS1 signers
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
abstract class Rsa extends BaseSigner
{
/**
* {@inheritdoc}
*/
public function createHash($payload, Key $key)
{
$key = openssl_get_privatekey($key->getContent(), $key->getPassphrase());
$this->validateKey($key);
$signature = '';
if (!openssl_sign($payload, $signature, $key, $this->getAlgorithm())) {
throw new InvalidArgumentException(
'There was an error while creating the signature: ' . openssl_error_string()
);
}
return $signature;
}
/**
* {@inheritdoc}
*/
public function doVerify($expected, $payload, Key $key)
{
$key = openssl_get_publickey($key->getContent());
$this->validateKey($key);
return openssl_verify($payload, $expected, $key, $this->getAlgorithm()) === 1;
}
/**
* Validates if the given key is a valid RSA public/private key
*
* @param resource $key
*
* @throws InvalidArgumentException
*/
private function validateKey($key)
{
if ($key === false) {
throw new InvalidArgumentException(
'It was not possible to parse your key, reason: ' . openssl_error_string()
);
}
$details = openssl_pkey_get_details($key);
if (!isset($details['key']) || $details['type'] !== OPENSSL_KEYTYPE_RSA) {
throw new InvalidArgumentException('This key is not compatible with RSA signatures');
}
}
/**
* Returns the algorithm name
*
* @return string
*/
abstract public function getAlgorithm();
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Rsa;
use Lcobucci\JWT\Signer\Rsa;
/**
* Signer for RSA SHA-256
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
class Sha256 extends Rsa
{
/**
* {@inheritdoc}
*/
public function getAlgorithmId()
{
return 'RS256';
}
/**
* {@inheritdoc}
*/
public function getAlgorithm()
{
return OPENSSL_ALGO_SHA256;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Rsa;
use Lcobucci\JWT\Signer\Rsa;
/**
* Signer for RSA SHA-384
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
class Sha384 extends Rsa
{
/**
* {@inheritdoc}
*/
public function getAlgorithmId()
{
return 'RS384';
}
/**
* {@inheritdoc}
*/
public function getAlgorithm()
{
return OPENSSL_ALGO_SHA384;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\Signer\Rsa;
use Lcobucci\JWT\Signer\Rsa;
/**
* Signer for RSA SHA-512
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
class Sha512 extends Rsa
{
/**
* {@inheritdoc}
*/
public function getAlgorithmId()
{
return 'RS512';
}
/**
* {@inheritdoc}
*/
public function getAlgorithm()
{
return OPENSSL_ALGO_SHA512;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT;
use BadMethodCallException;
use DateTime;
use DateTimeInterface;
use Generator;
use Lcobucci\JWT\Claim\Validatable;
use OutOfBoundsException;
/**
* Basic structure of the JWT
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 0.1.0
*/
class Token
{
/**
* The token headers
*
* @var array
*/
private $headers;
/**
* The token claim set
*
* @var array
*/
private $claims;
/**
* The token signature
*
* @var Signature
*/
private $signature;
/**
* The encoded data
*
* @var array
*/
private $payload;
/**
* Initializes the object
*
* @param array $headers
* @param array $claims
* @param array $payload
* @param Signature $signature
*/
public function __construct(
array $headers = ['alg' => 'none'],
array $claims = [],
Signature $signature = null,
array $payload = ['', '']
) {
$this->headers = $headers;
$this->claims = $claims;
$this->signature = $signature;
$this->payload = $payload;
}
/**
* Returns the token headers
*
* @return array
*/
public function getHeaders()
{
return $this->headers;
}
/**
* Returns if the header is configured
*
* @param string $name
*
* @return boolean
*/
public function hasHeader($name)
{
return array_key_exists($name, $this->headers);
}
/**
* Returns the value of a token header
*
* @param string $name
* @param mixed $default
*
* @return mixed
*
* @throws OutOfBoundsException
*/
public function getHeader($name, $default = null)
{
if ($this->hasHeader($name)) {
return $this->getHeaderValue($name);
}
if ($default === null) {
throw new OutOfBoundsException('Requested header is not configured');
}
return $default;
}
/**
* Returns the value stored in header
*
* @param string $name
*
* @return mixed
*/
private function getHeaderValue($name)
{
$header = $this->headers[$name];
if ($header instanceof Claim) {
return $header->getValue();
}
return $header;
}
/**
* Returns the token claim set
*
* @return array
*/
public function getClaims()
{
return $this->claims;
}
/**
* Returns if the claim is configured
*
* @param string $name
*
* @return boolean
*/
public function hasClaim($name)
{
return array_key_exists($name, $this->claims);
}
/**
* Returns the value of a token claim
*
* @param string $name
* @param mixed $default
*
* @return mixed
*
* @throws OutOfBoundsException
*/
public function getClaim($name, $default = null)
{
if ($this->hasClaim($name)) {
return $this->claims[$name]->getValue();
}
if ($default === null) {
throw new OutOfBoundsException('Requested claim is not configured');
}
return $default;
}
/**
* Verify if the key matches with the one that created the signature
*
* @param Signer $signer
* @param string $key
*
* @return boolean
*
* @throws BadMethodCallException When token is not signed
*/
public function verify(Signer $signer, $key)
{
if ($this->signature === null) {
throw new BadMethodCallException('This token is not signed');
}
if ($this->headers['alg'] !== $signer->getAlgorithmId()) {
return false;
}
return $this->signature->verify($signer, $this->getPayload(), $key);
}
/**
* Validates if the token is valid
*
* @param ValidationData $data
*
* @return boolean
*/
public function validate(ValidationData $data)
{
foreach ($this->getValidatableClaims() as $claim) {
if (!$claim->validate($data)) {
return false;
}
}
return true;
}
/**
* Determine if the token is expired.
*
* @param DateTimeInterface $now Defaults to the current time.
*
* @return bool
*/
public function isExpired(DateTimeInterface $now = null)
{
$exp = $this->getClaim('exp', false);
if ($exp === false) {
return false;
}
$now = $now ?: new DateTime();
$expiresAt = new DateTime();
$expiresAt->setTimestamp($exp);
return $now > $expiresAt;
}
/**
* Yields the validatable claims
*
* @return Generator
*/
private function getValidatableClaims()
{
foreach ($this->claims as $claim) {
if ($claim instanceof Validatable) {
yield $claim;
}
}
}
/**
* Returns the token payload
*
* @return string
*/
public function getPayload()
{
return $this->payload[0] . '.' . $this->payload[1];
}
/**
* Returns an encoded representation of the token
*
* @return string
*/
public function __toString()
{
$data = implode('.', $this->payload);
if ($this->signature === null) {
$data .= '.';
}
return $data;
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT;
/**
* Class that wraps validation values
*
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.0.0
*/
class ValidationData
{
/**
* The list of things to be validated
*
* @var array
*/
private $items;
/**
* Initializes the object
*
* @param int $currentTime
*/
public function __construct($currentTime = null)
{
$currentTime = $currentTime ?: time();
$this->items = [
'jti' => null,
'iss' => null,
'aud' => null,
'sub' => null,
'iat' => $currentTime,
'nbf' => $currentTime,
'exp' => $currentTime
];
}
/**
* Configures the id
*
* @param string $id
*/
public function setId($id)
{
$this->items['jti'] = (string) $id;
}
/**
* Configures the issuer
*
* @param string $issuer
*/
public function setIssuer($issuer)
{
$this->items['iss'] = (string) $issuer;
}
/**
* Configures the audience
*
* @param string $audience
*/
public function setAudience($audience)
{
$this->items['aud'] = (string) $audience;
}
/**
* Configures the subject
*
* @param string $subject
*/
public function setSubject($subject)
{
$this->items['sub'] = (string) $subject;
}
/**
* Configures the time that "iat", "nbf" and "exp" should be based on
*
* @param int $currentTime
*/
public function setCurrentTime($currentTime)
{
$this->items['iat'] = (int) $currentTime;
$this->items['nbf'] = (int) $currentTime;
$this->items['exp'] = (int) $currentTime;
}
/**
* Returns the requested item
*
* @param string $name
*
* @return mixed
*/
public function get($name)
{
return isset($this->items[$name]) ? $this->items[$name] : null;
}
/**
* Returns if the item is present
*
* @param string $name
*
* @return boolean
*/
public function has($name)
{
return !empty($this->items[$name]);
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\FunctionalTests;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Token;
use Lcobucci\JWT\Signature;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Signer\Hmac\Sha512;
/**
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
class HmacTokenTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Sha256
*/
private $signer;
/**
* @before
*/
public function createSigner()
{
$this->signer = new Sha256();
}
/**
* @test
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Hmac
* @covers Lcobucci\JWT\Signer\Hmac\Sha256
*/
public function builderCanGenerateAToken()
{
$user = (object) ['name' => 'testing', 'email' => 'testing@abc.com'];
$token = (new Builder())->setId(1)
->setAudience('http://client.abc.com')
->setIssuer('http://api.abc.com')
->set('user', $user)
->setHeader('jki', '1234')
->sign($this->signer, 'testing')
->getToken();
$this->assertAttributeInstanceOf(Signature::class, 'signature', $token);
$this->assertEquals('1234', $token->getHeader('jki'));
$this->assertEquals('http://client.abc.com', $token->getClaim('aud'));
$this->assertEquals('http://api.abc.com', $token->getClaim('iss'));
$this->assertEquals($user, $token->getClaim('user'));
return $token;
}
/**
* @test
*
* @depends builderCanGenerateAToken
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Parsing\Decoder
*/
public function parserCanReadAToken(Token $generated)
{
$read = (new Parser())->parse((string) $generated);
$this->assertEquals($generated, $read);
$this->assertEquals('testing', $read->getClaim('user')->name);
}
/**
* @test
*
* @depends builderCanGenerateAToken
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Hmac
* @covers Lcobucci\JWT\Signer\Hmac\Sha256
*/
public function verifyShouldReturnFalseWhenKeyIsNotRight(Token $token)
{
$this->assertFalse($token->verify($this->signer, 'testing1'));
}
/**
* @test
*
* @depends builderCanGenerateAToken
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Hmac
* @covers Lcobucci\JWT\Signer\Hmac\Sha256
* @covers Lcobucci\JWT\Signer\Hmac\Sha512
*/
public function verifyShouldReturnFalseWhenAlgorithmIsDifferent(Token $token)
{
$this->assertFalse($token->verify(new Sha512(), 'testing'));
}
/**
* @test
*
* @depends builderCanGenerateAToken
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Hmac
* @covers Lcobucci\JWT\Signer\Hmac\Sha256
*/
public function verifyShouldReturnTrueWhenKeyIsRight(Token $token)
{
$this->assertTrue($token->verify($this->signer, 'testing'));
}
/**
* @test
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Hmac
* @covers Lcobucci\JWT\Signer\Hmac\Sha256
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Parsing\Decoder
*/
public function everythingShouldWorkWhenUsingATokenGeneratedByOtherLibs()
{
$data = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJoZWxsbyI6IndvcmxkIn0.Rh'
. '7AEgqCB7zae1PkgIlvOpeyw9Ab8NGTbeOH7heHO0o';
$token = (new Parser())->parse((string) $data);
$this->assertEquals('world', $token->getClaim('hello'));
$this->assertTrue($token->verify($this->signer, 'testing'));
}
}
<?php
namespace Lcobucci\JWT;
use Lcobucci\JWT\Signer\Keychain;
/**
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
*/
trait Keys
{
/**
* @var array
*/
protected static $rsaKeys;
/**
* @var array
*/
protected static $ecdsaKeys;
/**
* @beforeClass
*/
public static function createRsaKeys()
{
$keychain = new Keychain();
$dir = 'file://' . __DIR__;
static::$rsaKeys = [
'private' => $keychain->getPrivateKey($dir . '/rsa/private.key'),
'public' => $keychain->getPublicKey($dir . '/rsa/public.key'),
'encrypted-private' => $keychain->getPrivateKey($dir . '/rsa/encrypted-private.key', 'testing'),
'encrypted-public' => $keychain->getPublicKey($dir . '/rsa/encrypted-public.key')
];
}
/**
* @beforeClass
*/
public static function createEcdsaKeys()
{
$keychain = new Keychain();
$dir = 'file://' . __DIR__;
static::$ecdsaKeys = [
'private' => $keychain->getPrivateKey($dir . '/ecdsa/private.key'),
'private-params' => $keychain->getPrivateKey($dir . '/ecdsa/private2.key'),
'public1' => $keychain->getPublicKey($dir . '/ecdsa/public1.key'),
'public2' => $keychain->getPublicKey($dir . '/ecdsa/public2.key'),
'public-params' => $keychain->getPublicKey($dir . '/ecdsa/public3.key'),
];
}
}
<?php
/**
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
*
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
*/
namespace Lcobucci\JWT\FunctionalTests;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Keys;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Token;
use Lcobucci\JWT\Signature;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\Signer\Rsa\Sha512;
/**
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
* @since 2.1.0
*/
class RsaTokenTest extends \PHPUnit_Framework_TestCase
{
use Keys;
/**
* @var Sha256
*/
private $signer;
/**
* @before
*/
public function createSigner()
{
$this->signer = new Sha256();
}
/**
* @test
*
* @expectedException \InvalidArgumentException
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Rsa
* @covers Lcobucci\JWT\Signer\Rsa\Sha256
*/
public function builderShouldRaiseExceptionWhenKeyIsInvalid()
{
$user = (object) ['name' => 'testing', 'email' => 'testing@abc.com'];
(new Builder())->setId(1)
->setAudience('http://client.abc.com')
->setIssuer('http://api.abc.com')
->set('user', $user)
->sign($this->signer, new Key('testing'));
}
/**
* @test
*
* @expectedException \InvalidArgumentException
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Rsa
* @covers Lcobucci\JWT\Signer\Rsa\Sha256
*/
public function builderShouldRaiseExceptionWhenKeyIsNotRsaCompatible()
{
$user = (object) ['name' => 'testing', 'email' => 'testing@abc.com'];
(new Builder())->setId(1)
->setAudience('http://client.abc.com')
->setIssuer('http://api.abc.com')
->set('user', $user)
->sign($this->signer, static::$ecdsaKeys['private']);
}
/**
* @test
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Rsa
* @covers Lcobucci\JWT\Signer\Rsa\Sha256
*/
public function builderCanGenerateAToken()
{
$user = (object) ['name' => 'testing', 'email' => 'testing@abc.com'];
$token = (new Builder())->setId(1)
->setAudience('http://client.abc.com')
->setIssuer('http://api.abc.com')
->set('user', $user)
->setHeader('jki', '1234')
->sign($this->signer, static::$rsaKeys['private'])
->getToken();
$this->assertAttributeInstanceOf(Signature::class, 'signature', $token);
$this->assertEquals('1234', $token->getHeader('jki'));
$this->assertEquals('http://client.abc.com', $token->getClaim('aud'));
$this->assertEquals('http://api.abc.com', $token->getClaim('iss'));
$this->assertEquals($user, $token->getClaim('user'));
return $token;
}
/**
* @test
*
* @depends builderCanGenerateAToken
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Parsing\Decoder
*/
public function parserCanReadAToken(Token $generated)
{
$read = (new Parser())->parse((string) $generated);
$this->assertEquals($generated, $read);
$this->assertEquals('testing', $read->getClaim('user')->name);
}
/**
* @test
*
* @depends builderCanGenerateAToken
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Rsa
* @covers Lcobucci\JWT\Signer\Rsa\Sha256
*/
public function verifyShouldReturnFalseWhenKeyIsNotRight(Token $token)
{
$this->assertFalse($token->verify($this->signer, self::$rsaKeys['encrypted-public']));
}
/**
* @test
*
* @depends builderCanGenerateAToken
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Rsa
* @covers Lcobucci\JWT\Signer\Rsa\Sha256
* @covers Lcobucci\JWT\Signer\Rsa\Sha512
*/
public function verifyShouldReturnFalseWhenAlgorithmIsDifferent(Token $token)
{
$this->assertFalse($token->verify(new Sha512(), self::$rsaKeys['public']));
}
/**
* @test
*
* @expectedException \InvalidArgumentException
*
* @depends builderCanGenerateAToken
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Rsa
* @covers Lcobucci\JWT\Signer\Rsa\Sha256
*/
public function verifyShouldRaiseExceptionWhenKeyIsNotRsaCompatible(Token $token)
{
$this->assertFalse($token->verify($this->signer, self::$ecdsaKeys['public1']));
}
/**
* @test
*
* @depends builderCanGenerateAToken
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Rsa
* @covers Lcobucci\JWT\Signer\Rsa\Sha256
*/
public function verifyShouldReturnTrueWhenKeyIsRight(Token $token)
{
$this->assertTrue($token->verify($this->signer, self::$rsaKeys['public']));
}
/**
* @test
*
* @covers Lcobucci\JWT\Builder
* @covers Lcobucci\JWT\Parser
* @covers Lcobucci\JWT\Token
* @covers Lcobucci\JWT\Signature
* @covers Lcobucci\JWT\Signer\Key
* @covers Lcobucci\JWT\Signer\BaseSigner
* @covers Lcobucci\JWT\Signer\Rsa
* @covers Lcobucci\JWT\Signer\Rsa\Sha256
* @covers Lcobucci\JWT\Claim\Factory
* @covers Lcobucci\JWT\Claim\Basic
* @covers Lcobucci\JWT\Parsing\Encoder
* @covers Lcobucci\JWT\Parsing\Decoder
*/
public function everythingShouldWorkWhenUsingATokenGeneratedByOtherLibs()
{
$data = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJoZWxsbyI6IndvcmxkIn0.s'
. 'GYbB1KrmnESNfJ4D9hOe1Zad_BMyxdb8G4p4LNP7StYlOyBWck6q7XPpPj_6gB'
. 'Bo1ohD3MA2o0HY42lNIrAStaVhfsFKGdIou8TarwMGZBPcif_3ThUV1pGS3fZc'
. 'lFwF2SP7rqCngQis_xcUVCyqa8E1Wa_v28grnl1QZrnmQFO8B5JGGLqcrfUHJO'
. 'nJCupP-Lqh4TmIhftIimSCgLNmJg80wyrpUEfZYReE7hPuEmY0ClTqAGIMQoNS'
. '98ljwDxwhfbSuL2tAdbV4DekbTpWzspe3dOJ7RSzmPKVZ6NoezaIazKqyqkmHZfcMaHI1lQeGia6LTbHU1bp0gINi74Vw';
$token = (new Parser())->parse((string) $data);
$this->assertEquals('world', $token->getClaim('hello'));
$this->assertTrue($token->verify($this->signer, self::$rsaKeys['public']));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment