* Fixed security issue caused by sensitive property in req.data
* Fixed issue caused by setting a Metadata property to a Java value, e.g. java.net.URL instance becomes string without quotes. (Could this be a Rhino bug?) * Finalized conversion of AV_USER table to simple naming scheme ("user") * Added global getTitle() method which returns either site.title or root.sys_title * Implemented universal HopObject.value() method * Rededicated User.update() method since its previous functionality is now taken over by User.value() * Restructured login and register functionalities in User and MemberMgr * Replaced first occurrences of Exception with Error * Introduced i18n via gettext in User and MemberMgr * Removed getMessage() and Message in User and MemberMgr * Added first possible implementation of global getPermission() method * Modified code of global evalEmail() and evalURL() methods to work with Helma modules * Simplified global sendMail() method by not throwing any MailException anymore and returning the status code only * sendMail() now is using helma.Mail (so we can debug message output)
This commit is contained in:
parent
7d21e881e3
commit
e9a7800a87
24 changed files with 401 additions and 436 deletions
|
@ -24,7 +24,7 @@
|
|||
|
||||
User.prototype.constructor = function(data) {
|
||||
var now = new Date;
|
||||
this.update({
|
||||
this.value({
|
||||
name: data.name,
|
||||
hash: data.hash,
|
||||
salt: session.data.token,
|
||||
|
@ -39,7 +39,7 @@ User.prototype.constructor = function(data) {
|
|||
User.prototype.value = function(key, value) {
|
||||
var self = this;
|
||||
|
||||
var getValue = function() {
|
||||
var getter = function() {
|
||||
switch (key) {
|
||||
case "hash":
|
||||
case "salt":
|
||||
|
@ -51,7 +51,7 @@ User.prototype.value = function(key, value) {
|
|||
}
|
||||
};
|
||||
|
||||
var setValue = function() {
|
||||
var setter = function() {
|
||||
switch (key) {
|
||||
case "email":
|
||||
case "lastVisit":
|
||||
|
@ -65,14 +65,7 @@ User.prototype.value = function(key, value) {
|
|||
}
|
||||
};
|
||||
|
||||
return value === undefined ? getValue() : setValue();
|
||||
};
|
||||
|
||||
User.prototype.update = function(values) {
|
||||
for (var key in values) {
|
||||
this.value(key, values[key]);
|
||||
}
|
||||
return;
|
||||
return HopObject.prototype.value.call(this, key, value, getter, setter);
|
||||
};
|
||||
|
||||
User.prototype.touch = function() {
|
||||
|
@ -80,41 +73,52 @@ User.prototype.touch = function() {
|
|||
return;
|
||||
};
|
||||
|
||||
User.prototype.login = function(data) {
|
||||
var user = this;
|
||||
var digest = data.digest;
|
||||
// Calculate digest for JavaScript-disabled browsers
|
||||
if (!digest) {
|
||||
digest = ((data.password + this.value("salt")).md5() +
|
||||
session.data.token).md5();
|
||||
}
|
||||
// Check if login is correct
|
||||
if (digest !== this.getDigest(session.data.token)) {
|
||||
throw new Exception("loginTypo");
|
||||
}
|
||||
session.login(user);
|
||||
user.touch();
|
||||
if (data.remember) {
|
||||
// Set long running cookies for automatic login
|
||||
res.setCookie("avUsr", user.value("name"), 365);
|
||||
var ip = req.data.http_remotehost.clip(getProperty("cookieLevel", "4"),
|
||||
"", "\\.");
|
||||
res.setCookie("avPw", (user.value("hash") + ip).md5(), 365);
|
||||
}
|
||||
return new Message("welcome", [res.handlers.context.getTitle(), user.name]);
|
||||
};
|
||||
|
||||
User.prototype.getDigest = function(token) {
|
||||
token || (token = String.EMPTY);
|
||||
return (this.value("hash") + token).md5();
|
||||
};
|
||||
|
||||
/**
|
||||
* update user-profile
|
||||
* @param Obj Object containing form values
|
||||
* @return Obj Object containing two properties:
|
||||
* - error (boolean): true if error happened, false if everything went fine
|
||||
* - message (String): containing a message to user
|
||||
*/
|
||||
User.prototype.update = function(data) {
|
||||
if (!data.digest && data.password) {
|
||||
data.digest = ((data.password + this.value("salt")).md5() +
|
||||
session.data.token).md5();
|
||||
}
|
||||
if (data.digest) {
|
||||
if (data.digest !== this.getDigest(session.data.token)) {
|
||||
throw Error(gettext("Oops, your old password is incorrect. Please re-enter it."));
|
||||
}
|
||||
if (!data.hash) {
|
||||
if (!data.newPassword || !data.newPasswordConfirm) {
|
||||
throw Error(gettext("Please specify a new password."));
|
||||
} else if (data.newPassword !== data.newPasswordConfirm) {
|
||||
throw Error(gettext("Unfortunately, your passwords didn't match. Please repeat your input."));
|
||||
}
|
||||
data.hash = (data.newPassword + session.data.token).md5();
|
||||
}
|
||||
this.value({
|
||||
hash: data.hash,
|
||||
salt: session.data.token
|
||||
});
|
||||
}
|
||||
this.value({
|
||||
url: evalURL(data.url),
|
||||
email: evalEmail(data.email),
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
User.prototype.status_macro = function(param) {
|
||||
// this macro is allowed just for sysadmins
|
||||
if (!session.user.sysadmin) {
|
||||
// This macro is allowed for privileged users only
|
||||
if (!getPermission(User.PRIVILEGED)) {
|
||||
return;
|
||||
}
|
||||
res.debug(Html.dropDown);
|
||||
if (param.as === "editor") {
|
||||
var options = {};
|
||||
for each (var status in User.status) {
|
||||
|
@ -312,18 +316,18 @@ User.register = function(data) {
|
|||
// special characters like umlauts and spaces
|
||||
var invalidChar = new RegExp("[^a-zA-Z0-9äöüß\\.\\-_ ]");
|
||||
if (!data.name) {
|
||||
throw new Exception("usernameMissing");
|
||||
throw Error(gettext("Please enter a username."));
|
||||
} else if (data.name.length > 30) {
|
||||
throw new Exception("usernameTooLong");
|
||||
throw Error(gettext("Sorry, the username you entered is too long. Please choose a shorter one."));
|
||||
} else if (invalidChar.exec(data.name)) {
|
||||
throw new Exception("usernameNoSpecialChars");
|
||||
throw Error(gettext("Please enter alphanumeric characters only in the username field."));
|
||||
} else if (this[data.name] || this[data.name + "_action"]) {
|
||||
throw new Exception("usernameExisting");
|
||||
throw Error(gettext("Sorry, the user name you entered already exists. Please enter a different one."));
|
||||
}
|
||||
|
||||
// check if email-address is valid
|
||||
if (!data.email) {
|
||||
throw new Exception("emailMissing");
|
||||
throw new Error(gettext("Please enter your e-mail address."));
|
||||
}
|
||||
evalEmail(data.email);
|
||||
|
||||
|
@ -331,26 +335,51 @@ User.register = function(data) {
|
|||
if (!data.hash) {
|
||||
// Check if passwords match
|
||||
if (!data.password || !data.passwordConfirm) {
|
||||
throw new Exception("passwordTwice");
|
||||
throw new Error(gettext("Could not verify your password. Please repeat your input."))
|
||||
} else if (data.password !== data.passwordConfirm) {
|
||||
throw new Exception("passwordNoMatch");
|
||||
throw new Error(gettext("Unfortunately, your passwords didn't match. Please repeat your input."));
|
||||
}
|
||||
data.hash = (data.password + session.data.token).md5();
|
||||
}
|
||||
|
||||
if (User.getByName(data.name)) {
|
||||
throw new Exception("memberExisting");
|
||||
throw new Error(gettext("Sorry, the user name you entered already exists. Please enter a different one."));
|
||||
}
|
||||
var user = new User(data);
|
||||
// grant trust and sysadmin-rights if there's no sysadmin 'til now
|
||||
if (root.manage.sysadmins.size() == 0) {
|
||||
user.sysadmin = user.trusted = 1;
|
||||
} else {
|
||||
user.sysadmin = user.trusted = 0;
|
||||
if (root.manage.sysadmins.size() < 1) {
|
||||
user.value("status", User.PRIVILEGED);
|
||||
}
|
||||
root.users.add(user);
|
||||
var welcomeWhere = path.site ? path.site.title : root.getTitle();
|
||||
return new Message("welcome", [welcomeWhere, user.name], user);
|
||||
session.login(user);
|
||||
return user;
|
||||
};
|
||||
|
||||
User.login = function(data) {
|
||||
var user = User.getByName(data.name);
|
||||
if (!user) {
|
||||
throw Error(gettext("Unfortunately, your login failed. Maybe a typo?"));
|
||||
}
|
||||
var digest = data.digest;
|
||||
// Calculate digest for JavaScript-disabled browsers
|
||||
if (!digest) {
|
||||
digest = ((data.password + user.value("salt")).md5() +
|
||||
session.data.token).md5();
|
||||
}
|
||||
// Check if login is correct
|
||||
if (digest !== user.getDigest(session.data.token)) {
|
||||
throw Error("Unfortunately, your login failed. Maybe a typo?");
|
||||
}
|
||||
if (data.remember) {
|
||||
// Set long running cookies for automatic login
|
||||
res.setCookie("avUsr", user.value("name"), 365);
|
||||
var ip = req.data.http_remotehost.clip(getProperty("cookieLevel", "4"),
|
||||
"", "\\.");
|
||||
res.setCookie("avPw", (user.value("hash") + ip).md5(), 365);
|
||||
}
|
||||
user.touch();
|
||||
session.login(user);
|
||||
return user;
|
||||
};
|
||||
|
||||
User.status = ["default", "blocked", "trusted", "privileged"];
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
##
|
||||
|
||||
_db = antville
|
||||
_table = AV_USER
|
||||
_table = user
|
||||
_id = id
|
||||
_name = name
|
||||
_parent = root.users
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue