summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/ajax-broker/api.php38
-rw-r--r--examples/ajax-broker/app.js107
-rw-r--r--examples/ajax-broker/index.html56
-rw-r--r--examples/broker/error.php25
-rw-r--r--examples/broker/index.php39
-rw-r--r--examples/broker/login.php56
-rw-r--r--examples/server/.htaccess6
-rw-r--r--examples/server/MySSOServer.php90
-rw-r--r--examples/server/index.php18
9 files changed, 435 insertions, 0 deletions
diff --git a/examples/ajax-broker/api.php b/examples/ajax-broker/api.php
new file mode 100644
index 0000000..996b813
--- /dev/null
+++ b/examples/ajax-broker/api.php
@@ -0,0 +1,38 @@
+<?php
+
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET'));
+
+if (empty($_REQUEST['command']) || !method_exists($broker, $_REQUEST['command'])) {
+ header("Content-Type: application/json");
+ header("HTTP/1.1 400 Bad Request");
+ echo json_encode(['error' => 'Command not specified']);
+ exit();
+}
+
+try {
+ $result = $broker->{$_REQUEST['command']}();
+} catch (Exception $e) {
+ $status = $e->getCode() ?: 500;
+ $result = ['error' => $e->getMessage()];
+}
+
+// JSONP
+if (!empty($_GET['callback'])) {
+ if (!isset($result)) $result = null;
+ if (!isset($status)) $status = isset($result) ? 200 : 204;
+
+ header('Content-Type: application/javascript');
+ echo $_GET['callback'] . '(' . json_encode($result) . ', ' . $status . ')';
+ return;
+}
+
+// REST
+if (!$result) {
+ http_response_code(204);
+} else {
+ http_response_code(isset($status) ? $status : 200);
+ header("Content-Type: application/json");
+ echo json_encode($result);
+}
diff --git a/examples/ajax-broker/app.js b/examples/ajax-broker/app.js
new file mode 100644
index 0000000..7a627c9
--- /dev/null
+++ b/examples/ajax-broker/app.js
@@ -0,0 +1,107 @@
++function($) {
+ // Init
+ attach();
+
+ /**
+ * Attach session.
+ * Will redirect to SSO server.
+ */
+ function attach() {
+ var req = $.ajax({
+ url: 'api.php?command=attach',
+ crossDomain: true,
+ dataType: 'jsonp'
+ });
+
+ req.done(function(data, code) {
+ if (code && code >= 400) { // jsonp failure
+ showError(data.error);
+ return;
+ }
+
+ loadUserInfo();
+ });
+
+ req.fail(function(jqxhr) {
+ showError(jqxhr.responseJSON || jqxhr.textResponse)
+ });
+ }
+
+ /**
+ * Do an AJAX request to the API
+ *
+ * @param command API command
+ * @param params POST data
+ * @param callback Callback function
+ */
+ function doApiRequest(command, params, callback) {
+ var req = $.ajax({
+ url: 'api.php?command=' + command,
+ method: params ? 'POST' : 'GET',
+ data: params,
+ dataType: 'json'
+ });
+
+ req.done(callback);
+
+ req.fail(function(jqxhr) {
+ showError(jqxhr.responseJSON || jqxhr.textResponse);
+ });
+ }
+
+ /**
+ * Display the error message
+ *
+ * @param data
+ */
+ function showError(data) {
+ var message = typeof data === 'object' && data.error ? data.error : 'Unexpected error';
+ $('#error').text(message).show();
+ }
+
+ /**
+ * Load and display user info
+ */
+ function loadUserInfo() {
+ doApiRequest('getUserinfo', null, showUserInfo);
+ }
+
+ /**
+ * Display user info
+ *
+ * @param info
+ */
+ function showUserInfo(info) {
+ $('body').removeClass('anonymous authenticated');
+ $('#user-info').html('');
+
+ if (info) {
+ for (var key in info) {
+ $('#user-info').append($('<dt>').text(key));
+ $('#user-info').append($('<dd>').text(info[key]));
+ }
+ }
+
+ $('body').addClass(info ? 'authenticated' : 'anonymous');
+ }
+
+ /**
+ * Submit login form through AJAX
+ */
+ $('#login-form').on('submit', function(e) {
+ e.preventDefault();
+
+ $('#error').text('').hide();
+
+ var data = {
+ username: this.username.value,
+ password: this.password.value
+ };
+
+ doApiRequest('login', data, showUserInfo);
+ });
+
+ $('#logout').on('click', function() {
+ doApiRequest('logout', {}, function() { showUserInfo(null); });
+ })
+}(jQuery);
diff --git a/examples/ajax-broker/index.html b/examples/ajax-broker/index.html
new file mode 100644
index 0000000..8b8a98b
--- /dev/null
+++ b/examples/ajax-broker/index.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Single Sign-On Ajax demo</title>
+ <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
+
+ <style>
+ .state {
+ display: none;
+ }
+ body.anonymous .state.anonymous,
+ body.authenticated .state.authenticated {
+ display: initial;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="container">
+ <h1>Single Sign-On Ajax demo</h1>
+
+ <div id="error" class="alert alert-danger" style="display: none;"></div>
+
+ <form id="login-form" class="form-horizontal state anonymous">
+ <div class="form-group">
+ <label for="inputUsername" class="col-sm-2 control-label">Username</label>
+ <div class="col-sm-10">
+ <input type="text" name="username" class="form-control" id="inputUsername">
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="inputPassword" class="col-sm-2 control-label">Password</label>
+ <div class="col-sm-10">
+ <input type="password" name="password" class="form-control" id="inputPassword">
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="col-sm-offset-2 col-sm-10">
+ <button type="submit" class="btn btn-default">Login</button>
+ </div>
+ </div>
+ </form>
+
+ <div class="state authenticated">
+ <h3>Logged in</h3>
+ <dl id="user-info" class="dl-horizontal"></dl>
+
+ <a id="logout" class="btn btn-default">Logout</a>
+ </div>
+ </div>
+
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
+ <script src="app.js"></script>
+ </body>
+</html>
+
diff --git a/examples/broker/error.php b/examples/broker/error.php
new file mode 100644
index 0000000..52c7a53
--- /dev/null
+++ b/examples/broker/error.php
@@ -0,0 +1,25 @@
+<?php
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET'));
+$error = $_GET['sso_error'];
+
+?>
+<!doctype html>
+<html>
+ <head>
+ <title>Single Sign-On demo (<?= $broker->broker ?>)</title>
+ <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
+ </head>
+ <body>
+ <div class="container">
+ <h1>Single Sign-On demo <small>(<?= $broker->broker ?>)</small></h1>
+
+ <div class="alert alert-danger">
+ <?= $error ?>
+ </div>
+
+ <a href="/">Try again</a>
+ </div>
+ </body>
+</html>
diff --git a/examples/broker/index.php b/examples/broker/index.php
new file mode 100644
index 0000000..2a5f12d
--- /dev/null
+++ b/examples/broker/index.php
@@ -0,0 +1,39 @@
+<?php
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+if (isset($_GET['sso_error'])) {
+ header("Location: error.php?sso_error=" . $_GET['sso_error'], true, 307);
+ exit;
+}
+
+$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET'));
+$broker->attach(true);
+
+$user = $broker->getUserInfo();
+
+if (!$user) {
+ header("Location: login.php", true, 307);
+ exit;
+}
+?>
+<!doctype html>
+<html>
+ <head>
+ <title><?= $broker->broker ?> (Single Sign-On demo)</title>
+ <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
+ </head>
+ <body>
+ <div class="container">
+ <h1><?= $broker->broker ?> <small>(Single Sign-On demo)</small></h1>
+ <h3>Logged in</h3>
+
+ <dl class="dl-horizontal">
+ <?php foreach ($user as $key => $value) : ?>
+ <dt><?= $key ?></dt><dd><?= $value ?></dd>
+ <?php endforeach; ?>
+ </dl>
+
+ <a id="logout" class="btn btn-default" href="login.php?logout=1">Logout</a>
+ </div>
+ </body>
+</html>
diff --git a/examples/broker/login.php b/examples/broker/login.php
new file mode 100644
index 0000000..e51fe39
--- /dev/null
+++ b/examples/broker/login.php
@@ -0,0 +1,56 @@
+<?php
+require_once __DIR__ . '/../../vendor/autoload.php';
+
+$broker = new Jasny\SSO\Broker(getenv('SSO_SERVER'), getenv('SSO_BROKER_ID'), getenv('SSO_BROKER_SECRET'));
+$broker->attach();
+
+if (!empty($_GET['logout'])) {
+ $broker->logout();
+} elseif ($broker->getUserInfo() || ($_SERVER['REQUEST_METHOD'] == 'POST' && $broker->login($_POST['username'], $_POST['password']))) {
+ header("Location: index.php", true, 303);
+ exit;
+}
+
+if ($_SERVER['REQUEST_METHOD'] == 'POST') $errmsg = "Login failed";
+?>
+<!doctype html>
+<html>
+ <head>
+ <title><?= $broker->broker ?> | Login (Single Sign-On demo)</title>
+ <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
+
+ <style>
+ h1 {
+ margin-bottom: 30px;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="container">
+ <h1><?= $broker->broker ?> <small>(Single Sign-On demo)</small></h1>
+
+ <?php if (isset($errmsg)): ?><div class="alert alert-danger"><?= $errmsg ?></div><?php endif; ?>
+
+ <form class="form-horizontal" action="login.php" method="post">
+ <div class="form-group">
+ <label for="inputUsername" class="col-sm-2 control-label">Username</label>
+ <div class="col-sm-10">
+ <input type="text" name="username" class="form-control" id="inputUsername">
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="inputPassword" class="col-sm-2 control-label">Password</label>
+ <div class="col-sm-10">
+ <input type="password" name="password" class="form-control" id="inputPassword">
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="col-sm-offset-2 col-sm-10">
+ <button type="submit" class="btn btn-default">Login</button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </body>
+</html>
diff --git a/examples/server/.htaccess b/examples/server/.htaccess
new file mode 100644
index 0000000..7bb4b5b
--- /dev/null
+++ b/examples/server/.htaccess
@@ -0,0 +1,6 @@
+RewriteEngine On
+
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule (.+) index.php?command=$1 [L]
+
diff --git a/examples/server/MySSOServer.php b/examples/server/MySSOServer.php
new file mode 100644
index 0000000..ca523b0
--- /dev/null
+++ b/examples/server/MySSOServer.php
@@ -0,0 +1,90 @@
+<?php
+
+use Jasny\ValidationResult;
+use Jasny\SSO;
+
+/**
+ * Example SSO server.
+ *
+ * Normally you'd fetch the broker info and user info from a database, rather then declaring them in the code.
+ */
+class MySSOServer extends SSO\Server
+{
+ /**
+ * Registered brokers
+ * @var array
+ */
+ private static $brokers = [
+ 'Alice' => ['secret'=>'8iwzik1bwd'],
+ 'Greg' => ['secret'=>'7pypoox2pc'],
+ 'Julias' => ['secret'=>'ceda63kmhp']
+ ];
+
+ /**
+ * System users
+ * @var array
+ */
+ private static $users = array (
+ 'jackie' => [
+ 'fullname' => 'Jackie Black',
+ 'email' => 'jackie.black@example.com',
+ 'password' => '$2y$10$lVUeiphXLAm4pz6l7lF9i.6IelAqRxV4gCBu8GBGhCpaRb6o0qzUO' // jackie123
+ ],
+ 'john' => [
+ 'fullname' => 'John Doe',
+ 'email' => 'john.doe@example.com',
+ 'password' => '$2y$10$RU85KDMhbh8pDhpvzL6C5.kD3qWpzXARZBzJ5oJ2mFoW7Ren.apC2' // john123
+ ],
+ );
+
+ /**
+ * Get the API secret of a broker and other info
+ *
+ * @param string $brokerId
+ * @return array
+ */
+ protected function getBrokerInfo($brokerId)
+ {
+ return isset(self::$brokers[$brokerId]) ? self::$brokers[$brokerId] : null;
+ }
+
+ /**
+ * Authenticate using user credentials
+ *
+ * @param string $username
+ * @param string $password
+ * @return ValidationResult
+ */
+ protected function authenticate($username, $password)
+ {
+ if (!isset($username)) {
+ return ValidationResult::error("username isn't set");
+ }
+
+ if (!isset($password)) {
+ return ValidationResult::error("password isn't set");
+ }
+
+ if (!isset(self::$users[$username]) || !password_verify($password, self::$users[$username]['password'])) {
+ return ValidationResult::error("Invalid credentials");
+ }
+
+ return ValidationResult::success();
+ }
+
+
+ /**
+ * Get the user information
+ *
+ * @return array
+ */
+ protected function getUserInfo($username)
+ {
+ if (!isset(self::$users[$username])) return null;
+
+ $user = compact('username') + self::$users[$username];
+ unset($user['password']);
+
+ return $user;
+ }
+}
diff --git a/examples/server/index.php b/examples/server/index.php
new file mode 100644
index 0000000..5416eb9
--- /dev/null
+++ b/examples/server/index.php
@@ -0,0 +1,18 @@
+<?php
+
+require_once __DIR__ . '/../../vendor/autoload.php';
+require_once 'MySSOServer.php';
+
+$ssoServer = new MySSOServer();
+$command = isset($_REQUEST['command']) ? $_REQUEST['command'] : null;
+
+if (!$command || !method_exists($ssoServer, $command)) {
+ header("HTTP/1.1 404 Not Found");
+ header('Content-type: application/json; charset=UTF-8');
+
+ echo json_encode(['error' => 'Unknown command']);
+ exit();
+}
+
+$result = $ssoServer->$command();
+