Skip to content

Commit

Permalink
v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
DestruidorPT committed Jan 12, 2020
1 parent badde48 commit 9ed0f97
Show file tree
Hide file tree
Showing 36 changed files with 2,772 additions and 0 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) Elton Pastilha, Vladyslav Adamovych, João Ricardo

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
49 changes: 49 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "destruidorpt/laravel-sqrl-auth",
"description": "Package for Authentication between Laravel and SQRL",
"keywords": ["SQRL", "laravel", "authentication", "QRCode", "auth", "login", "package", "Must have", "MCIF", "IPLeiria", "ESTG"],
"license": "MIT",
"minimum-stability": "dev",
"prefer-stable": true,
"authors": [
{
"name": "Elton Pastilha",
"email": "elton_ola@hotmail.com",
"homepage": "https://github.com/DestruidorPT",
"role": "Developer, CyberSecurity Expert and Gamer"
},
{
"name": "Vladyslav Adamovych",
"email": "vladyslav.adamovych@ipleiria.pt",
"homepage": "https://github.com/nekkiii",
"role": "Developer, CyberSecurity Expert and Gamer"
},
{
"name": "João Ricardo",
"email": "joao_pricardo@hotmail.com",
"homepage": "https://github.com/kratezo",
"role": "Developer, CyberSecurity Expert and Gamer"
}
],
"require": {
"php": ">=7.2",
"laravel/framework": ">=6.0",
"simplesoftwareio/simple-qrcode": ">=2.0"
},
"require-dev": {},
"autoload": {
"psr-4": {
"DestruidorPT\\LaravelSQRLAuth\\": "/src"
},
"classmap": [
"src"
]
},
"extra": {
"laravel": {
"providers": [
"DestruidorPT\\LaravelSQRLAuth\\LaravelSQRLAuthServiceProvider"
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
<?php

namespace App\Http\Controllers\LaravelSQRLAuthExemples;


use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use App\User;
use DestruidorPT\LaravelSQRLAuth\App\Sqrl_pubkey;
use DestruidorPT\LaravelSQRLAuth\App\Http\Controllers\SQRL\SQRLController;

class ExempleController extends Controller
{
/**
* Function to get the login page and check if given by paramer GET["nut"] is passed
* if $_GET["nut"] exist will check if the nonce is valid and return object type Sqrl_pubkey if the
* no SQRL Client registed is not associated to any user, if returns a number means is ID of the user
* associated and then proceds to authenticate that user
*
* @GET string nut
*
* @return View
*/
public function getAuthPage()
{
if(isset($_GET["nut"]) && !empty($_GET["nut"])) { // Check if the nut exist or if it's past on URL https://site.test?nut=<nonce value>
$object = SQRLController::getUserByOriginalNonceIfCanBeAuthenticated($_GET["nut"]); //Get the user by the original nonce
if(isset($object)) { //Will be null if the nonce expired or is invalid
if($object instanceof Sqrl_pubkey) { // This only happen when no SQRL Client is associated to the user, then Sqrl_pubkey from SQRL CLient is returned
//new user
return view('LaravelSQRLAuthExemples.newsqrl');//View for the user to create account or associate to one already created
} else if($object > 0) { //This happen when SQRL Client is associated to a user, so the value is number and is the id of the user
Auth::loginUsingId($object); //This is for authenticate the user with that id
}
}
}
if (Auth::check()) {
// The user is logged in...
return redirect()->intended('dashboard');
}
return view('LaravelSQRLAuthExemples.login', SQRLController::getNewAuthNonce());
}

/**
* Function to post credentials from login page and check if user exist and are valid credentials,
* But will check first if the user can login by normal login given by paramer GET["nut"] is passed
* if $_GET["nut"] exist will check if the nonce is valid and return object type Sqrl_pubkey if the
* no SQRL Client registed is not associated to any user, if returns a number means is ID of the user
* associated and then proceds to authenticate that user
*
* @GET string nut
*
* @return View
*/
public function login(Request $request)
{
if (Auth::check()) {
// The user is logged in...
return redirect()->intended('dashboard');
}
$validatedData = $request->validate([
'email' => 'required|email|exists:users,email',
'password' => 'required|string',
]);
$user = User::where("email", "=", $validatedData["email"])->first();
if(isset($user)){ //Check if the user exists
if(!SQRLController::checkIfUserCanAuthByNormalLogin($user->id)) { //Check if the user can not be authentication by normal login authentication
return redirect()->intended('login')->withErrors(['SQRL Only Allowed!!!']);//If returned false then the user only can authenticate by SQRL
}
}
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
return redirect()->intended('dashboard');
}
return redirect()->intended('login')->withErrors(['Login Fail!!!']);
}

/**
* Function to post the new user information and can associate the new user
* to the SQRL Client Public Key that was not previously associated to any user
*
* @GET string nut
* @param Request $request
*
* @return View
*/
public function newAcc(Request $request)
{
$validatedData = $request->validate([
'name' => 'required|string',
'email' => 'required|unique:users,email',
'password' => 'required|string',
]);
$validatedData['password'] = Hash::make($validatedData['password']);


$user = new User($validatedData);
$user->save();
//dd($user);
if(isset($user)) { // Check if user is not null
if(isset($_GET["nut"]) && !empty($_GET["nut"])) { // Check if the nut exist or if it's past on URL https://site.test?nut=<nonce value>
$object = SQRLController::getUserByOriginalNonceIfCanBeAuthenticated($_GET["nut"]); //Get the user by the original nonce
if(isset($object)) { //Will be null if the nonce expired or is invalid
if($object instanceof Sqrl_pubkey) { // This only happen when no SQRL Client is associated to the user, then Sqrl_pubkey from SQRL CLient is returned
//new user
$object->user_id = $user->id; // So the user was created then lets associate to the new user
$object->save();
}
}
}
Auth::loginUsingId($user->id);
}
if (Auth::check()) {
// Authentication passed...
return redirect()->intended('dashboard');
}
return redirect()->intended('login');
}

/**
* Function to post the new credentials of the user login and for associate the user
* to the SQRL Client Public Key that was not previously associated to any user
*
* @GET string nut
* @param Request $request
*
* @return View
*/
public function newlogin(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) { // Do a login of the user
// Authentication passed...
$object = SQRLController::getUserByOriginalNonceIfCanBeAuthenticated($_GET["nut"]); //Get the user by the original nonce
if(isset($object)) { //Will be null if the nonce expired or is invalid
if($object instanceof Sqrl_pubkey) { // This only happen when no SQRL Client is associated to the user, then Sqrl_pubkey from SQRL CLient is returned
//new user
$object->user_id = Auth::id(); // So the user was created then lets associate to the user already existing
$object->save();
}
}
return redirect()->intended('dashboard');
}
return redirect()->intended('login');
}

/**
* Function to logout user
*
* @param Request $request
*
* @return View
*/
public function logout(Request $request)
{
Auth::logout();
return redirect()->intended('login');
}

/**
* Function to get the dashboard page
*
*
* @return View
*/
public function getDashboardPage()
{
if (Auth::check()) {
// The user is logged in...
return view('LaravelSQRLAuthExemples.dashboard', ["user_name" => Auth::user()->name]);
}
return redirect()->intended('login');
}

/**
* Function to post the new question to the user by SQRL application, in this exemple is a question if the user confer a transaction of money
*
* @param Request $request
*
* @return View
*/
public function getTransferConfirmation(Request $request)
{
$validatedData = $request->validate([
'money' => 'required|numeric|min:1',
'btn1' => 'nullable|string|required_with:url1',
'url1' => 'nullable|string',
'btn2' => 'nullable|string|required_with:url2',
'url2' => 'nullable|string',
]);
$data = SQRLController::getNewQuestionNonce(env('SQRL_URL_LOGIN', 'https://sqrl.test/login'), env('SQRL_URL_LOGIN', 'https://sqrl.test/login'), "Do you confirm ".$validatedData["money"]."$ tranfering?", $validatedData["btn1"], $validatedData["url1"], $validatedData["btn2"], $validatedData["url2"]);
$data["money"] = $validatedData["money"];
return view('LaravelSQRLAuthExemples.transfer', $data);
}

/**
* Function to get the page to reset password
*
* @param Request $request
*
* @return View
*/
public function getResetPWPage()
{
return view('LaravelSQRLAuthExemples.forgotpassword');
}

/**
* Function to post the information of user to reset the password,
* but only will reset the password if user account allowed
*
* @param Request $request
*
* @return View
*/
public function resetPW(Request $request)
{
$validatedData = $request->validate([
'email' => 'required|email|exists:users,email',
'password' => 'string',
]);
$user = User::where("email", "=", $validatedData["email"])->first();
if(isset($user)){ //Check if the user exists
if(!SQRLController::checkIfUserCanUseRecoverPassword($user->id)) { //Check if the user can not recovery the password
return redirect()->intended('resetpw')->withErrors(['SQRL not Allowed recovery account!!!']); //This means that the account as hardlocked by SQRL Client that not Allowed recovery password by email or personal questions
} else if(isset($validatedData["password"]) && !empty($validatedData["password"])) {
$user->password = $validatedData["password"];
$user->save();
}
}
return view('LaravelSQRLAuthExemples.newpassword', ['email' => $validatedData["email"]]);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Laravel</title>

<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css" integrity="sha384-SI27wrMjH3ZZ89r4o+fGIJtnzkAnFs3E4qz9DIYioCQ5l9Rd/7UAa8DHcaL8jkWt" crossorigin="anonymous">
<!-- Styles -->
<style>
body {
height: 100vh;
width: 100%;
background: linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(0,0,0,0.15) 100%), radial-gradient(at top center, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.40) 120%) #989898;
background-blend-mode: multiply,multiply;
}
.container {
height: 90%;
width: 100%;
margin-top: 10vh;
}
.card {
background-image: linear-gradient(120deg, #f6d365 0%, #fda085 100%);
}
.sqrl-logo {
height: 100px !important;
width: 100px !important;
}
</style>
</head>
<body>
<div class="container">
<div class="card mx-auto my-auto" style="max-width: 540px;">
<div class="row no-gutters">
<div class="col-sm mx-2 my-3">
<form method="post" action="/logout">
{{ csrf_field() }}
<button type="submit" class="btn btn-link text-dark" style="float: right;">Logout</button>
</form>
<div class="card-body">
<h5 class="card-title">Auth User: {{$user_name ?? ''}}</h5>
<form method="post" action="/transfer">
{{ csrf_field() }}
<div class="form-group">
<label for="money">Money To Transfer:</label>
<input name="money" type="number" step="0.01" class="form-control" id="money">
</div>
<div class="form-group">
<label for="btn1">Button_1</label>
<input name="btn1" type="text" class="form-control" id="btn1">
</div>
<div class="form-group">
<label for="url1">URL_1</label>
<input name="url1" type="text" class="form-control" id="url1">
</div>
<div class="form-group">
<label for="btn2">Button_2</label>
<input name="btn2" type="text" class="form-control" id="btn2">
</div>
<div class="form-group">
<label for="url2">URL_2</label>
<input name="url2" type="text" class="form-control" id="url2">
</div>
<button type="submit" class="btn btn-dark">Transfer</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/js/bootstrap.min.js" integrity="sha384-3qaqj0lc6sV/qpzrc1N5DC6i1VRn/HyX4qdPaiEFbn54VjQBEU341pvjz7Dv3n6P" crossorigin="anonymous"></script>
</html>
Loading

0 comments on commit 9ed0f97

Please sign in to comment.