Procházet zdrojové kódy

Merge remote-tracking branch 'origin/1.10.x' into 1.10.x

Yannick Warnier před 8 roky
rodič
revize
2524fc9f54

+ 17 - 0
plugin/azure_active_directory/README.md

@@ -0,0 +1,17 @@
+# The Azure Active Directory Plugin
+Allow authentication with Microsoft's Azure Active Directory
+
+### To configure Azure Active Directory
+* [Create an Azure AD B2C tenant](https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-get-started/)
+* [Register your application](https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-app-registration/)
+* [Configure Facebook, Google+, Microsoft account, Amazon, and LinkedIn accounts for use in your consumer-facing applications](https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-overview/#how-to-articles)
+
+### To configure this plugin
+* Enable
+* Application ID: Enter the Application Id assinged to your app by the Azure portal, e.g. 580e250c-8f26-49d0-bee8-1c078add1609
+* Tenant: Enter the name of your B2C directory, e.g. contoso.onmicrosoft.com
+* Sign up policy: Enter your sign up policy name, e.g. b2c_1_sign_up
+* Sign in policy: Enter your sign in policy name, e.g. b2c_1_sign_in
+* Block name: (Optional) The name to show above the buttons
+
+And assign a region. Preferably `login_bottom`

+ 14 - 0
plugin/azure_active_directory/index.php

@@ -0,0 +1,14 @@
+<?php
+/* For licensing terms, see /license.txt */
+/**
+ * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
+ * @package chamilo.plugin.azure_active_directory
+ */
+$activeDirectoryPlugin = AzureActiveDirectory::create();
+
+if ($activeDirectoryPlugin->get(AzureActiveDirectory::SETTING_ENABLE) === 'true') {
+    $_template['block_title'] = $activeDirectoryPlugin->get(AzureActiveDirectory::SETTING_BLOCK_NAME);
+    $_template['signup_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNUP);
+    $_template['signin_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNIN);
+    $_template['signout_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNOUT);
+}

+ 20 - 0
plugin/azure_active_directory/lang/english.php

@@ -0,0 +1,20 @@
+<?php
+/* For licensing terms, see /license.txt */
+/**
+ * Strings to english L10n
+ * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
+ * @package chamilo.plugin.azure_active_directory
+ */
+$strings['plugin_title'] = 'Azure Active Directory';
+$strings['plugin_comment'] = 'Allow authentication with Microsoft\'s Azure Active Directory';
+
+$strings['enable'] = 'Enable';
+$strings['app_id'] = 'Application ID';
+$strings['app_id_help'] = 'Enter the Application Id assinged to your app by the Azure portal, e.g. 580e250c-8f26-49d0-bee8-1c078add1609';
+$strings['tenant'] = 'Tenant';
+$strings['tenant_help'] = 'Enter the name of your B2C directory, e.g. contoso.onmicrosoft.com';
+$strings['signup_policy'] = 'Sign up policy';
+$strings['signup_policy_help'] = 'Enter your sign up policy name, e.g.g b2c_1_sign_up';
+$strings['signin_policy'] = 'Sign in policy';
+$strings['signin_policy_help'] = 'Enter your sign in policy name, e.g. b2c_1_sign_in';
+$strings['block_name'] = 'Block name';

+ 9 - 0
plugin/azure_active_directory/plugin.php

@@ -0,0 +1,9 @@
+<?php
+/* For licensing terms, see /license.txt */
+/**
+ * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
+ * @package chamilo.plugin.azure_active_directory
+ */
+$plugin_info = AzureActiveDirectory::create()->get_info();
+
+$plugin_info['templates'] = array('view/block.tpl');

+ 30 - 0
plugin/azure_active_directory/readme.txt

@@ -0,0 +1,30 @@
+<h1 class="page-header">The Azure Active Directory Plugin</h1>
+<p>Allow authentication with Microsoft's Azure Active Directory</p>
+<h3>To configure Azure Active Directory</h3>
+<ul>
+    <li>
+        <a href="https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-get-started/">
+            Create an Azure AD B2C tenant
+        </a>
+    </li>
+    <li>
+        <a href="https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-app-registration/">
+            Register your application
+        </a>
+    </li>
+    <li>
+        <a href="https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-overview/#how-to-articles">
+            Configure Facebook, Google+, Microsoft account, Amazon, and LinkedIn accounts for use in your consumer-facing applications
+        </a>
+    </li>
+</ul>
+<h3>To configure this plugin</h3>
+<ul>
+    <li>Enable</li>
+    <li>Application ID: Enter the Application Id assinged to your app by the Azure portal, e.g. 580e250c-8f26-49d0-bee8-1c078add1609</li>
+    <li>Tenant: Enter the name of your B2C directory, e.g. contoso.onmicrosoft.com</li>
+    <li>Sign up policy: Enter your sign up policy name, e.g. b2c_1_sign_up</li>
+    <li>Sign in policy: Enter your sign in policy name, e.g. b2c_1_sign_in</li>
+    <li>Block name: (Optional) The name to show above the buttons</li>
+</ul>
+<p>And assign a region. Preferably <code>login_bottom</code></p>

+ 102 - 0
plugin/azure_active_directory/src/AzureActiveDirectory.php

@@ -0,0 +1,102 @@
+<?php
+/**
+ * AzureActiveDirectory plugin class
+ * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
+ * @package chamilo.plugin.azure_active_directory
+ */
+class AzureActiveDirectory extends Plugin
+{
+    const SETTING_ENABLE = 'enable';
+    const SETTING_APP_ID = 'app_id';
+    const SETTING_TENANT = 'tenant';
+    const SETTING_SIGNUP_POLICY = 'signup_policy';
+    const SETTING_SIGNIN_POLICY = 'signin_policy';
+    const SETTING_BLOCK_NAME = 'block_name';
+    const URL_TYPE_SIGNUP = 'sign-up';
+    const URL_TYPE_SIGNIN = 'sign-in';
+    const URL_TYPE_SIGNOUT = 'sign-out';
+
+    /**
+     * AzureActiveDirectory constructor.
+     */
+    protected function __construct()
+    {
+        $settings = [
+            self::SETTING_ENABLE => 'boolean',
+            self::SETTING_APP_ID => 'text',
+            self::SETTING_TENANT => 'text',
+            self::SETTING_SIGNUP_POLICY => 'text',
+            self::SETTING_SIGNIN_POLICY => 'text',
+            self::SETTING_BLOCK_NAME => 'text'
+        ];
+
+        parent::__construct('1.0', 'Angel Fernando Quiroz Campos', $settings);
+    }
+
+    /**
+     * Instance the plugin
+     * @staticvar null $result
+     * @return Tour
+     */
+    static function create()
+    {
+        static $result = null;
+
+        return $result ? $result : $result = new self();
+    }
+
+    /**
+     * @return string
+     */
+    public function get_name()
+    {
+        return 'azure_active_directory';
+    }
+
+    /**
+     * @param $urlType Type of URL to generate
+     * @return string
+     */
+    public function getUrl($urlType)
+    {
+        $settingsInfo = $this->get_settings();
+        $settings = [];
+
+        foreach ($settingsInfo as $settingInfo) {
+            $variable = str_replace($this->get_name() . '_', '', $settingInfo['variable']);
+
+            $settings[$variable] = $settingInfo['selected_value'];
+        }
+
+        $url = "https://login.microsoftonline.com/{$settings[self::SETTING_TENANT]}/oauth2/v2.0/";
+        $callback = api_get_path(WEB_PLUGIN_PATH) . $this->get_name() . '/src/callback.php';
+
+        if ($urlType === self::URL_TYPE_SIGNOUT) {
+            $action = 'logout';
+            $urlParams = [
+                'p' => $settings[self::SETTING_SIGNIN_POLICY],
+                'post_logout_redirect_uri' => $callback
+            ];
+        } else {
+            $action = 'authorize';
+            $policy = $settings[self::SETTING_SIGNUP_POLICY];
+
+            if ($urlType === self::URL_TYPE_SIGNIN) {
+                $policy = $settings[self::SETTING_SIGNIN_POLICY];
+            }
+
+            $urlParams = [
+                'client_id' => $settings[self::SETTING_APP_ID],
+                'response_type' => 'id_token',
+                'redirect_uri' => $callback,
+                'scope' => 'openid',
+                'response_mode' => 'form_post',
+                'state' => time(),
+                'nonce' => time(),
+                'p' => $policy
+            ];
+        }
+
+        return $url . $action . '?' . http_build_query($urlParams);
+    }
+}

+ 55 - 0
plugin/azure_active_directory/src/callback.php

@@ -0,0 +1,55 @@
+<?php
+require dirname(__FILE__) . '/../../../main/inc/global.inc.php';
+require_once dirname(__FILE__) . '/../../../main/auth/external_login/functions.inc.php';
+
+if (isset($_POST['error']) || empty($_REQUEST)) {
+    header('Location: ' . api_get_path(WEB_PATH) . 'index.php?logout=logout');
+    exit;
+}
+
+list($jwtHeader, $jwtPayload, $jwtSignature) = explode('.', $_REQUEST['id_token']);
+
+$jwtHeader = json_decode(
+    base64_decode($jwtHeader)
+);
+
+$jwtPayload = json_decode(
+    base64_decode($jwtPayload)
+);
+
+$u = array(
+    'firstname' => $jwtPayload->given_name,
+    'lastname' => $jwtPayload->family_name,
+    'status' => STUDENT,
+    'email' => $jwtPayload->emails[0],
+    'username' => $jwtPayload->emails[0],
+    'language' => 'en',
+    'password' => 'azure_active_directory',
+    'auth_source' => 'azure_active_directory ' . $jwtPayload->idp,
+    'extra' => array()
+);
+
+$userInfo = api_get_user_info_from_email($jwtPayload->emails[0]);
+
+if ($userInfo === false) {
+    // we have to create the user
+    $chamilo_uid = external_add_user($u);
+
+    if ($chamilo_uid !== false) {
+        $_user['user_id'] = $chamilo_uid;
+        $_user['uidReset'] = true;
+        $_SESSION['_user'] = $_user;
+    }
+} else {
+    // User already exists, update info and login
+    $chamilo_uid = $userInfo['user_id'];
+    $u['user_id'] = $chamilo_uid;
+    external_update_user($u);
+
+    $_user['user_id'] = $chamilo_uid;
+    $_user['uidReset'] = true;
+    $_SESSION['_user'] = $_user;
+}
+
+header('Location: ' . api_get_path(WEB_PATH));
+exit;

+ 12 - 0
plugin/azure_active_directory/view/block.tpl

@@ -0,0 +1,12 @@
+<div id="azure-active-directory-login">
+    {% if _u.logged %}
+        {# <a href="{{ azure_active_directory.signout_url }}" class="btn btn-primary">{{ 'Logout'|get_lang }}</a> #}
+    {% else %}
+        {% if not azure_active_directory.block_title is empty %}
+            <h4>{{ azure_active_directory.block_title }}</h4>
+        {% endif %}
+
+        <a href="{{ azure_active_directory.signin_url }}" class="btn btn-default">{{ 'SignIn'|get_lang }}</a>
+        <a href="{{ azure_active_directory.signup_url }}" class="btn btn-success">{{ 'SignUp'|get_lang }}</a>
+    {% endif %}
+</div>