Bug 340949: using free-busy times for denied read access, minor pref cleanup, adopting sync code

This commit is contained in:
daniel.boelzle%sun.com 2006-08-02 16:18:54 +00:00
Родитель a0d0d747fb
Коммит c15df7d453
7 изменённых файлов: 234 добавлений и 174 удалений

Просмотреть файл

@ -37,6 +37,21 @@
*
* ***** END LICENSE BLOCK ***** */
function createWcapCalendar( calId, session )
{
var cal = new calWcapCalendar( calId, session );
switch (CACHE) {
case "memory":
case "storage":
// wrap it up:
var cal_ = new calWcapCachedCalendar();
cal_.remoteCal = cal;
cal = cal_;
break;
}
return cal;
}
function calWcapCalendar( calId, session ) {
this.wrappedJSObject = this;
this.m_calId = calId;
@ -236,14 +251,13 @@ calWcapCalendar.prototype = {
this.calId.indexOf(userId + ":") == 0);
},
m_calProps: null,
getCalendarProperties:
function( propName, out_count )
{
this.getCalProps_(false /* !async: waits for response */);
var ret = [];
if (this.m_calProps != null) {
var nodeList = this.m_calProps.getElementsByTagName(propName);
var calProps = this.getCalProps_(false /* !async: waits for response*/);
if (calProps != null) {
var nodeList = calProps.getElementsByTagName(propName);
for ( var i = 0; i < nodeList.length; ++i ) {
ret.push( trimString(nodeList.item(i).textContent) );
}
@ -251,6 +265,7 @@ calWcapCalendar.prototype = {
out_count.value = ret.length;
return ret;
},
m_calProps: null,
getCalProps_:
function( bAsync )
{
@ -283,6 +298,7 @@ calWcapCalendar.prototype = {
this.notifyError( exc );
throw exc;
}
return this.m_calProps;
},
get defaultTimezone() {

Просмотреть файл

@ -765,8 +765,7 @@ calWcapCalendar.prototype.parseItems = function(
var lastAckProp = subComp.getFirstProperty("X-MOZ-LASTACK");
if (lastAckProp) { // shift to alarm comp:
// TZID is UTC:
item.alarmLastAck = getDatetimeFromIcalProp(
lastAckProp );
item.alarmLastAck = getDatetimeFromIcalProp( lastAckProp );
}
item.calendar = this_.superCalendar;
@ -787,6 +786,14 @@ calWcapCalendar.prototype.parseItems = function(
item.recurrenceInfo = null;
excItems.push( item );
}
if (item.title == null &&
(item.privacy == "PRIVATE" ||
item.privacy == "CONFIDENTIAL")) {
// assumed to look at a subscribed calendar,
// so patch title for private items:
item.title = g_privateItemTitle;
}
}
},
maxResult );
@ -914,6 +921,61 @@ calWcapCalendar.prototype.getItems_resp = function(
itemFilter, maxResult, rangeStart, rangeEnd, iListener )
{
try {
var exc = wcapResponse.exception;
// check whether access is denied,
// then show free-busy information instead:
if (exc && (exc == Components.interfaces.
calIWcapErrors.WCAP_ACCESS_DENIED_TO_CALENDAR)) {
if (iListener != null) {
var this_ = this;
var freeBusyListener = { // calIWcapFreeBusyListener:
onGetFreeBusyTimes:
function( rc, requestId, calId, count, entries )
{
if (rc == Components.results.NS_OK) {
var items = [];
for each ( var entry in entries ) {
var item = new CalEvent();
item.id = (g_busyItemUuidPrefix +
entry.dtRangeStart.icalString);
item.calendar = this_.superCalendar;
item.title = g_busyItemTitle;
item.startDate = entry.dtRangeStart;
item.endDate = entry.dtRangeEnd;
item.makeImmutable();
items.push(item);
}
iListener.onGetResult(
this_.superCalendar, Components.results.NS_OK,
Components.interfaces.calIItemBase,
this_.log( "getItems_resp() using free-busy " +
"information: success." ),
items.length, items );
iListener.onOperationComplete(
this_.superCalendar, Components.results.NS_OK,
Components.interfaces.calIOperationListener.GET,
items.length == 1 ? items[0].id : null, null );
this_.log(
items.length.toString() + " items delivered." );
}
else {
// if even availability is denied:
iListener.onOperationComplete(
this_.superCalendar,
Components.results.NS_ERROR_FAILURE,
Components.interfaces.calIOperationListener.GET,
null, rc );
}
}
};
this.session.getFreeBusyTimes(
this.calId, rangeStart, rangeEnd, true /*bBusyOnly*/,
freeBusyListener,
true /*bAsync*/, 0 /*requestId*/ );
}
return;
}
var icalRootComp = wcapResponse.data; // first statement, may throw
var items = this.parseItems(
@ -1109,7 +1171,7 @@ calWcapCalendar.prototype.syncChangesTo_resp = function(
calWcapCalendar.prototype.syncChangesTo = function(
destCal, dtFrom, iListener )
{
this.ensureOnline();
// this.ensureOnline();
if (dtFrom != null) {
// assure DATETIMEs:
if (dtFrom.isDate) {

Просмотреть файл

@ -75,7 +75,8 @@ var calWcapCalendarModule = {
if (!this.m_scriptsLoaded) {
this.m_scriptsLoaded = true;
// load scripts:
const scripts = [ "calWcapUtils.js", "calWcapErrors.js",
const scripts = [ "calWcapUtils.js" /* has the main init code */,
"calWcapErrors.js",
"calWcapRequest.js", "calWcapSession.js",
"calWcapCalendar.js", "calWcapCalendarItems.js",
"calWcapCachedCalendar.js" ];
@ -91,7 +92,6 @@ var calWcapCalendarModule = {
scriptLoader.loadSubScript(
ioService.newFileURI(scriptFile).spec, null );
}
init(); // init first time
}
if (!cid.equals( calWcapCalendar.prototype.classID ))
@ -104,20 +104,11 @@ var calWcapCalendarModule = {
function( outer, iid ) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
var cal;
switch (CACHE) {
// unsupported until fixed:
// case "memory":
// case "storage":
// cal = new calWcapCachedCalendar();
// break;
default:
cal = new calWcapCalendar(
null /* calId: null indicates default calendar */,
new calWcapSession() );
cal.session.defaultCalendar = cal;
break;
}
var session = new calWcapSession();
var cal = createWcapCalendar(
null /* calId: null indicates default calendar */,
session );
session.defaultCalendar = cal;
return cal.QueryInterface( iid );
}
};

Просмотреть файл

@ -183,6 +183,8 @@ function wcapErrorToString( rc )
function errorToString( err )
{
if (err instanceof String)
return err;
if (err instanceof Error)
return err.message;
switch (err) {

Просмотреть файл

@ -68,6 +68,9 @@ WcapResponse.prototype = {
this.m_data = d;
this.m_exc = null;
},
get exception() {
return this.m_exc;
},
set exception(exc) {
this.m_exc = exc;
}

Просмотреть файл

@ -351,7 +351,7 @@ calWcapSession.prototype = {
"prompting to reconnect." );
var prompt =
getWindowWatcher().getNewPrompter(null);
var bundle = getBundle();
var bundle = getWcapBundle();
if (!prompt.confirm(
bundle.GetStringFromName(
"reconnectConfirmation.label" ),
@ -455,7 +455,7 @@ calWcapSession.prototype = {
}
if (loginText == null) {
throw new Error(
getBundle().formatStringFromName(
getWcapBundle().formatStringFromName(
"accessingServerFailedError.text",
[loginUri.hostPort], 1 ) );
}
@ -463,7 +463,7 @@ calWcapSession.prototype = {
// user specified https, so http is no option:
loginText = null;
throw new Error(
getBundle() .formatStringFromName(
getWcapBundle() .formatStringFromName(
"mandatoryHttpsError.text",
[loginUri.hostPort], 1 ) );
}
@ -512,9 +512,10 @@ calWcapSession.prototype = {
while (this.m_sessionId == null) {
var prompt = getWindowWatcher().getNewPrompter(null);
if (prompt.promptUsernameAndPassword(
getBundle().GetStringFromName("loginDialog.label"),
getWcapBundle().GetStringFromName(
"loginDialog.label"),
loginText, outUser, outPW,
getBundle().GetStringFromName(
getWcapBundle().GetStringFromName(
"loginDialog.savePW.label" ),
savePW ))
{
@ -621,9 +622,10 @@ calWcapSession.prototype = {
if (parseInt(wcapVersion) < 2.0) {
this.log( "parsed server WCAP major: " + parseInt(wcapVersion) );
throw new Error(
getBundle("insufficientWcapVersionError.text", loginTextVars) );
getWcapBundle("insufficientWcapVersionError.text",
loginTextVars) );
}
return getBundle().formatStringFromName(
return getWcapBundle().formatStringFromName(
"loginDialog.text", loginTextVars, loginTextVars.length );
},
@ -789,14 +791,14 @@ calWcapSession.prototype = {
var ret;
if (calId == null || this.userId == calId) {
if (this.m_defaultCalendar == null)
this.m_defaultCalendar = new calWcapCalendar(this.userId, this);
this.m_defaultCalendar = createWcapCalendar(this.userId, this);
ret = this.m_defaultCalendar;
}
else {
var key = encodeURIComponent(calId);
ret = this.m_calIdToCalendar[key];
if (!ret) {
ret = new calWcapCalendar(calId, this);
ret = createWcapCalendar(calId, this);
this.m_calIdToCalendar[key] = ret;
}
}
@ -1040,7 +1042,7 @@ function confirmUnsecureLogin( uri )
}
}
var prompt = getWindowWatcher().getNewPrompter(null);
var bundle = getBundle();
var bundle = getWcapBundle();
var bConfirmed = prompt.confirm(
bundle.GetStringFromName("noHttpsConfirmation.label"),
bundle.formatStringFromName("noHttpsConfirmation.text", [host], 1) );

Просмотреть файл

@ -37,27 +37,6 @@
*
* ***** END LICENSE BLOCK ***** */
// globals:
// ctors:
var CalEvent;
var CalTodo;
var CalDateTime;
var XmlHttpRequest;
// preferences:
// memory|storage:
var CACHE = "off"; // xxx todo: off by default for now
// denotes where to host local storage calendar(s)
var CACHE_DIR = null;
// logging:
#expand var LOG_LEVEL = __LOG_LEVEL__;
var LOG_TIMEZONE = null;
var LOG_FILE_STREAM = null;
function logMessage( context, msg )
{
if (LOG_LEVEL > 0) {
@ -88,116 +67,6 @@ function logMessage( context, msg )
return msg;
}
function init()
{
try {
// ctors:
CalEvent = new Components.Constructor(
"@mozilla.org/calendar/event;1", "calIEvent" );
CalTodo = new Components.Constructor(
"@mozilla.org/calendar/todo;1", "calITodo" );
CalDateTime = new Components.Constructor(
"@mozilla.org/calendar/datetime;1", "calIDateTime" );
XmlHttpRequest = new Components.Constructor(
"@mozilla.org/xmlextras/xmlhttprequest;1", "nsIXMLHttpRequest" );
var prefService =
Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
var prefCalBranch = prefService.getBranch("calendar.");
try {
LOG_TIMEZONE = prefCalBranch.getCharPref("timezone.local");
}
catch (exc) {
}
var logLevel = 0;
try {
logLevel = prefCalBranch.getIntPref( "wcap.log_level" );
}
catch (exc) {
var calLog = false;
try {
calLog = prefCalBranch.getBoolPref( "debug.log" );
}
catch (exc) {
}
if (calLog)
logLevel = 1; // basic logging
}
if (logLevel > LOG_LEVEL) {
LOG_LEVEL = logLevel;
}
if (LOG_LEVEL > 0) {
try {
var logFileName = prefCalBranch.getCharPref("wcap.log_file");
if (logFileName != null) {
// set up file:
var logFile =
Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
logFile.initWithPath( logFileName );
// create output stream:
var logFileStream = Components.classes[
"@mozilla.org/network/file-output-stream;1"]
.createInstance(
Components.interfaces.nsIFileOutputStream);
logFileStream.init(
logFile,
0x02 /* PR_WRONLY */ |
0x08 /* PR_CREATE_FILE */ |
0x10 /* PR_APPEND */,
0700 /* read, write, execute/search by owner */,
0 /* unused */ );
LOG_FILE_STREAM = logFileStream;
}
}
catch (exc) {
}
logMessage( "init()",
"################################# NEW LOG " +
"#################################" );
}
// init cache dir directory:
try {
CACHE = prefCalBranch.getCharPref( "wcap.cache" );
}
catch (exc) {
}
logMessage( "calendar.wcap.cache", CACHE );
if (CACHE == "storage") {
var cacheDir = null;
try {
var sCacheDir = prefCalBranch.getCharPref( "wcap.cache_dir" );
cacheDir = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
cacheDir.initWithPath( sCacheDir );
}
catch (exc) { // not found: default to wcap/ directory in profile
var dirService = Components.classes[
"@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
cacheDir = dirService.get(
"ProfD", Components.interfaces.nsILocalFile );
cacheDir.append( "wcap" );
}
CACHE_DIR = cacheDir;
logMessage( "calendar.wcap.cache_dir", CACHE_DIR.path );
if (!CACHE_DIR.exists()) {
CACHE_DIR.create(
Components.interfaces.nsIFile.DIRECTORY_TYPE,
0700 /* read, write, execute/search by owner */ );
}
}
}
catch (exc) {
logMessage( "error in init()", exc );
}
}
// late-init service accessors:
var g_consoleService = null;
@ -262,26 +131,22 @@ function getCalendarManager()
return g_calendarManager;
};
var g_bundle = null;
function getBundle()
var g_wcapBundle = null;
function getWcapBundle()
{
if (g_bundle == null) {
if (g_wcapBundle == null) {
var stringBundleService =
Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService);
g_bundle = stringBundleService.createBundle(
g_wcapBundle = stringBundleService.createBundle(
"chrome://calendar/locale/wcap.properties" );
}
return g_bundle;
return g_wcapBundle;
}
function isEvent( item )
{
var bRet = (item instanceof Components.interfaces.calIEvent);
if (!bRet && !(item instanceof Components.interfaces.calITodo)) {
throw new Error("item is no calIEvent nor calITodo!");
}
return bRet;
return (item instanceof Components.interfaces.calIEvent);
}
function forEachIcalComponent( icalRootComp, componentType, func, maxResult )
@ -346,3 +211,122 @@ function getDatetimeFromIcalProp( prop )
return dt;
}
function getPref(prefName, defaultValue)
{
try {
const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
var prefBranch =Components.classes["@mozilla.org/preferences-service;1"]
.getService(nsIPrefBranch);
switch (prefBranch.getPrefType(prefName)) {
case nsIPrefBranch.PREF_BOOL:
return prefBranch.getBoolPref(prefName);
case nsIPrefBranch.PREF_INT:
return prefBranch.getIntPref(prefName);
case nsIPrefBranch.PREF_STRING:
return prefBranch.getCharPref(prefName);
default:
return defaultValue;
}
}
catch (exc) {
return defaultValue;
}
}
//
// init code for globals, prefs:
//
// ctors:
var CalEvent = new Components.Constructor(
"@mozilla.org/calendar/event;1", "calIEvent" );
var CalTodo = new Components.Constructor(
"@mozilla.org/calendar/todo;1", "calITodo" );
var CalDateTime = new Components.Constructor(
"@mozilla.org/calendar/datetime;1", "calIDateTime" );
var XmlHttpRequest = new Components.Constructor(
"@mozilla.org/xmlextras/xmlhttprequest;1", "nsIXMLHttpRequest" );
// global preferences:
// caching: off|memory|storage:
var CACHE = "off";
// denotes where to host local storage calendar(s)
var CACHE_DIR = null;
// logging:
#expand var LOG_LEVEL = __LOG_LEVEL__;
var LOG_TIMEZONE = getPref("calendar.timezone.local", null);
var LOG_FILE_STREAM = null;
try {
var logLevel = getPref("calendar.wcap.log_level", null);
if (logLevel == null) { // log_level pref undefined:
if (getPref("calendar.debug.log", false))
logLevel = 1; // at least basic logging when calendar.debug.log
}
if (logLevel > LOG_LEVEL) {
LOG_LEVEL = logLevel;
}
if (LOG_LEVEL > 0) {
var logFileName = getPref("calendar.wcap.log_file", null);
if (logFileName != null) {
// set up file:
var logFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
logFile.initWithPath( logFileName );
// create output stream:
var logFileStream = Components.classes[
"@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
logFileStream.init(
logFile,
0x02 /* PR_WRONLY */ |
0x08 /* PR_CREATE_FILE */ |
0x10 /* PR_APPEND */,
0700 /* read, write, execute/search by owner */,
0 /* unused */ );
LOG_FILE_STREAM = logFileStream;
}
logMessage( "init sequence",
"################################# NEW LOG " +
"#################################" );
}
// init cache dir directory:
CACHE = getPref("calendar.wcap.cache", "off" /* xxx todo */ );
logMessage( "calendar.wcap.cache", CACHE );
if (CACHE == "storage") {
var cacheDir = null;
var sCacheDir = getPref("calendar.wcap.cache_dir", null);
if (sCacheDir != null) {
cacheDir = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
cacheDir.initWithPath( sCacheDir );
}
else { // not found: default to wcap/ directory in profile
var dirService = Components.classes[
"@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
cacheDir = dirService.get(
"ProfD", Components.interfaces.nsILocalFile );
cacheDir.append( "wcap" );
}
CACHE_DIR = cacheDir;
logMessage( "calendar.wcap.cache_dir", CACHE_DIR.path );
if (!CACHE_DIR.exists()) {
CACHE_DIR.create( Components.interfaces.nsIFile.DIRECTORY_TYPE,
0700 /* read, write, execute/search by owner */ );
}
}
}
catch (exc) {
logMessage( "error in init sequence", exc );
}
// some string resources:
var g_privateItemTitle = getWcapBundle().GetStringFromName("privateItem.title");
var g_busyItemTitle = getWcapBundle().GetStringFromName("busyItem.title");
var g_busyItemUuidPrefix = ("uuid" + getTime().icalString);