View | Details | Raw Unified | Return to bug 51492
Collapse All | Expand All

(-)saml/univention-saml/debian/changelog (+6 lines)
 Lines 1-3    Link Here 
1
univention-saml (6.0.3-1) unstable; urgency=medium
2
3
  * Bug #51492: add change password dialog to SAML login
4
5
 -- Florian Best <best@univention.de>  Thu, 09 Jul 2020 08:04:51 +0200
6
1
univention-saml (6.0.2-45) unstable; urgency=medium
7
univention-saml (6.0.2-45) unstable; urgency=medium
2
8
3
  * Bug #47567: Add saml serviceproviders to groups
9
  * Bug #47567: Add saml serviceproviders to groups
(-)saml/univention-saml/debian/control (+1 lines)
 Lines 20-25   Depends: Link Here 
20
 memcached,
20
 memcached,
21
 openssl,
21
 openssl,
22
 php-cgi,
22
 php-cgi,
23
 php-curl,
23
 php-krb5,
24
 php-krb5,
24
 php-ldap,
25
 php-ldap,
25
 php-mcrypt,
26
 php-mcrypt,
(-)saml/univention-saml/simplesamlphp/modules/uldap/lib/Auth/Source/uLDAP.php (+39 lines)
 Lines 53-58   class sspmod_uldap_Auth_Source_uLDAP extends sspmod_core_Auth_UserPassBase { Link Here 
53
		assert('is_string($username)');
53
		assert('is_string($username)');
54
		assert('is_string($password)');
54
		assert('is_string($password)');
55
55
56
		$password = $this->checkPasswordChange($username, $password);
57
56
		try {
58
		try {
57
			$attributes = $this->ldapConfig->login($username, $password, $sasl_args);
59
			$attributes = $this->ldapConfig->login($username, $password, $sasl_args);
58
		} catch (SimpleSAML_Error_Error $e) {
60
		} catch (SimpleSAML_Error_Error $e) {
 Lines 69-74   class sspmod_uldap_Auth_Source_uLDAP extends sspmod_core_Auth_UserPassBase { Link Here 
69
71
70
	}
72
	}
71
73
74
	private function checkPasswordChange($username, $password) {
75
		if (!isset($_POST['new_password'])) {
76
			return $password;
77
		}
78
		$new_password = $_POST['new_password'];
79
		assert('is_string($new_password)');
80
81
		$config = SimpleSAML_Configuration::getInstance();
82
		$language = new \SimpleSAML\Locale\Language($config);
83
		$url = 'https://' . $config->getValue('hostfqdn') . '/univention/auth';
84
		$data =  json_encode(array("options" => array("username" => $username, "password" => $password, "new_password" => $new_password)));
85
		$ch = curl_init();
86
		curl_setopt($ch, CURLOPT_URL, $url);
87
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', sprintf('Accept-Language: %s; q=1, en; q=0.5', $language->getLanguage())));
88
		curl_setopt($ch, CURLOPT_USERAGENT, 'simplesamlphp');
89
		curl_setopt($ch, CURLOPT_REFERER, 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
90
		curl_setopt($ch, CURLOPT_POST, TRUE);
91
		curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
92
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
93
		$response = curl_exec($ch);
94
		if ($response === FALSE) {
95
			SimpleSAML\Logger::debug('Error: ' . curl_error($ch));
96
		}
97
		$httpcode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
98
		SimpleSAML\Logger::debug('Password changing response: ' . var_export(array($httpcode, $response), true));
99
		if (FALSE !== $response && strpos(curl_getinfo($ch, CURLINFO_CONTENT_TYPE), 'application/json') >= 0) {
100
			$response = json_decode($response, TRUE);
101
		} else {
102
			$response = array('message' => $response);
103
		}
104
		if ($httpcode !== 200) {
105
			throw new SimpleSAML_Error_Error(array('PW_CHANGE_FAILED', '%s' => $response['message']));
106
		}
107
		curl_close($ch);
108
		return $new_password;
109
	}
110
72
111
73
	/**
112
	/**
74
	 * Investigate login failure
113
	 * Investigate login failure
(-)saml/univention-saml/simplesamlphp/modules/univentiontheme/dictionaries/errors_static.definition.json (+6 lines)
 Lines 5-10    Link Here 
5
	"descr_WRONGUSERPASS": {
5
	"descr_WRONGUSERPASS": {
6
		"en": "Either no user with the given username could be found, or the password you gave was wrong. Please check the username and try again."
6
		"en": "Either no user with the given username could be found, or the password you gave was wrong. Please check the username and try again."
7
	},
7
	},
8
	"title_PW_CHANGE_FAILED": {
9
		"en": "Changing password failed"
10
	},
11
	"descr_PW_CHANGE_FAILED": {
12
		"en": "%s"
13
	},
8
	"title_LDAP_ACCDISABLED": {
14
	"title_LDAP_ACCDISABLED": {
9
		"en": "Account disabled"
15
		"en": "Account disabled"
10
	},
16
	},
(-)saml/univention-saml/simplesamlphp/modules/univentiontheme/dictionaries/errors_static.translation.json (+6 lines)
 Lines 5-10    Link Here 
5
	"descr_WRONGUSERPASS": {
5
	"descr_WRONGUSERPASS": {
6
		"de": "Entweder es konnte kein Nutzer mit dem angegebenen Nutzernamen gefunden werden oder das Passwort ist falsch. \u00dcberpr\u00fcfen Sie die Zugangsdaten und probieren Sie es nochmal"
6
		"de": "Entweder es konnte kein Nutzer mit dem angegebenen Nutzernamen gefunden werden oder das Passwort ist falsch. \u00dcberpr\u00fcfen Sie die Zugangsdaten und probieren Sie es nochmal"
7
	},
7
	},
8
	"title_PW_CHANGE_FAILED": {
9
		"de": "Passwort ändern fehlgeschlagen"
10
	},
11
	"descr_PW_CHANGE_FAILED": {
12
		"de": "%s"
13
	},
8
	"title_LDAP_ACCDISABLED": {
14
	"title_LDAP_ACCDISABLED": {
9
		"de": "Account deaktiviert"
15
		"de": "Account deaktiviert"
10
	},
16
	},
(-)saml/univention-saml/simplesamlphp/modules/univentiontheme/themes/univention/core/loginuserpass.php (-19 / +40 lines)
 Lines 2-10    Link Here 
2
$this->includeAtTemplateBase('includes/header.php');
2
$this->includeAtTemplateBase('includes/header.php');
3
3
4
$this->data['header'] = $this->t('{login:user_pass_header}');
4
$this->data['header'] = $this->t('{login:user_pass_header}');
5
6
$PW_EXPIRED = $this->data['errorcode'] !== NULL && in_array($this->data['errorcode'], array('LDAP_PWCHANGE', 'KRB_PWCHANGE', 'SAMBA_PWCHANGE'));
7
// echo '<pre>'; var_dump($this->data); echo '</pre>';
5
?>
8
?>
6
		<div id="umcLoginWrapper">
9
		<div id="umcLoginWrapper">
7
			<h1 style="text-align: center;"><?php echo htmlspecialchars(sprintf($this->t('{univentiontheme:login:loginat}'), $this->configuration->getValue('domainname', ''))); ?></h1>
10
			<h1 style="text-align: center;"><?php echo htmlspecialchars($this->t('{univentiontheme:login:loginat}', array('%s' => $this->configuration->getValue('domainname', '')))); ?></h1>
8
<?php
11
<?php
9
if (isset($this->data['SPMetadata']['privacypolicy'])) {
12
if (isset($this->data['SPMetadata']['privacypolicy'])) {
10
	printf('<h3 style="text-align: center;"><a href="%s">%s</a></h3>', htmlspecialchars($this->data['SPMetadata']['privacypolicy'], ENT_QUOTES), htmlspecialchars($this->t('{consent:consent:consent_privacypolicy}')));
13
	printf('<h3 style="text-align: center;"><a href="%s">%s</a></h3>', htmlspecialchars($this->data['SPMetadata']['privacypolicy'], ENT_QUOTES), htmlspecialchars($this->t('{consent:consent:consent_privacypolicy}')));
 Lines 17-45   if (isset($this->data['SPMetadata']['privacypolicy'])) { Link Here 
17
					<img id="umcLoginLogo" src="/univention/js/dijit/themes/umc/images/login_logo.svg"/>
20
					<img id="umcLoginLogo" src="/univention/js/dijit/themes/umc/images/login_logo.svg"/>
18
				</div>
21
				</div>
19
				<div class="umcLoginFormWrapper">
22
				<div class="umcLoginFormWrapper">
20
					<div id="umcLoginNotices" class="umcLoginNotices" style="display: none;"></div>
23
				<div id="umcLoginNotices" class="umcLoginNotices" style="display: <?php echo $this->data['errorcode'] !== NULL ? 'block' : 'none'; ?>;">
21
					<form id="umcLoginForm" name="umcLoginForm" action="?" method="post" class="umcLoginForm" autocomplete="on">
22
						<label for="umcLoginUsername">
23
							<input placeholder="<?php echo htmlspecialchars($this->t('{login:username}'), ENT_QUOTES); ?>" id="umcLoginUsername" name="username" type="text" autocomplete="username"  tabindex="1" value="<?php echo htmlspecialchars($this->data['username'], ENT_QUOTES); ?>" <?php echo $this->data['forceUsername'] ? 'readonly' : ''; ?>/>
24
						</label>
25
						<label for="umcLoginPassword">
26
							<input placeholder="<?php echo htmlspecialchars($this->t('{login:password}'), ENT_QUOTES); ?>" id="umcLoginPassword" name="password" type="password" tabindex="2" autocomplete="current-password"/>
27
						</label>
28
						<div id="umcLoginWarnings" class="umcLoginWarnings">
29
<?php
24
<?php
30
/*
31
if ($this->data['errorcode'] !== NULL) {
32
	echo('<span class="logintitle">' . $this->t('{login:help_header}') . '</span>');
33
	echo('<span class="logintext">' . $this->t('{login:help_text}') . '</span>');
34
}
35
*/
36
37
if ($this->data['errorcode'] !== NULL) {
25
if ($this->data['errorcode'] !== NULL) {
38
?>
26
?>
39
	<p class="umcLoginWarning" >
27
	<p class="umcLoginWarning" >
40
		<b><?php echo htmlspecialchars($this->t('{univentiontheme:errors:title_' . $this->data['errorcode'] . '}', $this->data['errorparams'])); ?>.</b><br>
28
		<b><?php echo htmlspecialchars($this->t('{univentiontheme:errors:title_' . $this->data['errorcode'] . '}', $this->data['errorparams'])); ?>.</b><br>
41
<?php
29
<?php
42
if (in_array($this->data['errorcode'], array('LDAP_PWCHANGE', 'KRB_PWCHANGE', 'SAMBA_PWCHANGE'))) {
30
if ($PW_EXPIRED) {
43
	$password_change_url = $this->configuration->getValue('password_change_url', '');
31
	$password_change_url = $this->configuration->getValue('password_change_url', '');
44
	$password_change_url = $password_change_url ? $password_change_url : str_replace('/univention/saml/metadata', '/univention/login/', $this->data['SPMetadata']['entityid']);
32
	$password_change_url = $password_change_url ? $password_change_url : str_replace('/univention/saml/metadata', '/univention/login/', $this->data['SPMetadata']['entityid']);
45
	echo '<span style="color: black;">';
33
	echo '<span style="color: black;">';
 Lines 55-60   if (in_array($this->data['errorcode'], array('LDAP_PWCHANGE', 'KRB_PWCHANGE', 'S Link Here 
55
<?php
43
<?php
56
}
44
}
57
?>
45
?>
46
					</div>
47
					<form id="umcLoginForm" name="umcLoginForm" action="?" method="post" class="umcLoginForm" autocomplete="on" <?php if ($PW_EXPIRED) { echo 'style="display: none; "'; } ?>>
48
						<label for="umcLoginUsername">
49
							<input placeholder="<?php echo htmlspecialchars($this->t('{login:username}'), ENT_QUOTES); ?>" id="umcLoginUsername" name="username" type="text" autocomplete="username"  tabindex="1" value="<?php echo htmlspecialchars($this->data['username'], ENT_QUOTES); ?>" <?php echo $this->data['forceUsername'] ? 'readonly' : ''; ?>/>
50
						</label>
51
						<label for="umcLoginPassword">
52
							<input placeholder="<?php echo htmlspecialchars($this->t('{login:password}'), ENT_QUOTES); ?>" id="umcLoginPassword" name="password" type="password" tabindex="2" autocomplete="current-password"/>
53
						</label>
54
						<div id="umcLoginWarnings" class="umcLoginWarnings">
58
						</div>
55
						</div>
59
<?php
56
<?php
60
foreach ($this->data['stateparams'] as $name => $value) {
57
foreach ($this->data['stateparams'] as $name => $value) {
 Lines 90-97   foreach ($this->data['organizations'] as $orgId => $orgDesc) { Link Here 
90
<?php
87
<?php
91
}
88
}
92
?>
89
?>
93
						<input id="umcLoginSubmit" type="submit" name="submit" value="Login"/>
90
						<input id="umcLoginSubmit" type="submit" name="submit" value="<?php echo htmlspecialchars($this->t('{login:login}'), ENT_QUOTES); ?>"/>
91
					</form>
92
93
<?php
94
if ($PW_EXPIRED) {
95
?>
96
					<form id="umcNewPasswordForm" name="umcLoginForm" action="?" method="post" class="umcLoginForm" autocomplete="off" style="display: block;">
97
						<input name="username" type="hidden" value="<?php echo htmlspecialchars($this->data['username'], ENT_QUOTES); ?>" />
98
						<input name="password" type="hidden" value="<?php echo htmlspecialchars($_REQUEST['password'], ENT_QUOTES); /* TODO: store instead in the session? */ ?>" />
99
						<label for="umcLoginNewPassword">
100
							<input id="umcLoginNewPassword" name="new_password" type="password" autocomplete="new-password" placeholder="<?php echo htmlspecialchars($this->t('{login:new_password}'), ENT_QUOTES); ?>">
101
						</label>
102
						<label for="umcLoginNewPasswordRetype">
103
							<input id="umcLoginNewPasswordRetype" type="password" autocomplete="new-password" placeholder="<?php echo htmlspecialchars($this->t('{login:new_password_retype}'), ENT_QUOTES); ?>">
104
						</label>
105
						<input id="umcNewPasswordSubmit" type="submit" name="submit" value="<?php echo htmlspecialchars($this->t('{login:change_password}'), ENT_QUOTES); ?>">
106
<?php
107
foreach ($this->data['stateparams'] as $name => $value) {
108
	echo '<input type="hidden" name="' . htmlspecialchars($name, ENT_QUOTES) . '" value="' . htmlspecialchars($value, ENT_QUOTES) . '" />';
109
}
110
?>
94
					</form>
111
					</form>
112
<?php
113
}
114
?>
115
95
				</div>
116
				</div>
96
			</div>
117
			</div>
97
			<div id="umcLoginLinks"></div>
118
			<div id="umcLoginLinks"></div>

Return to bug 51492