summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--inc/crypto.inc.php29
-rw-r--r--inc/user.inc.php43
-rw-r--r--modules/edit.inc.php41
-rw-r--r--modules/login.inc.php7
-rw-r--r--modules/main.inc.php74
-rw-r--r--modules/register.inc.php2
-rw-r--r--shib/api.php2
-rw-r--r--style/default.css4
-rw-r--r--templates/main/guest.html2
-rw-r--r--templates/main/logged-in-testacc.html53
10 files changed, 229 insertions, 28 deletions
diff --git a/inc/crypto.inc.php b/inc/crypto.inc.php
new file mode 100644
index 0000000..56f5073
--- /dev/null
+++ b/inc/crypto.inc.php
@@ -0,0 +1,29 @@
+<?php
+
+class Crypto
+{
+
+ /**
+ * Hash given string using crypt's $6$,
+ * which translates to ~130 bit salt
+ * and 5000 rounds of hashing with SHA-512.
+ */
+ public static function hash6($password)
+ {
+ $salt = substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 16);
+ $hash = crypt($password, '$6$' . $salt);
+ if (strlen($hash) < 60) Util::traceError('Error hashing password using SHA-512');
+ return $hash;
+ }
+
+ /**
+ * Check if the given password matches the given cryp hash.
+ * Useful for checking a hashed password.
+ */
+ public static function verify($password, $hash)
+ {
+ return crypt($password, $hash) === $hash;
+ }
+
+}
+
diff --git a/inc/user.inc.php b/inc/user.inc.php
index 496857e..ef29003 100644
--- a/inc/user.inc.php
+++ b/inc/user.inc.php
@@ -46,6 +46,13 @@ class User
return (int)self::$user['userid'];
}
+ public static function getMail()
+ {
+ if (!isset(self::$user['email']))
+ return false;
+ return self::$user['email'];
+ }
+
public static function getName()
{
if (!self::isLoggedIn())
@@ -115,8 +122,9 @@ class User
if (Session::getUid() === false)
return false;
// Try user from local DB
- self::$user = Database::queryFirst('SELECT userid, shibid, login, firstname, lastname, email FROM user WHERE userid = :uid LIMIT 1', array('uid' => Session::getUid()));
- return self::$user !== false;
+ self::$user = Database::queryFirst('SELECT userid, shibid, login, organizationid AS organization, firstname, lastname, email FROM user WHERE userid = :uid LIMIT 1', array('uid' => Session::getUid()));
+ self::$isInDb = self::$user !== false;
+ return self::$isInDb;
}
// Try bwIDM etc.
if (!$hasSession) {
@@ -190,12 +198,35 @@ class User
}
}
+ public static function updatePassword($pass)
+ {
+ if (!self::isLoggedIn() || self::$isShib || !self::$isInDb)
+ return false;
+ $pw = Crypto::hash6($pass);
+ $ret = Database::exec('UPDATE user SET password = :pass WHERE userid = :user LIMIT 1', array(
+ 'pass' => $pw,
+ 'user' => self::getId()
+ ));
+ return $ret == 1;
+ }
+
+
+ public static function updateMail($mail)
+ {
+ if (!self::isLoggedIn() || self::$isShib || !self::$isInDb)
+ return false;
+ $ret = Database::exec('UPDATE user SET email = :mail WHERE userid = :user LIMIT 1', array(
+ 'mail' => $mail,
+ 'user' => self::getId()
+ ));
+ return $ret == 1 || $mail === self::get('email');
+ }
public static function login($user, $pass)
{
$ret = Database::queryFirst('SELECT userid, password FROM user WHERE login = :user LIMIT 1', array(':user' => $user));
if ($ret === false)
return false;
- if (!Crypto::verify($pass, $ret['passwd']))
+ if (!Crypto::verify($pass, $ret['password']))
return false;
Session::create();
Session::setUid($ret['userid']);
@@ -212,7 +243,11 @@ class User
@setcookie($name, '', time() - 8640000, null, null, !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', true);
}
Session::delete();
- Header('Location: ?do=Logout&noredirect=yes');
+ if (self::$isShib) {
+ Header('Location: ?do=Logout&noredirect=yes');
+ } else {
+ Header('Location: ?do=Main');
+ }
exit(0);
}
diff --git a/modules/edit.inc.php b/modules/edit.inc.php
new file mode 100644
index 0000000..e3770ce
--- /dev/null
+++ b/modules/edit.inc.php
@@ -0,0 +1,41 @@
+<?php
+
+class Page_Edit extends Page
+{
+
+ public function doPreprocess()
+ {
+ if (!User::load()) {
+ Message::addError('Sie sind nicht angemeldet');
+ Util::redirect('?do=Main');
+ }
+ // See which attributes we are allowed to edit
+ $shib = User::isShibbolethAuth();
+ $pw1 = Request::post('pass1');
+ $pw2 = Request::post('pass2');
+ $mail = Request::post('email');
+ if ((!empty($pw1) || !empty($pw2)) && !$shib) {
+ if ($pw1 !== $pw2) {
+ Message::addError('Ihr Passwort wurde nicht verändert, da die Passwortwiederholung nicht mit dem Passwort übereinstimmt');
+ } else if (mb_strlen($pw1) < 3) {
+ Message::addError('Ihr Passwort ist zu kurz');
+ } else if (!User::updatePassword($pw1)) {
+ Message::addError('Datenbankfehler beim Aktualisieren des Passworts');
+ } else {
+ Message::addSuccess('Ihr Passwort wurde aktualisiert und ist ab sofort gültig');
+ }
+ }
+ if ($mail !== false && $mail !== User::getMail()) {
+ $mail = trim($mail);
+ if (!preg_match('/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}/i', $mail)) {
+ Message::addError('Ihre e-Mail-Adresse wurde nicht aktualisiert, da Sie ein ungültiges Format hat');
+ } else {
+ User::updateMail($mail);
+ Message::addSuccess('Ihr e-Mail-Adresse wurde aktualisiert');
+ }
+ }
+ Util::redirect('?do=Main');
+ }
+
+}
+
diff --git a/modules/login.inc.php b/modules/login.inc.php
index 517ce4e..37b005f 100644
--- a/modules/login.inc.php
+++ b/modules/login.inc.php
@@ -7,6 +7,13 @@ class Page_Login extends Page
{
if (User::load())
Util::redirect('?do=Main');
+ if (Request::post('action') === 'login') {
+ if (User::login(Request::post('user'), Request::post('pass')))
+ Util::redirect('?do=Main');
+ sleep(2);
+ Message::addError('Benutzername oder Passwort falsch');
+ Util::redirect('?do=Login');
+ }
}
public function doRender()
diff --git a/modules/main.inc.php b/modules/main.inc.php
index 3f77d7b..c1382e6 100644
--- a/modules/main.inc.php
+++ b/modules/main.inc.php
@@ -11,30 +11,62 @@ class Page_Main extends Page
protected function doRender()
{
Render::addTemplate('main/_page');
- if (User::isLoggedIn()) {
- // Logged in user --
- if (User::getOrganization() !== false) {
- // Organization is known, show signup form
- if (User::isShibbolethAuth() && !User::isInDatabase()) {
- // User comes via Shibboleth and is not known yet
- $data = User::getData();
- $data['organization'] = User::getOrganizationName();
- Render::addTemplate('main/deploy', $data);
- } else if (User::isInDatabase()) {
- // User is known from DB at least
- Render::addTemplate('main/logged-in');
- }
- } else if (User::getRemoteOrganizationId() !== false) {
- // Organization is not known, see if we at least have an idea
- Message::addWarning('Ihre Hochschule/Einrichtung {{0}} ist leider nicht bekannt. Bitte kontaktieren Sie den Support.', User::getRemoteOrganizationId());
- } else {
- // No idea where the user is coming from
- Message::addError('Ihr IdP sendet leider keine Informationen über Ihre Hochschul-/Einrichtungszugehörigkeit');
- }
- } else {
+ if (!User::isLoggedIn()) {
// Guest
Render::addTemplate('main/guest');
+ return;
+ }
+ // Logged in user --
+ if (User::isLocalOnly()) {
+ // Local test account
+ $this->renderLocalAccount();
+ return;
+ }
+ if (!User::isShibbolethAuth()) {
+ // Should not be possible
+ Message::addError('Sie sind nicht korrekt authentifiziert. Bitte melden Sie sich erneut an.');
+ Session::delete();
+ return;
+ }
+ // --- Below here we know the user via shibboleth
+ if (User::isInDatabase()) {
+ // User is also in DB, so he signed up for the service
+ $this->renderShibbolethRegistered();
+ return;
}
+ // User is not in DB, so he might want so sign up for the service - see if conditions are met
+ if (User::getOrganization() !== false) {
+ // Organization is known, show signup form
+ $this->renderShibbolethUnregistered();
+ return;
+ }
+ // Nothing we can do here, show error message :-(
+ if (User::getRemoteOrganizationId() !== false) {
+ // Organization is not known, see if we at least have an idea
+ Message::addWarning('Ihre Hochschule/Einrichtung {{0}} ist leider nicht bekannt. Bitte kontaktieren Sie den Support.', User::getRemoteOrganizationId());
+ } else {
+ // No idea where the user is coming from
+ Message::addError('Ihr IdP sendet leider keine Informationen über Ihre Hochschul-/Einrichtungszugehörigkeit');
+ }
+ }
+
+ private function renderShibbolethRegistered()
+ {
+ Render::addTemplate('main/logged-in');
+ }
+
+ private function renderShibbolethUnregistered()
+ {
+ $data = User::getData();
+ $data['organization'] = User::getOrganizationName();
+ Render::addTemplate('main/deploy', $data);
+ }
+
+ private function renderLocalAccount()
+ {
+ $data = User::getData();
+ $data['organization'] = User::getOrganizationName();
+ Render::addTemplate('main/logged-in-testacc', $data);
}
}
diff --git a/modules/register.inc.php b/modules/register.inc.php
index ca5f4bf..3dd3b89 100644
--- a/modules/register.inc.php
+++ b/modules/register.inc.php
@@ -11,7 +11,7 @@ class Page_Register extends Page
Util::redirect('?do=Main');
}
if (!User::isShibbolethAuth())
- Util::redirect('/secure-all/?do=Main');
+ Util::redirect(CONFIG_PREFIX . 'shib/?do=Main');
if (Request::post('agb') === 'on') {
// Put stuff in DB
User::deploy(Request::post('share') !== 'on');
diff --git a/shib/api.php b/shib/api.php
index 0c2a297..58b9c80 100644
--- a/shib/api.php
+++ b/shib/api.php
@@ -38,7 +38,7 @@ if (empty($_SERVER['persistent-id'])) {
// Not found, so we don't know which satellite to use
$response['status'] = 'unregistered';
$response['id'] = $shibId;
- $response['url'] = 'https://bwlp-masterserver.ruf.uni-freiburg.de/secure-all/';
+ $response['url'] = 'https://bwlp-masterserver.ruf.uni-freiburg.de/webif/';
} else {
// Found, see if we got personal information, either temporarily through metadata, or from database
$firstName = $user['firstname'];
diff --git a/style/default.css b/style/default.css
index 07e8a44..1a68547 100644
--- a/style/default.css
+++ b/style/default.css
@@ -43,6 +43,10 @@ p {
border-top-right-radius: 0;
}
+span.form-control {
+ color: #777;
+}
+
.form-narrow {
max-width: 600px;
padding: 10px;
diff --git a/templates/main/guest.html b/templates/main/guest.html
index 76b77ab..14cc902 100644
--- a/templates/main/guest.html
+++ b/templates/main/guest.html
@@ -1,7 +1,7 @@
<div class="form-narrow">
Sie sind nicht authentifiziert. Bitte wählen Sie:
<ul>
- <li><a href="shib/">Anmelden oder Registrieren über bwIDM</a></li>
+ <li><a href="shib/">Anmelden oder registrieren über bwIDM</a></li>
<li><a href="?do=Login">Anmelden mit einem bwLehrpool-Testaccount</a></li>
</ul>
</div>
diff --git a/templates/main/logged-in-testacc.html b/templates/main/logged-in-testacc.html
new file mode 100644
index 0000000..a9e6f28
--- /dev/null
+++ b/templates/main/logged-in-testacc.html
@@ -0,0 +1,53 @@
+<p>
+ Sie sind mit Ihrem Test-Account <b>{{login}}</b> angemeldet. Sie können Ihr Passwort oder Ihre e-Mail-Adresse ändern.
+</p>
+
+<form method="post" action="?do=Edit">
+ <input type="hidden" name="token" value="{{token}}">
+ <div class="form-narrow">
+
+ <div class="group-group">
+ <div class="input-group">
+ <span class="input-group-addon slx-ga">
+ Einrichtung
+ </span>
+ <span class="form-control">{{organization}}</span>
+ </div>
+ <div class="input-group">
+ <span class="input-group-addon slx-ga">
+ Vorname
+ </span>
+ <span class="form-control">{{firstname}}</span>
+ </div>
+ <div class="input-group">
+ <span class="input-group-addon slx-ga">
+ Nachname
+ </span>
+ <span class="form-control">{{lastname}}</span>
+ </div>
+ <div class="input-group">
+ <span class="input-group-addon slx-ga">
+ Mail
+ </span>
+ <input class="form-control" type="text" name="email" value="{{email}}" pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}">
+ </div>
+ <div class="input-group">
+ <span class="input-group-addon slx-ga">
+ Passwort
+ </span>
+ <input class="form-control" type="password" name="pass1">
+ </div>
+ <div class="input-group">
+ <span class="input-group-addon slx-ga">
+ Wiederholen
+ </span>
+ <input class="form-control" type="password" name="pass2">
+ </div>
+ </div>
+
+ <div class="pull-right">
+ <button type="submit" class="btn btn-primary">Speichern</button>
+ </div>
+
+ </div>
+</form>