diff options
49 files changed, 1196 insertions, 0 deletions
diff --git a/PluggableAuth/.dir-locals.el b/PluggableAuth/.dir-locals.el new file mode 100644 index 00000000..22804955 --- /dev/null +++ b/PluggableAuth/.dir-locals.el @@ -0,0 +1,88 @@ +((nil . ((mode . flycheck) + (mode . company) + (mode . edep) + (mode . subword) + (tab-width . 4) + (c-basic-offset . 4) + (indent-tabs-mode . t) + (eval . (progn (when (fboundp 'delete-trailing-whitespace) + (delete-trailing-whitespace)) + (tabify (point-min) (point-max)))) + (c-hanging-braces-alist + (defun-open after) + (block-open after) + (defun-close)) + (c-offsets-alist . ( + (access-label . -) + (annotation-top-cont . 0) + (annotation-var-cont . +) + (arglist-close . php-lineup-arglist-close) + (arglist-cont-nonempty first + php-lineup-cascaded-calls + c-lineup-arglist) + (arglist-intro . php-lineup-arglist-intro) + (block-close . 0) + (block-open . 0) + (brace-entry-open . 0) + (brace-list-close . 0) + (brace-list-entry . 0) + (brace-list-intro . +) + (brace-list-open . 0) + (c . c-lineup-C-comments) + (case-label . 0) + (catch-clause . 0) + (class-close . 0) + (comment-intro . 0) + (composition-close . 0) + (composition-open . 0) + (cpp-define-intro c-lineup-cpp-define +) + (cpp-macro . [0]) + (cpp-macro-cont . +) + (defun-block-intro . +) + (defun-close . 0) + (defun-open . 0) + (do-while-closure . 0) + (else-clause . 0) + (extern-lang-close . 0) + (extern-lang-open . 0) + (friend . 0) + (func-decl-cont . +) + (inclass . +) + (incomposition . +) + (inexpr-class . +) + (inexpr-statement . +) + (inextern-lang . +) + (inher-cont . c-lineup-multi-inher) + (inher-intro . +) + (inlambda . 0) + (inline-close . 0) + (inline-open . 0) + (inmodule . +) + (innamespace . +) + (knr-argdecl . 0) + (knr-argdecl-intro . +) + (label . +) + (lambda-intro-cont . +) + (member-init-cont . c-lineup-multi-inher) + (member-init-intro . +) + (module-close . 0) + (module-open . 0) + (namespace-close . 0) + (namespace-open . 0) + (statement . 0) + (statement-block-intro . +) + (statement-case-intro . +) + (statement-case-open . 0) + (statement-cont first + php-lineup-cascaded-calls + php-lineup-string-cont +) + (stream-op . c-lineup-streamop) + (string . c-lineup-dont-change) + (substatement . +) + (substatement-label . 2) + (substatement-open . 0) + (template-args-cont c-lineup-template-args +) + (topmost-intro . 0) + (topmost-intro-cont first php-lineup-cascaded-calls +) + )) + ))) diff --git a/PluggableAuth/.gitignore b/PluggableAuth/.gitignore new file mode 100644 index 00000000..8aa2a07f --- /dev/null +++ b/PluggableAuth/.gitignore @@ -0,0 +1,23 @@ +node_modules/ +vendor/ +composer.lock + +# Editors +*.kate-swp +*~ +\#*# +.#* +.*.swp +.project +.buildpath +.classpath +.settings +cscope.files +cscope.out +*.orig +## NetBeans +nbproject* +project.index +## Sublime +sublime-* +sftp-config.json diff --git a/PluggableAuth/.gitreview b/PluggableAuth/.gitreview new file mode 100644 index 00000000..5376489b --- /dev/null +++ b/PluggableAuth/.gitreview @@ -0,0 +1,6 @@ +[gerrit] +host=gerrit.wikimedia.org +port=29418 +project=mediawiki/extensions/PluggableAuth.git +track=1 +defaultrebase=0 diff --git a/PluggableAuth/.phpcs.xml b/PluggableAuth/.phpcs.xml new file mode 100644 index 00000000..b915cf83 --- /dev/null +++ b/PluggableAuth/.phpcs.xml @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<ruleset> + <rule ref="./vendor/mediawiki/mediawiki-codesniffer/MediaWiki" /> + <file>.</file> + <arg name="extensions" value="php"/> + <arg name="encoding" value="UTF-8"/> +</ruleset> diff --git a/PluggableAuth/.phpmd.xml b/PluggableAuth/.phpmd.xml new file mode 100644 index 00000000..2c2ab34c --- /dev/null +++ b/PluggableAuth/.phpmd.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<ruleset xmlns="http://pmd.sf.net/ruleset/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" + xsi:noNamespaceSchemaLocation=" http://pmd.sf.net/ruleset_xml_schema.xsd"> + + <rule ref="rulesets/codesize.xml"> + <exclude name="TooManyMethods" /> + <exclude name="ExcessiveClassComplexity" /> + </rule> + <rule ref="rulesets/codesize.xml/TooManyMethods"> + <properties> + <property name="maxmethods" value="20" /> + </properties> + </rule> + + <!-- todo: exclude the camel case method rule for the tests --> + <rule ref="rulesets/controversial.xml" /> + + <rule ref="rulesets/design.xml" /> + + <rule ref="rulesets/naming.xml"> + <exclude name="ShortVariable" /> + </rule> + + <rule ref="rulesets/unusedcode.xml"> + <exclude name="UnusedLocalVariable" /> + </rule> +</ruleset> diff --git a/PluggableAuth/CODE_OF_CONDUCT.md b/PluggableAuth/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..d8e5d087 --- /dev/null +++ b/PluggableAuth/CODE_OF_CONDUCT.md @@ -0,0 +1 @@ +The development of this software is covered by a [Code of Conduct](https://www.mediawiki.org/wiki/Code_of_Conduct). diff --git a/PluggableAuth/COPYING b/PluggableAuth/COPYING new file mode 100644 index 00000000..69cbaabb --- /dev/null +++ b/PluggableAuth/COPYING @@ -0,0 +1,19 @@ +Copyright (c) 2015-2017 The MITRE Corporation + +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. diff --git a/PluggableAuth/Gruntfile.js b/PluggableAuth/Gruntfile.js new file mode 100644 index 00000000..a45071e1 --- /dev/null +++ b/PluggableAuth/Gruntfile.js @@ -0,0 +1,21 @@ +/*jshint node:true */ +module.exports = function ( grunt ) { + grunt.loadNpmTasks( 'grunt-jsonlint' ); + grunt.loadNpmTasks( 'grunt-banana-checker' ); + + grunt.initConfig( { + banana: { + all: 'i18n/' + }, + jsonlint: { + all: [ + '**/*.json', + '!node_modules/**', + '!vendor/**' + ] + } + } ); + + grunt.registerTask( 'test', [ 'jsonlint', 'banana' ] ); + grunt.registerTask( 'default', 'test' ); +}; diff --git a/PluggableAuth/composer.json b/PluggableAuth/composer.json new file mode 100644 index 00000000..0e7c221d --- /dev/null +++ b/PluggableAuth/composer.json @@ -0,0 +1,41 @@ +{ + "name": "mediawiki/pluggable-auth", + "license": "MIT", + "type": "mediawiki-extension", + "homepage": "https://www.mediawiki.org/wiki/Extension:PluggableAuth", + "description": "An authentication framework for MediaWiki", + "keywords": [ + "extension", + "wiki", + "mediawiki", + "authentication" + ], + "authors": [ + { + "name": "Cindy Cicalese", + "email": "cindom@gmail.com", + "role": "Contributor" + } + ], + "require-dev": { + "jakub-onderka/php-parallel-lint": "1.0.0", + "jakub-onderka/php-console-highlighter": "0.3.2", + "mediawiki/minus-x": "0.3.1", + "mediawiki/mediawiki-codesniffer": "18.0.0", + "phpmd/phpmd": "~2.1" + }, + "scripts": { + "phpunit": "php $MW_INSTALL_PATH/tests/phpunit/phpunit.php -c .phpunit.xml.dist", + "phpdbg": "phpdbg -qrr $MW_INSTALL_PATH/tests/phpunit/phpunit.php -c .phpunit.xml.dist", + "test": [ + "parallel-lint . --exclude vendor --exclude node_modules", + "minus-x check .", + "phpmd includes text .phpmd.xml || :", + "phpcs -p -s" + ], + "fix": [ + "minus-x fix .", + "phpcbf" + ] + } +} diff --git a/PluggableAuth/extension.json b/PluggableAuth/extension.json new file mode 100644 index 00000000..39667cdd --- /dev/null +++ b/PluggableAuth/extension.json @@ -0,0 +1,57 @@ +{ + "name": "PluggableAuth", + "version": "5.4", + "author": [ + "[https://www.mediawiki.org/wiki/User:Cindy.cicalese Cindy Cicalese]" + ], + "url": "https://www.mediawiki.org/wiki/Extension:PluggableAuth", + "descriptionmsg": "pluggableauth-desc", + "type": "other", + "SpecialPages": { + "PluggableAuthLogin": "PluggableAuthLogin" + }, + "MessagesDirs": { + "PluggableAuth": [ + "i18n" + ] + }, + "ExtensionMessagesFiles": { + "PluggableAuthAlias": "includes/PluggableAuth.alias.php" + }, + "AutoloadClasses": { + "PluggableAuth": "includes/PluggableAuth.php", + "PluggableAuthHooks": "includes/PluggableAuthHooks.php", + "PluggableAuthPrimaryAuthenticationProvider": "includes/PluggableAuthPrimaryAuthenticationProvider.php", + "PluggableAuthBeginAuthenticationRequest": "includes/PluggableAuthBeginAuthenticationRequest.php", + "PluggableAuthContinueAuthenticationRequest": "includes/PluggableAuthContinueAuthenticationRequest.php", + "PluggableAuthLogin": "includes/PluggableAuthLogin.php" + }, + "callback": "PluggableAuthHooks::onRegistration", + "Hooks": { + "TitleReadWhitelist": "PluggableAuthHooks::onTitleReadWhitelist", + "UserLogoutComplete": "PluggableAuthHooks::deauthenticate", + "AuthChangeFormFields": "PluggableAuthHooks::onAuthChangeFormFields", + "PersonalUrls": "PluggableAuthHooks::modifyLoginURLs", + "BeforeInitialize": "PluggableAuthHooks::doBeforeInitialize" + }, + "AuthManagerAutoConfig": { + "primaryauth": { + "PluggableAuthPrimaryAuthenticationProvider": { + "class": "PluggableAuthPrimaryAuthenticationProvider", + "sort": 0 + } + } + }, + "PluggableAuthLoginSpecialPages": [ + "PluggableAuthLogin", + "Userlogin" + ], + "config": { + "PluggableAuth_EnableAutoLogin": false, + "PluggableAuth_EnableLocalLogin": false, + "PluggableAuth_EnableLocalProperties": false, + "PluggableAuth_ButtonLabel": null, + "PluggableAuth_ExtraLoginFields": [] + }, + "manifest_version": 1 +} diff --git a/PluggableAuth/gitinfo.json b/PluggableAuth/gitinfo.json new file mode 100644 index 00000000..c7656a1e --- /dev/null +++ b/PluggableAuth/gitinfo.json @@ -0,0 +1 @@ +{"branch": "300ac44dde702b9f36fab06c7d75f943d89c510c\n", "headSHA1": "300ac44dde702b9f36fab06c7d75f943d89c510c\n", "remoteURL": "https://gerrit-replica.wikimedia.org/r/mediawiki/extensions/PluggableAuth", "headCommitDate": "1523683714", "head": "300ac44dde702b9f36fab06c7d75f943d89c510c\n"}
\ No newline at end of file diff --git a/PluggableAuth/i18n/ast.json b/PluggableAuth/i18n/ast.json new file mode 100644 index 00000000..0c7e1a82 --- /dev/null +++ b/PluggableAuth/i18n/ast.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Xuacu" + ] + }, + "pluggableauth-desc": "Ufre un marcu p'autenticación y autorización coneutable", + "pluggableauth-not-authorized": "{{GENDER:$1|L'usuariu|La usuaria}} $1 nun ta {{GENDER:$1|autorizáu|autorizada}}.", + "pluggableauth-authentication-failure": "Fallu n'autenticación o autorización.", + "pluggableauth-authentication-workflow-failure": "Fallu nel procesu d'autenticación.", + "pluggableauth-loginbutton-label": "Aniciar sesión con PluggableAuth", + "pluggableauth-loginbutton-help": "Autentícate con PluggableAuth" +} diff --git a/PluggableAuth/i18n/be-tarask.json b/PluggableAuth/i18n/be-tarask.json new file mode 100644 index 00000000..c8507ea1 --- /dev/null +++ b/PluggableAuth/i18n/be-tarask.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Red Winged Duck" + ] + }, + "pluggableauth-desc": "Забясьпечвае структуру для зьменнай аўтэнтыфікацыі і аўтарызацыі", + "pluggableauth-not-authorized": "{{GENDER:$1|Удзельнік|Удзельніца}} $1 не {{GENDER:$1|аўтарызаваны|аўтарызаваная}}.", + "pluggableauth-authentication-failure": "Удзельнік ня можа быць аўтэнтыфікаваны.", + "pluggableauth-authentication-workflow-failure": "Памылка працэсу аўтэнтыфікацыі.", + "pluggableauth-loginbutton-label": "Увайсьці ў сыстэму з дапамогай PluggableAuth", + "pluggableauth-loginbutton-help": "Аўтэнтыфікуе вас з дапамогай PluggableAuth" +} diff --git a/PluggableAuth/i18n/de.json b/PluggableAuth/i18n/de.json new file mode 100644 index 00000000..f3723e5c --- /dev/null +++ b/PluggableAuth/i18n/de.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Metalhead64" + ] + }, + "pluggableauth-desc": "Ergänzt ein Framework zur Authentifikation und Autorisierung", + "pluggableauth-not-authorized": "{{GENDER:$1|Der Benutzer|Die Benutzerin}} $1 ist nicht berechtigt.", + "pluggableauth-authentication-failure": "Der Benutzer konnte nicht authentifiziert werden.", + "pluggableauth-authentication-workflow-failure": "Authentifikations-Workflow-Fehler.", + "pluggableauth-loginbutton-label": "Mit PluggableAuth anmelden", + "pluggableauth-loginbutton-help": "Authentifiziert dich mit PluggableAuth" +} diff --git a/PluggableAuth/i18n/el.json b/PluggableAuth/i18n/el.json new file mode 100644 index 00000000..5ebbcbb3 --- /dev/null +++ b/PluggableAuth/i18n/el.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Nikosgranturismogt" + ] + }, + "pluggableauth-loginbutton-label": "Συνδεθείτε με το PluggableAuth" +} diff --git a/PluggableAuth/i18n/en.json b/PluggableAuth/i18n/en.json new file mode 100644 index 00000000..575186c3 --- /dev/null +++ b/PluggableAuth/i18n/en.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "cicalese" + ] + }, + "pluggableauth-desc": "Provides framework for pluggable authentication and authorization", + "pluggableauth-not-authorized": "{{GENDER:$1|User}} $1 not authorized.", + "pluggableauth-authentication-failure": "User cannot be authenticated.", + "pluggableauth-authentication-workflow-failure": "Authentication workflow failure.", + "pluggableauth-loginbutton-label": "Log in with PluggableAuth", + "pluggableauth-loginbutton-help": "Authenticates you with PluggableAuth" +} diff --git a/PluggableAuth/i18n/es.json b/PluggableAuth/i18n/es.json new file mode 100644 index 00000000..8d9b4ff9 --- /dev/null +++ b/PluggableAuth/i18n/es.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Macofe" + ] + }, + "pluggableauth-desc": "Proporciona el marco para anexar autenticación y autorización", + "pluggableauth-not-authorized": "{{GENDER:$1|El usuario|La usuaria}} $1 no está {{GENDER:$1|autorizado|autorizada}}.", + "pluggableauth-authentication-failure": "El usuario no puede autenticarse." +} diff --git a/PluggableAuth/i18n/fi.json b/PluggableAuth/i18n/fi.json new file mode 100644 index 00000000..2e3edf3f --- /dev/null +++ b/PluggableAuth/i18n/fi.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Nike", + "Olkitu" + ] + }, + "pluggableauth-not-authorized": "{{GENDER:$1|Käyttäjää}} $1 ei ole valtuutettu.", + "pluggableauth-authentication-failure": "Kirjautuminen epäonnistui.", + "pluggableauth-loginbutton-label": "Kirjaudu PluggableAuth:lla.", + "pluggableauth-loginbutton-help": "Kirjauduttu PluggableAuth avulla." +} diff --git a/PluggableAuth/i18n/fr.json b/PluggableAuth/i18n/fr.json new file mode 100644 index 00000000..faeac847 --- /dev/null +++ b/PluggableAuth/i18n/fr.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Wladek92", + "Gomoko", + "Urhixidur" + ] + }, + "pluggableauth-desc": "Fournit le cadre d’application pour les greffons d’authentication et d’autorisation", + "pluggableauth-not-authorized": "Utilisat{{GENDER:$1|eur|rice}} $1 non autorisé{{GENDER:$1||e}}.", + "pluggableauth-authentication-failure": "L’utilisateur n’a pas pu être authentifié.", + "pluggableauth-authentication-workflow-failure": "Échec du processus d’authentification.", + "pluggableauth-loginbutton-label": "Se connecter avec PluggableAuth", + "pluggableauth-loginbutton-help": "Vous authentifie avec PluggableAuth" +} diff --git a/PluggableAuth/i18n/gl.json b/PluggableAuth/i18n/gl.json new file mode 100644 index 00000000..8a54011b --- /dev/null +++ b/PluggableAuth/i18n/gl.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Elisardojm" + ] + }, + "pluggableauth-desc": "Proporciona o marco para anexar autenticación e autorización", + "pluggableauth-not-authorized": "{{GENDER:$1|O usuario|A usuaria}} $1 non está {{GENDER:$1|autorizado|autorizada}}.", + "pluggableauth-authentication-failure": "O usuario non pode autenticarse.", + "pluggableauth-authentication-workflow-failure": "Fallo no proceso de autenticación.", + "pluggableauth-loginbutton-label": "Conectarse con PluggableAuth", + "pluggableauth-loginbutton-help": "Autentícao con PluggableAuth" +} diff --git a/PluggableAuth/i18n/it.json b/PluggableAuth/i18n/it.json new file mode 100644 index 00000000..bdde8193 --- /dev/null +++ b/PluggableAuth/i18n/it.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Beta16" + ] + }, + "pluggableauth-not-authorized": "Utente $1 non {{GENDER:$1|autorizzato|autorizzata|autorizzato/a}}.", + "pluggableauth-loginbutton-label": "Accedi con PluggableAuth", + "pluggableauth-loginbutton-help": "Autenticati con PluggableAuth" +} diff --git a/PluggableAuth/i18n/ko.json b/PluggableAuth/i18n/ko.json new file mode 100644 index 00000000..96e670f1 --- /dev/null +++ b/PluggableAuth/i18n/ko.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Revi", + "Ykhwong" + ] + }, + "pluggableauth-desc": "플러그 가능한 식별과 인증을 위한 프레임워크 제공", + "pluggableauth-not-authorized": "$1 {{GENDER:$1|사용자}}가 인증되지 않았습니다.", + "pluggableauth-authentication-failure": "사용자를 인증할 수 없습니다.", + "pluggableauth-loginbutton-label": "PluggableAuth로 로그인" +} diff --git a/PluggableAuth/i18n/ksh.json b/PluggableAuth/i18n/ksh.json new file mode 100644 index 00000000..ae7b2344 --- /dev/null +++ b/PluggableAuth/i18n/ksh.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Purodha" + ] + }, + "pluggableauth-desc": "Brängk ene Rahme för ußtuuschbahre Ongerprojramme för et Aanmällde un esu.", + "pluggableauth-not-authorized": "{{GENDER:$1|Dä Metmaacher|De Metmaacherėn|Dä Metmaacher|De Metmaacherėn|Dä Metmaacher}} es nit berääschtesch." +} diff --git a/PluggableAuth/i18n/lb.json b/PluggableAuth/i18n/lb.json new file mode 100644 index 00000000..96cc722f --- /dev/null +++ b/PluggableAuth/i18n/lb.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Robby" + ] + }, + "pluggableauth-not-authorized": "{{GENDER:$1|De Benotzer}} $1 ass net autoriséiert.", + "pluggableauth-authentication-failure": "Benotzer kann net authentifizéiert ginn.", + "pluggableauth-loginbutton-label": "Mat PluggableAuth aloggen", + "pluggableauth-loginbutton-help": "Authentifizéiert Iech mat PluggableAuth" +} diff --git a/PluggableAuth/i18n/lv.json b/PluggableAuth/i18n/lv.json new file mode 100644 index 00000000..c11b2504 --- /dev/null +++ b/PluggableAuth/i18n/lv.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Papuass" + ] + }, + "pluggableauth-authentication-failure": "Lietotāju nevar autentificēt." +} diff --git a/PluggableAuth/i18n/mk.json b/PluggableAuth/i18n/mk.json new file mode 100644 index 00000000..efed3479 --- /dev/null +++ b/PluggableAuth/i18n/mk.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Bjankuloski06" + ] + }, + "pluggableauth-desc": "Дава рамка за приклучна заверка и овластување", + "pluggableauth-not-authorized": "{{GENDER:$1|Корисникот}} $1 не е овластен.", + "pluggableauth-authentication-failure": "Неуспешна заверка или овластување.", + "pluggableauth-authentication-workflow-failure": "Неупех во работниот тек на заверката.", + "pluggableauth-loginbutton-label": "Најава со PluggableAuth", + "pluggableauth-loginbutton-help": "Ве заверува со PluggableAuth" +} diff --git a/PluggableAuth/i18n/ms.json b/PluggableAuth/i18n/ms.json new file mode 100644 index 00000000..713aeb97 --- /dev/null +++ b/PluggableAuth/i18n/ms.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Anakmalaysia" + ] + }, + "pluggableauth-not-authorized": "{{GENDER:$1|Pengguna}} $1 tidak diizinkan." +} diff --git a/PluggableAuth/i18n/nl.json b/PluggableAuth/i18n/nl.json new file mode 100644 index 00000000..3551e265 --- /dev/null +++ b/PluggableAuth/i18n/nl.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Esketti" + ] + }, + "pluggableauth-desc": "Biedt een kader voor pluggable authenticatie en autorisatie", + "pluggableauth-not-authorized": "{{GENDER:$1|Gebruikers}} $1 niet toegestaan." +} diff --git a/PluggableAuth/i18n/oc.json b/PluggableAuth/i18n/oc.json new file mode 100644 index 00000000..f2bac0b7 --- /dev/null +++ b/PluggableAuth/i18n/oc.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Cedric31" + ] + }, + "pluggableauth-not-authorized": "{{GENDER:$1|Utilizaire|Utilizaira}} $1 pas {{GENDER:$1|autorizat|autorizada}}." +} diff --git a/PluggableAuth/i18n/pl.json b/PluggableAuth/i18n/pl.json new file mode 100644 index 00000000..5b5cd688 --- /dev/null +++ b/PluggableAuth/i18n/pl.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Chrumps" + ] + }, + "pluggableauth-authentication-failure": "Użytkownik nie może być uwierzytelniony." +} diff --git a/PluggableAuth/i18n/pt-br.json b/PluggableAuth/i18n/pt-br.json new file mode 100644 index 00000000..7f113da3 --- /dev/null +++ b/PluggableAuth/i18n/pt-br.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Eduardo Addad de Oliveira" + ] + }, + "pluggableauth-desc": "Fornece uma estrutura para autenticação e autorização modulares", + "pluggableauth-not-authorized": "{{GENDER:$1|Usuário $1 não autorizado|Usuária $1 não autorizada}}.", + "pluggableauth-authentication-failure": "O usuário não pode ser autenticado.", + "pluggableauth-authentication-workflow-failure": "Falha no processo de autenticação.", + "pluggableauth-loginbutton-label": "Iniciar sessão com PluggableAuth", + "pluggableauth-loginbutton-help": "Faz a sua autenticação com PluggableAuth" +} diff --git a/PluggableAuth/i18n/pt.json b/PluggableAuth/i18n/pt.json new file mode 100644 index 00000000..80bfa88a --- /dev/null +++ b/PluggableAuth/i18n/pt.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Vitorvicentevalente", + "Hamilton Abreu" + ] + }, + "pluggableauth-desc": "Fornece uma estrutura para autenticação e autorização modulares", + "pluggableauth-not-authorized": "{{GENDER:$1|Utilizador $1 não autorizado|Utilizadora $1 não autorizada}}.", + "pluggableauth-authentication-failure": "Não foi possível autenticar o utilizador.", + "pluggableauth-authentication-workflow-failure": "Falha no processo de autenticação.", + "pluggableauth-loginbutton-label": "Iniciar sessão com PluggableAuth", + "pluggableauth-loginbutton-help": "Faz a sua autenticação com PluggableAuth" +} diff --git a/PluggableAuth/i18n/qqq.json b/PluggableAuth/i18n/qqq.json new file mode 100644 index 00000000..c6f0b658 --- /dev/null +++ b/PluggableAuth/i18n/qqq.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "cicalese", + "Liuxinyu970226", + "Umherirrender" + ] + }, + "pluggableauth-desc": "{{desc|name=Pluggable Auth|url=https://www.mediawiki.org/wiki/Extension:PluggableAuth}}", + "pluggableauth-not-authorized": "Text to display when an authorization plugin indicates that the user is not authorized to log in. Parameters:\n* $1 - a username with GENDER support.", + "pluggableauth-authentication-failure": "Failure message when there is an authentication or authorization failure (e.g. User not authorized).", + "pluggableauth-authentication-workflow-failure": "Failure message when there is an error in authentication workflow, such as an AuthenticationRequest being received in the wrong action.", + "pluggableauth-loginbutton-label": "Used as label for the button shown in [[Special:UserLogin]].", + "pluggableauth-loginbutton-help": "Help message used for the Login with PluggableAuth button on [[Special:UserLogin]]." +} diff --git a/PluggableAuth/i18n/roa-tara.json b/PluggableAuth/i18n/roa-tara.json new file mode 100644 index 00000000..0ec95f29 --- /dev/null +++ b/PluggableAuth/i18n/roa-tara.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Joetaras" + ] + }, + "pluggableauth-desc": "Dèje 'nu framework pe attaccà autendicaziune e autorizzazziune", + "pluggableauth-not-authorized": "{{GENDER:$1|Utende}} $1 none autorizzate." +} diff --git a/PluggableAuth/i18n/ru.json b/PluggableAuth/i18n/ru.json new file mode 100644 index 00000000..9a4bda29 --- /dev/null +++ b/PluggableAuth/i18n/ru.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Kareyac" + ] + }, + "pluggableauth-authentication-failure": "Пользователь не может быть аутентифицирован." +} diff --git a/PluggableAuth/i18n/sv.json b/PluggableAuth/i18n/sv.json new file mode 100644 index 00000000..6f5efb70 --- /dev/null +++ b/PluggableAuth/i18n/sv.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Lokal Profil", + "WikiPhoenix" + ] + }, + "pluggableauth-not-authorized": "{{GENDER:$1|Användare}} $1 är inte auktoriserad.", + "pluggableauth-loginbutton-label": "Logga in med PluggableAuth" +} diff --git a/PluggableAuth/i18n/tl.json b/PluggableAuth/i18n/tl.json new file mode 100644 index 00000000..2a498ac5 --- /dev/null +++ b/PluggableAuth/i18n/tl.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Emem.calist" + ] + }, + "pluggableauth-loginbutton-label": "Mag-Log in gamit ang 'PluggableAuth'" +} diff --git a/PluggableAuth/i18n/uk.json b/PluggableAuth/i18n/uk.json new file mode 100644 index 00000000..3ab0b638 --- /dev/null +++ b/PluggableAuth/i18n/uk.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Ата", + "Piramidion" + ] + }, + "pluggableauth-desc": "Забезпечує основу для змінної автентифікації та авторизації", + "pluggableauth-not-authorized": "{{GENDER:$1|Користувач $1 не авторизований|Користувачка $1 не авторизована}}.", + "pluggableauth-authentication-failure": "Автентифікація користувача неможлива.", + "pluggableauth-authentication-workflow-failure": "Помилка процесу автентифікації.", + "pluggableauth-loginbutton-label": "Увійти в систему за допомогою PluggableAuth", + "pluggableauth-loginbutton-help": "Автентифікує Вас через PluggableAuth" +} diff --git a/PluggableAuth/i18n/zh-hans.json b/PluggableAuth/i18n/zh-hans.json new file mode 100644 index 00000000..2fa466db --- /dev/null +++ b/PluggableAuth/i18n/zh-hans.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Liuxinyu970226" + ] + }, + "pluggableauth-desc": "提供框架用于插接式身份认证和授权", + "pluggableauth-not-authorized": "{{GENDER:$1|用户}}$1未获授权。", + "pluggableauth-authentication-failure": "用户身份不能被验证。", + "pluggableauth-authentication-workflow-failure": "身份验证工作流失败。", + "pluggableauth-loginbutton-label": "通过PluggableAuth登录", + "pluggableauth-loginbutton-help": "使用PluggableAuth验证您的身份" +} diff --git a/PluggableAuth/i18n/zh-hant.json b/PluggableAuth/i18n/zh-hant.json new file mode 100644 index 00000000..09481355 --- /dev/null +++ b/PluggableAuth/i18n/zh-hant.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Liuxinyu970226", + "Kly" + ] + }, + "pluggableauth-desc": "提供可插入式的驗證與授權框架", + "pluggableauth-not-authorized": "{{GENDER:$1|使用者}} $1 沒有取得授權。", + "pluggableauth-authentication-failure": "使用者無法被驗證。", + "pluggableauth-authentication-workflow-failure": "驗證流程失敗。", + "pluggableauth-loginbutton-label": "以 PluggableAuth 登入", + "pluggableauth-loginbutton-help": "以 PluggableAuth 來驗證您的身份" +} diff --git a/PluggableAuth/includes/PluggableAuth.alias.php b/PluggableAuth/includes/PluggableAuth.alias.php new file mode 100644 index 00000000..df3accfa --- /dev/null +++ b/PluggableAuth/includes/PluggableAuth.alias.php @@ -0,0 +1,16 @@ +<?php + +/** + * Aliases for special pages + * + * @file + * @ingroup Extensions + */ +// @codingStandardsIgnoreFile + +$specialPageAliases = []; + +/** English (English) */ +$specialPageAliases['en'] = [ + 'PluggableAuthLogin' => ['PluggableAuthLogin'], +]; diff --git a/PluggableAuth/includes/PluggableAuth.php b/PluggableAuth/includes/PluggableAuth.php new file mode 100644 index 00000000..8ecf4e40 --- /dev/null +++ b/PluggableAuth/includes/PluggableAuth.php @@ -0,0 +1,54 @@ +<?php + +abstract class PluggableAuth { + + /** + * @since 1.0 + * + * @param int &$id The user's user ID + * @param string &$username The user's user name + * @param string &$realname The user's real name + * @param string &$email The user's email address + * @param string &$errorMessage Returns a descritive message if + * there's an error + */ + abstract public function authenticate( &$id, &$username, &$realname, + &$email, &$errorMessage ); + + /** + * @since 1.0 + * + * @param User &$user The user + */ + abstract public function deauthenticate( User &$user ); + + /** + * @since 1.0 + * + * @param int $id The user's user ID + */ + abstract public function saveExtraAttributes( $id ); + + private static $instance = null; + + /** + * @since 2.0 + * @return PluggableAuth a PluggableAuth object + */ + public static function singleton() { + wfDebugLog( 'PluggableAuth', 'Getting PluggableAuth singleton' ); + wfDebugLog( 'PluggableAuth', 'Class name: ' . $GLOBALS['wgPluggableAuth_Class'] ); + if ( !is_null( self::$instance ) ) { + wfDebugLog( 'PluggableAuth', 'Singleton already exists' ); + return self::$instance; + } elseif ( isset( $GLOBALS['wgPluggableAuth_Class'] ) && + class_exists( $GLOBALS['wgPluggableAuth_Class'] ) && + is_subclass_of( $GLOBALS['wgPluggableAuth_Class'], + 'PluggableAuth' ) ) { + self::$instance = new $GLOBALS['wgPluggableAuth_Class']; + return self::$instance; + } + wfDebugLog( 'PluggableAuth', 'Could not get authentication plugin instance.' ); + return false; + } +} diff --git a/PluggableAuth/includes/PluggableAuthBeginAuthenticationRequest.php b/PluggableAuth/includes/PluggableAuthBeginAuthenticationRequest.php new file mode 100644 index 00000000..04831fb8 --- /dev/null +++ b/PluggableAuth/includes/PluggableAuthBeginAuthenticationRequest.php @@ -0,0 +1,35 @@ +<?php + +use \MediaWiki\Auth\ButtonAuthenticationRequest; +use \MediaWiki\Auth\AuthManager; + +class PluggableAuthBeginAuthenticationRequest extends + ButtonAuthenticationRequest { + + public function __construct() { + if ( isset( $GLOBALS['wgPluggableAuth_ButtonLabelMessage'] ) ) { + $label = wfMessage( $GLOBALS['wgPluggableAuth_ButtonLabelMessage'] ); + } elseif ( $GLOBALS['wgPluggableAuth_ButtonLabel'] ) { + $label = new RawMessage( $GLOBALS['wgPluggableAuth_ButtonLabel'] ); + } else { + $label = wfMessage( 'pluggableauth-loginbutton-label' ); + } + parent::__construct( + 'pluggableauthlogin', + $label, + wfMessage( 'pluggableauth-loginbutton-help' ), + true ); + } + + /** + * Returns field information. + * @return array field information + */ + public function getFieldInfo() { + if ( $this->action !== AuthManager::ACTION_LOGIN ) { + return []; + } + return array_merge( $GLOBALS['wgPluggableAuth_ExtraLoginFields'], + parent::getFieldInfo() ); + } +} diff --git a/PluggableAuth/includes/PluggableAuthContinueAuthenticationRequest.php b/PluggableAuth/includes/PluggableAuthContinueAuthenticationRequest.php new file mode 100644 index 00000000..a08bba6e --- /dev/null +++ b/PluggableAuth/includes/PluggableAuthContinueAuthenticationRequest.php @@ -0,0 +1,33 @@ +<?php + +use \MediaWiki\Auth\AuthenticationRequest; +use \MediaWiki\Auth\AuthManager; + +class PluggableAuthContinueAuthenticationRequest extends AuthenticationRequest { + + /** + * Returns field information. + * @return array field information + */ + public function getFieldInfo() { + return []; + } + + /** + * Load from submission. + * @param array $data data (ignored) + * @return bool success + */ + public function loadFromSubmission( array $data ) { + $authManager = AuthManager::singleton(); + $error = $authManager->getAuthenticationSessionData( + PluggableAuthLogin::ERROR_SESSION_KEY ); + if ( is_null( $error ) ) { + $this->username = $authManager->getAuthenticationSessionData( + PluggableAuthLogin::USERNAME_SESSION_KEY ); + $authManager->removeAuthenticationSessionData( + PluggableAuthLogin::USERNAME_SESSION_KEY ); + } + return true; + } +} diff --git a/PluggableAuth/includes/PluggableAuthHooks.php b/PluggableAuth/includes/PluggableAuthHooks.php new file mode 100644 index 00000000..ee1e9777 --- /dev/null +++ b/PluggableAuth/includes/PluggableAuthHooks.php @@ -0,0 +1,161 @@ +<?php + +class PluggableAuthHooks { + + /** + * Implements extension registration callback. + * See https://www.mediawiki.org/wiki/Manual:Extension_registration#Customizing_registration + * Removes password providers if local login is not enabled. + * + * @since 2.0 + * + */ + public static function onRegistration() { + if ( $GLOBALS['wgPluggableAuth_EnableLocalLogin'] ) { + return; + } + $passwordProviders = [ + 'MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider', + 'MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider' + ]; + $providers = $GLOBALS['wgAuthManagerAutoConfig']; + if ( isset( $providers['primaryauth'] ) ) { + $primaries = $providers['primaryauth']; + foreach ( $primaries as $key => $provider ) { + if ( in_array( $provider['class'], $passwordProviders ) ) { + unset( $GLOBALS['wgAuthManagerAutoConfig']['primaryauth'][$key] ); + } + } + } + } + + /** + * Implements TitleReadWhitelist hook. + * See https://www.mediawiki.org/wiki/Manual:Hooks/TitleReadWhitelist + * Adds PluggableAuth login special pages to whitelist. + * + * @since 2.0 + * @param Title $title being checked + * @param User $user Current user + * @param bool &$whitelisted whether this title is whitelisted + */ + public static function onTitleReadWhitelist( + Title $title, User $user, &$whitelisted + ) { + $loginSpecialPages = ExtensionRegistry::getInstance()->getAttribute( + 'PluggableAuthLoginSpecialPages' ); + foreach ( $loginSpecialPages as $page ) { + if ( $title->isSpecial( $page ) ) { + $whitelisted = true; + return; + } + } + } + + /** + * Implements AuthChangeFormFields hook. + * See https://www.mediawiki.org/wiki/Manual:Hooks/AuthChangeFormFields + * Moves login button to bottom of form. + * + * @since 2.0 + * @param array $requests AuthenticationRequests the fields are created from + * @param array $fieldInfo union of AuthenticationRequest::getFieldInfo() + * @param HTMLForm &$formDescriptor The special key weight can be set to + * change the order of the fields. + * @param int $action one of the AuthManager::ACTION_* constants. + */ + public static function onAuthChangeFormFields( + array $requests, array $fieldInfo, array &$formDescriptor, $action + ) { + if ( isset( $formDescriptor['pluggableauthlogin'] ) ) { + $formDescriptor['pluggableauthlogin']['weight'] = 101; + } + } + + /** + * Implements UserLogoutComplete hook. + * See https://www.mediawiki.org/wiki/Manual:Hooks/UserLogoutComplete + * Calls deauthenticate hook in authentication plugin. + * + * @since 2.0 + * @param User $user User after logout (won't have name, ID, etc.) + * @param string $inject_html Any HTML to inject after the logout message. + * @param string $old_name The text of the username that just logged out. + */ + public static function deauthenticate( + User $user, $inject_html, $old_name + ) { + $old_user = User::newFromName( $old_name ); + if ( $old_user === false ) { + return; + } + wfDebugLog( 'PluggableAuth', 'Deauthenticating ' . $old_name ); + $pluggableauth = PluggableAuth::singleton(); + if ( $pluggableauth ) { + $pluggableauth->deauthenticate( $old_user ); + } + wfDebugLog( 'PluggableAuth', 'Deauthenticated ' . $old_name ); + } + + /** + * Grab the page request early + * See https://www.mediawiki.org/wiki/Manual:Hooks/BeforeInitialize + * Redirects ASAP to login + * @param Title &$title being used for request + * @param null $article unused + * @param OutputPage $out object + * @param User $user current user + * @param WebRequest $request why we're here + * @param MediaWiki $mw object + * + * Note that $title has to be passed by ref so we can replace it. + */ + public static function doBeforeInitialize( + Title &$title, $article, OutputPage $out, User $user, + WebRequest $request, MediaWiki $mw + ) { + if ( !$GLOBALS['wgPluggableAuth_EnableAutoLogin'] ) { + return; + } + if ( !$out->getUser()->isAnon() ) { + return; + } + if ( !User::isEveryoneAllowed( 'read' ) && $title->userCan( 'read' ) ) { + return; + } + $loginSpecialPages = ExtensionRegistry::getInstance()->getAttribute( + 'PluggableAuthLoginSpecialPages' + ); + foreach ( $loginSpecialPages as $page ) { + if ( $title->isSpecial( $page ) ) { + return; + } + } + + $oldTitle = $title; + $title = Title::newFromText( "UserLogin", NS_SPECIAL ); + $out->redirect( $title->getFullURL( [ + 'returnto' => urlencode( $oldTitle ), + 'returntoquery' => $request->getRawQueryString() + ] ) ); + } + + /** + * Implements PersonalUrls hook. + * See https://www.mediawiki.org/wiki/Manual:Hooks/PersonalUrls + * Removes logout link from skin if auto login is enabled. + * + * @since 1.0 + * + * @param array &$personal_urls urls sto modify + * @param Title $title current title + * @param SkinTemplate $skin template for vars + */ + public static function modifyLoginURLs( + array &$personal_urls, Title $title = null, SkinTemplate $skin = null + ) { + if ( $GLOBALS['wgPluggableAuth_EnableAutoLogin'] ) { + unset( $personal_urls['logout'] ); + } + } +} diff --git a/PluggableAuth/includes/PluggableAuthLogin.php b/PluggableAuth/includes/PluggableAuthLogin.php new file mode 100644 index 00000000..c27e6a6b --- /dev/null +++ b/PluggableAuth/includes/PluggableAuthLogin.php @@ -0,0 +1,83 @@ +<?php + +use \MediaWiki\Auth\AuthManager; + +class PluggableAuthLogin extends UnlistedSpecialPage { + + const RETURNTOURL_SESSION_KEY = 'PluggableAuthLoginReturnToUrl'; + const RETURNTOPAGE_SESSION_KEY = 'PluggableAuthLoginReturnToPage'; + const RETURNTOQUERY_SESSION_KEY = 'PluggableAuthLoginReturnToQuery'; + const EXTRALOGINFIELDS_SESSION_KEY = 'PluggableAuthLoginExtraLoginFields'; + const USERNAME_SESSION_KEY = 'PluggableAuthLoginUsername'; + const REALNAME_SESSION_KEY = 'PluggableAuthLoginRealname'; + const EMAIL_SESSION_KEY = 'PluggableAuthLoginEmail'; + const ERROR_SESSION_KEY = 'PluggableAuthLoginError'; + + public function __construct() { + parent::__construct( 'PluggableAuthLogin' ); + } + + /** + * @param string|null $param parameters (ignored) + */ + public function execute( $param ) { + wfDebugLog( 'PluggableAuth', 'In execute()' ); + $authManager = AuthManager::singleton(); + $user = $this->getUser(); + $pluggableauth = PluggableAuth::singleton(); + $error = null; + if ( $pluggableauth ) { + if ( $pluggableauth->authenticate( $id, $username, $realname, $email, + $error ) ) { + if ( is_null( $id ) ) { + $user->loadDefaults( $username ); + $user->mName = $username; + $user->mRealName = $realname; + $user->mEmail = $email; + $user->mEmailAuthenticated = wfTimestamp(); + $user->mTouched = wfTimestamp(); + wfDebugLog( 'PluggableAuth', 'Authenticated new user: ' . $username ); + } else { + $user->mId = $id; + $user->loadFromId(); + wfDebugLog( 'PluggableAuth', 'Authenticated existing user: ' . $user->mName ); + } + $authorized = true; + Hooks::run( 'PluggableAuthUserAuthorization', [ $user, &$authorized ] ); + if ( $authorized ) { + $authManager->setAuthenticationSessionData( + self::USERNAME_SESSION_KEY, $username ); + $authManager->setAuthenticationSessionData( + self::REALNAME_SESSION_KEY, $realname ); + $authManager->setAuthenticationSessionData( + self::EMAIL_SESSION_KEY, $email ); + wfDebugLog( 'PluggableAuth', 'User is authorized.' ); + } else { + wfDebugLog( 'PluggableAuth', 'Authorization failure.' ); + $error = wfMessage( 'pluggableauth-not-authorized', $username )->text(); + } + } else { + wfDebugLog( 'PluggableAuth', 'Authentication failure.' ); + if ( is_null( $error ) ) { + $error = wfMessage( 'pluggableauth-authentication-failure' )->text(); + } else { + if ( !is_string( $error ) ) { + $error = strval( $error ); + } + wfDebugLog( 'PluggableAuth', 'ERROR: ' . $error ); + } + } + } + if ( !is_null( $error ) ) { + $authManager->setAuthenticationSessionData( self::ERROR_SESSION_KEY, + $error ); + } + $returnToUrl = $authManager->getAuthenticationSessionData( + self::RETURNTOURL_SESSION_KEY ); + if ( is_null( $returnToUrl ) || count( $returnToUrl ) === 0 ) { + wfDebugLog( 'PluggableAuth', 'ERROR: return to URL is null or empty' ); + } else { + $this->getOutput()->redirect( $returnToUrl ); + } + } +} diff --git a/PluggableAuth/includes/PluggableAuthPrimaryAuthenticationProvider.php b/PluggableAuth/includes/PluggableAuthPrimaryAuthenticationProvider.php new file mode 100644 index 00000000..2fda5db0 --- /dev/null +++ b/PluggableAuth/includes/PluggableAuthPrimaryAuthenticationProvider.php @@ -0,0 +1,182 @@ +<?php + +use \MediaWiki\Auth\AuthenticationRequest; +use \MediaWiki\Auth\ButtonAuthenticationRequest; +use \MediaWiki\Auth\AbstractPrimaryAuthenticationProvider; +use \MediaWiki\Auth\AuthManager; +use \MediaWiki\Auth\AuthenticationResponse; + +class PluggableAuthPrimaryAuthenticationProvider extends + AbstractPrimaryAuthenticationProvider { + + /** + * Start an authentication flow + * @inheritDoc + */ + public function beginPrimaryAuthentication( array $reqs ) { + $request = ButtonAuthenticationRequest::getRequestByName( $reqs, + 'pluggableauthlogin' ); + if ( !$request ) { + return AuthenticationResponse::newAbstain(); + } + $extraLoginFields = []; + foreach ( $GLOBALS['wgPluggableAuth_ExtraLoginFields'] as $key => $value ) { + if ( isset( $request, $key ) ) { + $extraLoginFields[$key] = $request->$key; + } + } + $url = Title::newFromText( 'Special:PluggableAuthLogin' )->getFullURL(); + $this->manager->setAuthenticationSessionData( + PluggableAuthLogin::RETURNTOURL_SESSION_KEY, $request->returnToUrl ); + $this->manager->setAuthenticationSessionData( + PluggableAuthLogin::EXTRALOGINFIELDS_SESSION_KEY, $extraLoginFields ); + // @codingStandardsIgnoreStart + if ( isset( $_GET['returnto'] ) ) { + $returnto = $_GET['returnto']; + } else { + $returnto = ''; + } + $this->manager->setAuthenticationSessionData( + PluggableAuthLogin::RETURNTOPAGE_SESSION_KEY, $returnto ); + if ( isset( $_GET['returntoquery'] ) ) { + $returntoquery = $_GET['returntoquery']; + } else { + $returntoquery = ''; + } + // @codingStandardsIgnoreEnd + $this->manager->setAuthenticationSessionData( + PluggableAuthLogin::RETURNTOQUERY_SESSION_KEY, $returntoquery ); + + return AuthenticationResponse::newRedirect( [ + new PluggableAuthContinueAuthenticationRequest() + ], $url ); + } + + /** + * Continue an authentication flow + * @inheritDoc + */ + public function continuePrimaryAuthentication( array $reqs ) { + $request = AuthenticationRequest::getRequestByClass( $reqs, + PluggableAuthContinueAuthenticationRequest::class ); + if ( !$request ) { + return AuthenticationResponse::newFail( + wfMessage( 'pluggableauth-authentication-workflow-failure' ) ); + } + $error = $this->manager->getAuthenticationSessionData( + PluggableAuthLogin::ERROR_SESSION_KEY ); + if ( !is_null( $error ) ) { + $this->manager->removeAuthenticationSessionData( + PluggableAuthLogin::ERROR_SESSION_KEY ); + return AuthenticationResponse::newFail( new RawMessage( $error ) ); + } + $username = $request->username; + $user = User::newFromName( $username ); + if ( $user && $user->getId() !== 0 ) { + $this->updateUserRealnameAndEmail( $user ); + Hooks::run( 'PluggableAuthPopulateGroups', [ $user ] ); + } + return AuthenticationResponse::newPass( $username ); + } + + /** + * Determine whether a property can change + * @inheritDoc + */ + public function providerAllowsPropertyChange( $property ) { + return $GLOBALS['wgPluggableAuth_EnableLocalProperties']; + } + + private function updateUserRealNameAndEmail( $user, $force = false ) { + $realname = $this->manager->getAuthenticationSessionData( + PluggableAuthLogin::REALNAME_SESSION_KEY ); + $this->manager->removeAuthenticationSessionData( + PluggableAuthLogin::REALNAME_SESSION_KEY ); + $email = $this->manager->getAuthenticationSessionData( + PluggableAuthLogin::EMAIL_SESSION_KEY ); + $this->manager->removeAuthenticationSessionData( + PluggableAuthLogin::EMAIL_SESSION_KEY ); + if ( $user->mRealName != $realname || $user->mEmail != $email ) { + if ( $GLOBALS['wgPluggableAuth_EnableLocalProperties'] && !$force ) { + wfDebugLog( 'PluggableAuth', 'Local properties enabled.' ); + wfDebugLog( 'PluggableAuth', 'Did not save updated real name and email address.' ); + } else { + wfDebugLog( 'PluggableAuth', 'Local properties disabled or has just been created.' ); + $user->mRealName = $realname; + if ( $email && Sanitizer::validateEmail( $email ) ) { + $user->mEmail = $email; + $user->confirmEmail(); + } + $user->saveSettings(); + wfDebugLog( 'PluggableAuth', 'Saved updated real name and email address.' ); + } + } else { + wfDebugLog( 'PluggableAuth', 'Real name and email address did not change.' ); + } + } + + /** + * @inheritDoc + */ + public function autoCreatedAccount( $user, $source ) { + $this->updateUserRealNameAndEmail( $user, true ); + $pluggableauth = PluggableAuth::singleton(); + if ( $pluggableauth ) { + $pluggableauth->saveExtraAttributes( $user->mId ); + } + } + + /** + * Test whether the named user exists + * @inheritDoc + */ + public function testUserExists( $username, $flags = User::READ_NORMAL ) { + return false; + } + + /** + * Validate a change of authentication data (e.g. passwords) + * @inheritDoc + */ + public function providerAllowsAuthenticationDataChange( + AuthenticationRequest $req, $checkData = true ) { + return StatusValue::newGood( 'ignored' ); + } + + /** + * Fetch the account-creation type + * @inheritDoc + */ + public function accountCreationType() { + return self::TYPE_LINK; + } + + /** + * Start an account creation flow + * @inheritDoc + */ + public function beginPrimaryAccountCreation( $user, $creator, array $reqs ) { + return AuthenticationResponse::newAbstain(); + } + + /** + * Change or remove authentication data (e.g. passwords) + * @inheritDoc + */ + public function providerChangeAuthenticationData( AuthenticationRequest $req ) { + } + + /** + * @inheritDoc + */ + public function getAuthenticationRequests( $action, array $options ) { + switch ( $action ) { + case AuthManager::ACTION_LOGIN: + return [ + new PluggableAuthBeginAuthenticationRequest() + ]; + default: + return []; + } + } +} diff --git a/PluggableAuth/package.json b/PluggableAuth/package.json new file mode 100644 index 00000000..bcf5b133 --- /dev/null +++ b/PluggableAuth/package.json @@ -0,0 +1,11 @@ +{ + "private": true, + "scripts": { + "test": "grunt test" + }, + "devDependencies": { + "grunt": "1.0.1", + "grunt-banana-checker": "0.5.0", + "grunt-jsonlint": "1.1.0" + } +} diff --git a/PluggableAuth/version b/PluggableAuth/version new file mode 100644 index 00000000..9f74e3a2 --- /dev/null +++ b/PluggableAuth/version @@ -0,0 +1,4 @@ +PluggableAuth: REL1_31 +2020-05-25T18:28:00 + +300ac44 |