merge of '41b11d3b1b18c4d1c7da8ba97062c553d70d8596'

and 'b4d23e0ff0b98727a952a0a09a9cb7e312f3562a'

Monotone-Parent: 41b11d3b1b18c4d1c7da8ba97062c553d70d8596
Monotone-Parent: b4d23e0ff0b98727a952a0a09a9cb7e312f3562a
Monotone-Revision: 53112c079fc1cf21b6b08a3036256c983f01c96e

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2008-08-26T17:42:24
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau 2008-08-26 17:42:24 +00:00
commit c2e7a5ae98
19 changed files with 286 additions and 160 deletions

View file

@ -1,3 +1,24 @@
2008-08-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MainUI/SOGoRootPage.m ([SOGoRootPage -setUserName:_value])
([SOGoRootPage -userName]): removed accessors, since the
corresponding ivar is not used and was removed too.
* UI/SOGoUI/UIxComponent.m ([-shortUserNameForDisplay]): no longer
make use of the "wrongusernamepassword" hack.
* UI/MainUI/SOGoRootPage.m ([SOGoRootPage -connectAction]): return
HTTP code 403 if the username and the password passed in the
request are not valid.
* SoObjects/SOGo/SOGoUserFolder.m ([SOGoUserFolder
-lookupName:_keyinContext:_ctxacquire:_flag]): whenever a user has
no access to the specified module, a response with code 403 and
the content of "UIxModuleAccessDenied" will be generated.
* UI/SOGoUI/UIxModuleAccessDenied.[hm]: new template module
displaying an error message.
2008-08-22 Wolfgang Sourdeau <wsourdeau@inverse.ca> 2008-08-22 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MailPartViewers/UIxMailRenderingContext.m * UI/MailPartViewers/UIxMailRenderingContext.m

View file

