1<?php
2/**
3 * DokuWiki / Mantis Authentication Plugin
4 *
5 * Allows single sign-on to DokuWiki, using external Trust mechanism to
6 * authenticate the user against MantisBT's user cookie.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 *
21 * @copyright (c) 2006       Victor Boctor
22 * @copyright (c) 2007-2012  Victor Boctor, Tiago Gomes and various contributors
23 * @copyright (c) 2013, 2020 Damien Regad
24 * @license   GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.html)
25 * @author    Damien Regad
26 */
27
28// must be run within Dokuwiki
29if( !defined( 'DOKU_INC' ) ) die();
30
31/**
32 * Class auth_plugin_authmantis.
33 *
34 * Dokuwiki Single Sign-On with MantisBT.
35 */
36class auth_plugin_authmantis extends DokuWiki_Auth_Plugin {
37
38	/**
39	 * Constructor.
40	 *
41	 * Sets additional capabilities and config strings
42	 */
43	function __construct() {
44		parent::__construct();
45
46		// MantisBT Core MUST be loaded - abort if it is not
47		// We can't load it in the plugin, due to conflicts with the
48		// declaration of utf8 compatibility functions.
49		if( !defined( 'MANTIS_VERSION' ) ) {
50			die( $this->getLang( 'mantis_core_missing' ) );
51		}
52
53		$this->cando['external'] = true;
54		$this->cando['logoff'] = true;
55	}
56
57	/**
58	 * Authenticates the user using Mantis APIs.
59	 * @param   string  $user    Username
60	 * @param   string  $pass    Cleartext Password
61	 * @param   bool    $sticky  Cookie should not expire
62	 * @return  bool             true on successful auth
63	 */
64	public function trustExternal( $user, $pass, $sticky = false ) {
65		global $USERINFO;
66
67		$ValidUser = false;
68
69		// Manage HTTP authentication with Negotiate protocol enabled
70		$user = auth_prepare_username( $user );
71		$pass = auth_prepare_password( $pass );
72
73		// This is necessary in all cases where Authorization HTTP header is always set
74		if( auth_is_user_authenticated() ) {
75			$user = '';
76		}
77
78		// Has a user name been provided?
79		if( !empty( $user ) ) {
80			// User name provided, so login via form in progress...
81			// Are the specified user name and password valid?
82			if( auth_attempt_login( $user, $pass, $sticky ) ) {
83				// Credential accepted...
84				$_SERVER['REMOTE_USER'] = $user; // Set the user name (makes things work...)
85				$ValidUser = true; // Report success.
86			}
87			else {
88				// Invalid credentials
89				global $lang;
90				msg( $lang['badlogin'], -1 );
91			}
92		}
93		else {
94			// No user name provided.
95			// Is a user already logged in?
96			if(  auth_is_user_authenticated() ) {
97				// Yes, a user is logged in, so set the globals...
98
99				$t_user_id = auth_get_current_user_id();
100
101				$USERINFO = $this->_loadUserData( $t_user_id );
102				$_SERVER[ 'REMOTE_USER' ] = user_get_field( $t_user_id, 'username' );
103				$ValidUser = true;
104			}
105		}
106
107		// Is there a valid user login?
108		if( !$ValidUser ) {
109			// No, so make sure any existing authentication is revoked.
110			auth_logoff ( );
111		}
112
113		return $ValidUser;
114	}
115
116	/**
117	 * Logout from Mantis
118	 */
119	public function logOff() {
120		auth_logout();
121	}
122
123	/**
124	 * Return user info
125	 *
126	 * @param string $user username
127	 * @param bool $requireGroups whether or not the returned data must include groups
128	 * @return false|array containing user data or false
129	 */
130	public function getUserData($user, $requireGroups = true) {
131		return $this->_loadUserData( user_get_id_by_name( $user ) );
132	}
133
134	/**
135	 * Retrieves user information from MantisBT
136	 * @param int $p_user_id
137	 * @return array|false if user does not exist
138	 */
139	protected function _loadUserData( $p_user_id ) {
140		if( !user_exists( $p_user_id ) ) {
141			return false;
142		}
143
144		// is it a media display or a page?
145		if( isset( $_REQUEST['media'] ) ) {
146			//media
147			$t_project_name = explode( ':', getNS( getID( "media", false ) ) );
148		}
149		else {
150			// normal page
151			$t_project_name = explode( ':', getNS( getID() ) );
152		}
153
154		if( array_key_exists( 1, $t_project_name ) ) {
155			$t_project_id = project_get_id_by_name( $t_project_name[1] );
156			$t_project_name = strtoupper( $t_project_name[1] );
157		}
158		else {
159			$t_project_id = ALL_PROJECTS;
160		}
161		$t_access_level_string = strtoupper(
162			MantisEnum::getLabel(
163				config_get( 'access_levels_enum_string' ),
164				access_get_project_level( $t_project_id )
165			)
166		);
167		$t_access_levels = array( $t_access_level_string );
168		if( $t_project_id !== ALL_PROJECTS ) {
169			$t_access_levels[] = $t_project_name;
170		}
171
172		return array(
173			'name' => user_get_name( $p_user_id ),
174			'pass' => user_get_field( $p_user_id, 'password' ),
175			'mail' => user_get_field( $p_user_id, 'email' ),
176			'grps' => $t_access_levels,
177		);
178	}
179}
180