@ -27,6 +27,7 @@
#import <NGObjWeb/NSException+HTTP.h> #import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoClassSecurityInfo.h> #import <NGObjWeb/SoClassSecurityInfo.h>
#import <NGObjWeb/SoSecurityManager.h> #import <NGObjWeb/SoSecurityManager.h>
#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/WOContext+SoObjects.h> #import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WORequest.h> #import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h> #import <NGObjWeb/WOResponse.h>
@ -44,6 +45,8 @@
#import <Contacts/SOGoContactFolders.h> #import <Contacts/SOGoContactFolders.h>
#import <Mailer/SOGoMailAccounts.h> #import <Mailer/SOGoMailAccounts.h>
#import <SOGoUI/UIxComponent.h>
#import "NSArray+Utilities.h" #import "NSArray+Utilities.h"
#import "NSDictionary+Utilities.h" #import "NSDictionary+Utilities.h"
#import "LDAPUserManager.h" #import "LDAPUserManager.h"
@ -442,6 +445,26 @@
return [$(@"SOGoFreeBusyObject") objectWithName: _key inContainer: self]; return [$(@"SOGoFreeBusyObject") objectWithName: _key inContainer: self];
} }
- (WOResponse *) _moduleAccessDeniedPage
{
WOResponse *response;
UIxComponent *page;
NSString *content;
response = [context response];
[response setStatus: 403];
[response setHeader: @"text/html; charset=utf8"
forKey: @"content-type"];
page = [[WOApplication application] pageWithName: @"UIxModuleAccessDenied"
inContext: context];
// [page appendToResponse: response
// inContext: context];
content = [[page generateResponse] contentAsString];
[response appendContentString: content];
return response;
}
- (id) lookupName: (NSString *) _key - (id) lookupName: (NSString *) _key
inContext: (WOContext *) _ctx inContext: (WOContext *) _ctx
acquire: (BOOL) _flag acquire: (BOOL) _flag
@ -454,14 +477,22 @@
if (!obj) if (!obj)
{ {
currentUser = [_ctx activeUser]; currentUser = [_ctx activeUser];
if ([_key isEqualToString: @"Calendar"] if ([_key isEqualToString: @"Calendar"])
&& [currentUser canAccessModule: _key]) {
obj = [self privateCalendars: @"Calendar" inContext: _ctx]; if ([currentUser canAccessModule: _key])
obj = [self privateCalendars: @"Calendar" inContext: _ctx];
else
obj = [self _moduleAccessDeniedPage];
}
else if ([_key isEqualToString: @"Contacts"]) else if ([_key isEqualToString: @"Contacts"])
obj = [self privateContacts: _key inContext: _ctx]; obj = [self privateContacts: _key inContext: _ctx];
else if ([_key isEqualToString: @"Mail"] else if ([_key isEqualToString: @"Mail"])
&& [currentUser canAccessModule: _key]) {
obj = [self mailAccountsFolder: _key inContext: _ctx]; if ([currentUser canAccessModule: _key])
obj = [self mailAccountsFolder: _key inContext: _ctx];
else
obj = [self _moduleAccessDeniedPage];
}
else if ([_key isEqualToString: @"Preferences"]) else if ([_key isEqualToString: @"Preferences"])
obj = [$(@"SOGoPreferencesFolder") objectWithName: _key obj = [$(@"SOGoPreferencesFolder") objectWithName: _key
inContainer: self]; inContainer: self];

View file

@ -40,3 +40,6 @@
= "U bent al op deze map geabonneerd!"; = "U bent al op deze map geabonneerd!";
"The user rights cannot be edited for this object!" "The user rights cannot be edited for this object!"
= "De machtigingen kunnen niet worden aangepast voor dit object!"; = "De machtigingen kunnen niet worden aangepast voor dit object!";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "You are not allowed to access this module or this system. Please contact your system administrator.";

View file

@ -41,3 +41,6 @@
= "You have already subscribed to that folder!"; = "You have already subscribed to that folder!";
"The user rights cannot be edited for this object!" "The user rights cannot be edited for this object!"
= "The user rights cannot be edited for this object!"; = "The user rights cannot be edited for this object!";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "You are not allowed to access this module or this system. Please contact your system administrator.";

View file

@ -38,3 +38,6 @@
= "Vous êtes déja abonné à ce dossier."; = "Vous êtes déja abonné à ce dossier.";
"The user rights cannot be edited for this object!" "The user rights cannot be edited for this object!"
= "Les droits sur cet objet ne peuvent pas être édités."; = "Les droits sur cet objet ne peuvent pas être édités.";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "Vous n'êtes pas autorisé à accéder à ce module ou ce système. Veuillez contacter votre administrateur système.";

View file

@ -40,3 +40,6 @@
= "Sie haben diesen Ordner bereits abonniert!"; = "Sie haben diesen Ordner bereits abonniert!";
"The user rights cannot be edited for this object!" "The user rights cannot be edited for this object!"
= "Die Benutzer-Rechte können für dieses Objekt nicht verändert werden!"; = "Die Benutzer-Rechte können für dieses Objekt nicht verändert werden!";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "You are not allowed to access this module or this system. Please contact your system administrator.";

View file

@ -35,3 +35,6 @@
"Unable to rename that folder!" = "Impossibile rinominare la cartella!"; "Unable to rename that folder!" = "Impossibile rinominare la cartella!";
"You have already subscribed to that folder!" = "Hai già sottoscritto la cartella!"; "You have already subscribed to that folder!" = "Hai già sottoscritto la cartella!";
"The user rights cannot be edited for this object!" = "I permessi di questo oggetto non possono essere modificati!"; "The user rights cannot be edited for this object!" = "I permessi di questo oggetto non possono essere modificati!";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "You are not allowed to access this module or this system. Please contact your system administrator.";

View file

@ -45,3 +45,6 @@
= "Ya se ha suscrito a esta carpeta."; = "Ya se ha suscrito a esta carpeta.";
"The user rights cannot be edited for this object!" "The user rights cannot be edited for this object!"
= "No es posible modificar los permisos de acceso a este objeto."; = "No es posible modificar los permisos de acceso a este objeto.";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "You are not allowed to access this module or this system. Please contact your system administrator.";

View file

@ -26,9 +26,6 @@
#import <UI/SOGoUI/UIxComponent.h> #import <UI/SOGoUI/UIxComponent.h>
@interface SOGoRootPage : UIxComponent @interface SOGoRootPage : UIxComponent
{
NSString *userName;
}
@end @end

View file

@ -46,24 +46,8 @@
@implementation SOGoRootPage @implementation SOGoRootPage
- (void) dealloc
{
[userName release];
[super dealloc];
}
/* accessors */ /* accessors */
- (void) setUserName: (NSString *) _value
{
ASSIGNCOPY (userName, _value);
}
- (NSString *) userName
{
return userName;
}
- (NSString *) connectURL - (NSString *) connectURL
{ {
return [NSString stringWithFormat: @"%@connect", [self applicationPath]]; return [NSString stringWithFormat: @"%@connect", [self applicationPath]];
@ -77,20 +61,27 @@
WOCookie *authCookie; WOCookie *authCookie;
SOGoWebAuthenticator *auth; SOGoWebAuthenticator *auth;
NSString *cookieValue, *cookieString; NSString *cookieValue, *cookieString;
NSString *userName, *password;
auth = [[WOApplication application] auth = [[WOApplication application]
authenticatorInContext: context]; authenticatorInContext: context];
request = [context request]; request = [context request];
response = [self responseWith204]; userName = [request formValueForKey: @"userName"];
cookieString = [NSString stringWithFormat: @"%@:%@", password = [request formValueForKey: @"password"];
[request formValueForKey: @"userName"], if ([auth checkLogin: userName password: password])
[request formValueForKey: @"password"]]; {
cookieValue = [NSString stringWithFormat: @"basic %@", response = [self responseWith204];
[cookieString stringByEncodingBase64]]; cookieString = [NSString stringWithFormat: @"%@:%@",
authCookie = [WOCookie cookieWithName: [auth cookieNameInContext: context] userName, password];
value: cookieValue]; cookieValue = [NSString stringWithFormat: @"basic %@",
[authCookie setPath: @"/"]; [cookieString stringByEncodingBase64]];
[response addCookie: authCookie]; authCookie = [WOCookie cookieWithName: [auth cookieNameInContext: context]
value: cookieValue];
[authCookie setPath: @"/"];
[response addCookie: authCookie];
}
else
response = [self responseWithStatus: 403];
return response; return response;
} }

View file

@ -23,6 +23,7 @@ libSOGoUI_OBJC_FILES += \
\ \
UIxJSClose.m \ UIxJSClose.m \
UIxComponent.m \ UIxComponent.m \
UIxModuleAccessDenied.m \
SOGoAptFormatter.m \ SOGoAptFormatter.m \
WOContext+UIx.m \ WOContext+UIx.m \
SOGoACLAdvisory.m \ SOGoACLAdvisory.m \

View file

@ -446,9 +446,6 @@ static BOOL uixDebugEnabled = NO;
- (NSString *) shortUserNameForDisplay - (NSString *) shortUserNameForDisplay
{ {
if ([context activeUser] == nil)
return @"wrongusernamepassword";
return [[context activeUser] login]; return [[context activeUser] login];
} }

View file

@ -0,0 +1,27 @@
/* UIxModuleAccessDenied.h - this file is part of SOGo
*
* Copyright (C) 2008 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import "UIxComponent.h"
@interface UIxModuleAccessDenied : UIxComponent
@end

View file

@ -0,0 +1,27 @@
/* UIxModuleAccessDenied.m - this file is part of SOGo
*
* Copyright (C) 2008 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import "UIxModuleAccessDenied.h"
@implementation UIxModuleAccessDenied
@end

View file

@ -7,6 +7,7 @@
xmlns:const="http://www.skyrix.com/od/constant" xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url" xmlns:rsrc="OGo:url"
xmlns:label="OGo:label" xmlns:label="OGo:label"
const:popup="YES"
><var:string var:value="doctype" const:escapeHTML="NO"/> ><var:string var:value="doctype" const:escapeHTML="NO"/>
<form id="connectForm" var:href="connectURL"> <form id="connectForm" var:href="connectURL">
<div id="loginScreen"> <div id="loginScreen">
@ -14,9 +15,8 @@
type="text/javascript">var loginSuffix = '<var:string value="loginSuffix"/>';</script type="text/javascript">var loginSuffix = '<var:string value="loginSuffix"/>';</script
></var:if> ></var:if>
<img const:alt="*" id="splash" rsrc:src="lori-login.jpg"/><br/><br/> <img const:alt="*" id="splash" rsrc:src="lori-login.jpg"/><br/><br/>
<var:if condition="shortUserNameForDisplay" const:value="wrongusernamepassword" <p id="loginErrorMessage"><var:string label:value="Wrong username or password."/></p>
><p class="error"><var:string label:value="Wrong username or password."/></p> <label><var:string label:value="Username:"/><br/>
</var:if><label><var:string label:value="Username:"/><br/>
<input class="textField" id="userName" name="userName" <input class="textField" id="userName" name="userName"
type="text" var:value="userName" /></label><br/> type="text" var:value="userName" /></label><br/>
<label><var:string label:value="Password:"/><br/> <label><var:string label:value="Password:"/><br/>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE var:component>
<var:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:uix="OGo:uix"
xmlns:label="OGo:label"
xmlns:rsrc="OGo:url"
className="UIxPageFrame"
title="title"
const:toolbar="none"
const:cssFiles="UIxModuleAccessDenied.css"
const:popup="YES">
<div id="messageWindow">
<var:string label:value="You are not allowed to access this module or this system. Please contact your system administrator."
/>
</div>
</var:component>

View file

@ -41,64 +41,57 @@
<body var:class="bodyClasses" <body var:class="bodyClasses"
><var:if condition="isCompatibleBrowser" ><var:if condition="isCompatibleBrowser"
> ><var:if condition="isPopup" const:negate="YES"
<var:if condition="shortUserNameForDisplay" const:value="anonymous" ><var:if condition="context.isUIxDebugEnabled"
const:negate="YES" ><div id="logConsole"><!-- space --></div></var:if>
><var:if condition="shortUserNameForDisplay" <div id="linkBanner" class="linkbanner">
const:value="wrongusernamepassword" <a id="logoff" var:href="logoffPath"
const:negate="YES" ><var:string label:value="Disconnect" /></a>
><var:if condition="isPopup" const:negate="YES" <var:if condition="userHasCalendarAccess">
><var:if condition="context.isUIxDebugEnabled" <var:if condition="isCalendar">
><div id="logConsole"><!-- space --></div></var:if> <span class="active"><var:string label:value="Calendar"
<div id="linkBanner" class="linkbanner"> /></span>
<a id="logoff" var:href="logoffPath"
><var:string label:value="Disconnect" /></a>
<var:if condition="userHasCalendarAccess">
<var:if condition="isCalendar">
<span class="active"><var:string label:value="Calendar"
/></span>
</var:if>
<var:if condition="isCalendar" const:negate="YES">
<a id="calendarBannerLink"
var:href="relativeCalendarPath"
><var:string label:value="Calendar" /></a>
</var:if>
|
</var:if> </var:if>
<var:if condition="isContacts"> <var:if condition="isCalendar" const:negate="YES">
<span class="active"><var:string label:value="Address Book" <a id="calendarBannerLink"
/></span> var:href="relativeCalendarPath"
</var:if> ><var:string label:value="Calendar" /></a>
<var:if condition="isContacts" const:negate="YES"> </var:if>
<a id="contactsBannerLink" |
var:href="relativeContactsPath" </var:if>
><var:string label:value="Address Book" /></a> <var:if condition="isContacts">
</var:if> <span class="active"><var:string label:value="Address Book"
| /></span>
<var:if condition="userHasMailAccess"> </var:if>
<var:if condition="isMail"> <var:if condition="isContacts" const:negate="YES">
<span class="active"><var:string label:value="Mail" <a id="contactsBannerLink"
/></span> var:href="relativeContactsPath"
</var:if> ><var:string label:value="Address Book" /></a>
<var:if condition="isMail" const:negate="YES"> </var:if>
<a id="mailBannerLink" var:href="relativeMailPath" |
><var:string label:value="Mail" /></a> <var:if condition="userHasMailAccess">
</var:if> <var:if condition="isMail">
| <span class="active"><var:string label:value="Mail"
</var:if> /></span>
<a id="preferencesBannerLink" </var:if>
var:href="relativePreferencesPath" <var:if condition="isMail" const:negate="YES">
><var:string label:value="Preferences" /></a> <a id="mailBannerLink" var:href="relativeMailPath"
<var:if condition="context.isUIxDebugEnabled" ><var:string label:value="Mail" /></a>
>| <a id="consoleBannerLink" </var:if>
href="#"><var:string |
label:value="Log Console (dev.)" /></a </var:if>
></var:if> <a id="preferencesBannerLink"
</div> var:href="relativePreferencesPath"
</var:if ><var:string label:value="Preferences" /></a>
><var:component className="UIxToolbar" var:toolbar="toolbar" <var:if condition="context.isUIxDebugEnabled"
/> >| <a id="consoleBannerLink"
</var:if></var:if> href="#"><var:string
label:value="Log Console (dev.)" /></a
></var:if>
</div>
</var:if
><var:component className="UIxToolbar" var:toolbar="toolbar"
/>
<div id="pageContent"><var:component-content/></div> <div id="pageContent"><var:component-content/></div>

View file

@ -48,8 +48,9 @@ DIV#loginButton IMG#progressIndicator
margin-top: 5px; margin-top: 5px;
margin-left: 5px; } margin-left: 5px; }
P.error #loginErrorMessage
{ color: #f00; { display: none;
color: #f00;
text-align: center; } text-align: center; }
P.browser P.browser

View file

@ -1,76 +1,80 @@
function initLogin() { function initLogin() {
var date = new Date(); var date = new Date();
date.setTime(date.getTime() - 86400000); date.setTime(date.getTime() - 86400000);
document.cookie = ("0xHIGHFLYxSOGo-0.9=discard; path=/" document.cookie = ("0xHIGHFLYxSOGo-0.9=discard; path=/"
+ "; expires=" + date.toGMTString()); + "; expires=" + date.toGMTString());
var submit = $("submit"); var submit = $("submit");
submit.observe("click", onLoginClick); submit.observe("click", onLoginClick);
var userName = $("userName"); var userName = $("userName");
userName.focus(); userName.focus();
var image = $("preparedAnimation"); var image = $("preparedAnimation");
image.parentNode.removeChild(image); image.parentNode.removeChild(image);
} }
function onLoginClick(event) { function onLoginClick(event) {
var userNameField = $("userName"); var userNameField = $("userName");
var userName = userNameField.value; var userName = userNameField.value;
var password = $("password").value; var password = $("password").value;
if (userName.length > 0) { if (userName.length > 0) {
startAnimation($("loginButton"), $("submit")); startAnimation($("loginButton"), $("submit"));
if (typeof(loginSuffix) != "undefined" if (typeof(loginSuffix) != "undefined"
&& loginSuffix.length > 0 && loginSuffix.length > 0
&& !userName.endsWith(loginSuffix)) && !userName.endsWith(loginSuffix))
userName += loginSuffix; userName += loginSuffix;
var url = $("connectForm").getAttribute("action"); var url = $("connectForm").getAttribute("action");
var parameters = ("userName=" + encodeURI(userName) + "&password=" + encodeURI(password)); var parameters = ("userName=" + encodeURI(userName) + "&password=" + encodeURI(password));
document.cookie = ""; document.cookie = "";
triggerAjaxRequest(url, onLoginCallback, null, parameters, triggerAjaxRequest(url, onLoginCallback, null, parameters,
{ "Content-type": "application/x-www-form-urlencoded", { "Content-type": "application/x-www-form-urlencoded",
"Content-length": parameters.length, "Content-length": parameters.length,
"Connection": "close" }); "Connection": "close" });
} }
else else
userNameField.focus(); userNameField.focus();
preventDefault(event); preventDefault(event);
} }
function onLoginCallback(http) { function onLoginCallback(http) {
if (http.readyState == 4) { if (http.readyState == 4) {
if (isHttpStatus204(http.status)) { if (isHttpStatus204(http.status)) {
var userName = $("userName").value; var userName = $("userName").value;
if (typeof(loginSuffix) != "undefined" if (typeof(loginSuffix) != "undefined"
&& loginSuffix.length > 0 && loginSuffix.length > 0
&& !userName.endsWith(loginSuffix)) && !userName.endsWith(loginSuffix))
userName += loginSuffix; userName += loginSuffix;
var address = "" + window.location.href; var address = "" + window.location.href;
var baseAddress = ApplicationBaseURL + encodeURI(userName); var baseAddress = ApplicationBaseURL + encodeURI(userName);
var altBaseAddress; var altBaseAddress;
if (baseAddress[0] == "/") { if (baseAddress[0] == "/") {
var parts = address.split("/"); var parts = address.split("/");
var hostpart = parts[2]; var hostpart = parts[2];
var protocol = parts[0]; var protocol = parts[0];
baseAddress = protocol + "//" + hostpart + baseAddress; baseAddress = protocol + "//" + hostpart + baseAddress;
} }
var altBaseAddress; var altBaseAddress;
var parts = baseAddress.split("/"); var parts = baseAddress.split("/");
parts.splice(3, 0); parts.splice(3, 0);
altBaseAddress = parts.join("/"); altBaseAddress = parts.join("/");
var newAddress; var newAddress;
if ((address.startsWith(baseAddress) if ((address.startsWith(baseAddress)
|| address.startsWith(altBaseAddress)) || address.startsWith(altBaseAddress))
&& !address.endsWith("/logoff")) && !address.endsWith("/logoff"))
newAddress = address; newAddress = address;
else else
newAddress = baseAddress; newAddress = baseAddress;
window.location.href = newAddress; window.location.href = newAddress;
}
else {
var message = $("loginErrorMessage");
message.setStyle({ display: "block" });
}
} }
}
} }
FastInit.addOnLoad(initLogin); FastInit.addOnLoad(initLogin);