Monotone-Parent: 925d096d1e0f9b05775333d6111c325f69a17ac0
Monotone-Revision: cadb1dbd9d4e2d99af291da99b803238fd438921 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2008-01-16T18:50:17 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
01e97af01c
commit
1ed587058e
|
@ -42,7 +42,6 @@
|
|||
|
||||
#import <WEExtensions/WEResourceManager.h>
|
||||
|
||||
#import <SoObjects/SOGo/SOGoCache.h>
|
||||
#import <SoObjects/SOGo/SOGoDAVAuthenticator.h>
|
||||
#import <SoObjects/SOGo/SOGoPermissions.h>
|
||||
#import <SoObjects/SOGo/SOGoUserFolder.h>
|
||||
|
@ -57,7 +56,6 @@
|
|||
@interface SOGo : SoApplication
|
||||
{
|
||||
NSMutableDictionary *localeLUT;
|
||||
SOGoCache *cache;
|
||||
}
|
||||
|
||||
- (NSDictionary *) currentLocaleConsideringLanguages:(NSArray *)_langs;
|
||||
|
@ -392,9 +390,7 @@ static BOOL debugObjectAllocation = NO;
|
|||
static NSArray *runLoopModes = nil;
|
||||
WOResponse *resp;
|
||||
|
||||
cache = [SOGoCache sharedCache];
|
||||
resp = [super dispatchRequest: _request];
|
||||
[SOGoCache killCache];
|
||||
|
||||
if (![self isTerminating])
|
||||
{
|
||||
|
|
|
@ -104,8 +104,11 @@
|
|||
- (NSArray *)subFolderNames;
|
||||
- (NSArray *)allSubFolderNames;
|
||||
|
||||
- (NSDictionary *) recordOfEntryWithName: (NSString *) name;
|
||||
- (NSNumber *)versionOfContentWithName:(NSString *)_name;
|
||||
- (NSCalendarDate *)creationDateOfEntryWithName:(NSString *)_name;
|
||||
- (NSCalendarDate *)lastModificationOfEntryWithName:(NSString *)_name;
|
||||
|
||||
- (NSString *)fetchContentWithName:(NSString *)_name;
|
||||
- (NSException *)writeContent:(NSString *)_content toName:(NSString *)_name
|
||||
baseVersion:(unsigned int)_baseVersion;
|
||||
- (NSException *)writeContent:(NSString *)_content toName:(NSString *)_name;
|
||||
|
|
|
@ -251,14 +251,15 @@ static GCSStringFormatter *stringFormatter = nil;
|
|||
recursive:YES];
|
||||
}
|
||||
|
||||
- (NSDictionary *) _fetchValueOfColumns: (NSArray *) _cols
|
||||
inContentWithName: (NSString *) _name
|
||||
ignoreDeleted: (BOOL) ignoreDeleted
|
||||
- (id) _fetchValueOfColumn: (NSString *)_col
|
||||
inContentWithName: (NSString *)_name
|
||||
ignoreDeleted: (BOOL) ignoreDeleted
|
||||
{
|
||||
EOAdaptorChannel *channel;
|
||||
NSException *error;
|
||||
NSDictionary *row;
|
||||
NSArray *attrs;
|
||||
NSString *result;
|
||||
NSMutableString *sql;
|
||||
|
||||
if ((channel = [self acquireStoreChannel]) == nil) {
|
||||
|
@ -270,13 +271,12 @@ static GCSStringFormatter *stringFormatter = nil;
|
|||
sql = [NSMutableString stringWithFormat: @"SELECT %@"
|
||||
@" FROM %@"
|
||||
@" WHERE c_name = '%@'",
|
||||
[_cols componentsJoinedByString: @","],
|
||||
[self storeTableName], _name];
|
||||
_col, [self storeTableName], _name];
|
||||
if (ignoreDeleted)
|
||||
[sql appendString: @" AND (c_deleted != 1 OR c_deleted IS NULL)"];
|
||||
|
||||
/* run SQL */
|
||||
|
||||
|
||||
if ((error = [channel evaluateExpressionX:sql]) != nil) {
|
||||
[self errorWithFormat:@"%s: cannot execute SQL '%@': %@",
|
||||
__PRETTY_FUNCTION__, sql, error];
|
||||
|
@ -286,64 +286,51 @@ static GCSStringFormatter *stringFormatter = nil;
|
|||
|
||||
/* fetch results */
|
||||
|
||||
result = nil;
|
||||
attrs = [channel describeResults:NO /* do not beautify names */];
|
||||
row = [channel fetchAttributes: attrs withZone: NULL];
|
||||
if (row)
|
||||
if ((row = [channel fetchAttributes:attrs withZone:NULL]) != nil) {
|
||||
result = [[[row objectForKey:_col] copy] autorelease];
|
||||
if (![result isNotNull]) result = nil;
|
||||
[channel cancelFetch];
|
||||
}
|
||||
|
||||
/* release and return result */
|
||||
|
||||
[self releaseChannel:channel];
|
||||
|
||||
return row;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSDictionary *) recordOfEntryWithName: (NSString *) name
|
||||
{
|
||||
NSDictionary *row;
|
||||
NSMutableDictionary *record;
|
||||
NSArray *columns;
|
||||
NSString *strValue;
|
||||
int intValue;
|
||||
|
||||
columns = [NSArray arrayWithObjects: @"c_content", @"c_version",
|
||||
@"c_creationdate", @"c_lastmodified", nil];
|
||||
row = [self _fetchValueOfColumns: columns
|
||||
inContentWithName: name
|
||||
ignoreDeleted: YES];
|
||||
if (row)
|
||||
{
|
||||
record = [NSMutableDictionary dictionaryWithCapacity: 5];
|
||||
strValue = [row objectForKey: @"c_content"];
|
||||
if (![strValue isNotNull])
|
||||
strValue = @"";
|
||||
[record setObject: strValue forKey: @"c_content"];
|
||||
[record setObject: [row objectForKey: @"c_version"]
|
||||
forKey: @"c_version"];
|
||||
intValue = [[row objectForKey: @"c_creationdate"] intValue];
|
||||
[record
|
||||
setObject: [NSCalendarDate dateWithTimeIntervalSince1970: intValue]
|
||||
forKey: @"c_creationdate"];
|
||||
intValue = [[row objectForKey: @"c_lastmodified"] intValue];
|
||||
[record
|
||||
setObject: [NSCalendarDate dateWithTimeIntervalSince1970: intValue]
|
||||
forKey: @"c_lastmodified"];
|
||||
}
|
||||
else
|
||||
record = nil;
|
||||
|
||||
return record;
|
||||
- (NSNumber *)versionOfContentWithName:(NSString *)_name {
|
||||
return [self _fetchValueOfColumn:@"c_version" inContentWithName:_name
|
||||
ignoreDeleted: YES];
|
||||
}
|
||||
|
||||
- (NSNumber *) deletionOfEntryWithName: (NSString *) name
|
||||
{
|
||||
NSDictionary *row;
|
||||
- (NSCalendarDate *)creationDateOfEntryWithName:(NSString *)_name {
|
||||
int seconds;
|
||||
|
||||
row = [self _fetchValueOfColumns: [NSArray arrayWithObject: @"c_deleted"]
|
||||
inContentWithName: name
|
||||
ignoreDeleted: NO];
|
||||
seconds = [[self _fetchValueOfColumn:@"c_creationdate" inContentWithName:_name
|
||||
ignoreDeleted: YES] intValue];
|
||||
|
||||
return [row objectForKey: @"c_deleted"];
|
||||
return [NSCalendarDate dateWithTimeIntervalSince1970: seconds];
|
||||
}
|
||||
|
||||
- (NSCalendarDate *)lastModificationOfEntryWithName:(NSString *)_name {
|
||||
int seconds;
|
||||
|
||||
seconds = [[self _fetchValueOfColumn:@"c_lastmodified" inContentWithName:_name
|
||||
ignoreDeleted: YES] intValue];
|
||||
|
||||
return [NSCalendarDate dateWithTimeIntervalSince1970: seconds];
|
||||
}
|
||||
|
||||
- (NSNumber *)deletionOfContentWithName:(NSString *)_name {
|
||||
return [self _fetchValueOfColumn:@"c_deleted" inContentWithName:_name
|
||||
ignoreDeleted: NO];
|
||||
}
|
||||
|
||||
- (NSString *)fetchContentWithName:(NSString *)_name {
|
||||
return [self _fetchValueOfColumn:@"c_content" inContentWithName:_name
|
||||
ignoreDeleted: YES];
|
||||
}
|
||||
|
||||
- (NSDictionary *)fetchContentsOfAllFiles {
|
||||
|
@ -584,7 +571,6 @@ static GCSStringFormatter *stringFormatter = nil;
|
|||
{
|
||||
EOAdaptorChannel *storeChannel, *quickChannel;
|
||||
NSMutableDictionary *quickRow, *contentRow;
|
||||
NSDictionary *currentRow;
|
||||
GCSFieldExtractor *extractor;
|
||||
NSException *error;
|
||||
NSNumber *storedVersion;
|
||||
|
@ -612,24 +598,19 @@ static GCSStringFormatter *stringFormatter = nil;
|
|||
if (doLogStore)
|
||||
[self logWithFormat:@"should store content: '%@'\n%@", _name, _content];
|
||||
|
||||
currentRow = [self _fetchValueOfColumns: [NSArray arrayWithObjects:
|
||||
@"c_version",
|
||||
@"c_deleted", nil]
|
||||
inContentWithName: _name
|
||||
ignoreDeleted: NO];
|
||||
storedVersion = [currentRow objectForKey: @"c_version"];
|
||||
storedVersion = [self versionOfContentWithName:_name];
|
||||
if (doLogStore)
|
||||
[self logWithFormat:@" version: %@", storedVersion];
|
||||
isNewRecord = [storedVersion isNotNull] ? NO : YES;
|
||||
if (!isNewRecord)
|
||||
{
|
||||
if ([[currentRow objectForKey: @"c_deleted"] intValue] > 0)
|
||||
if ([[self deletionOfContentWithName:_name] intValue] > 0)
|
||||
{
|
||||
[self _purgeRecordWithName: _name];
|
||||
isNewRecord = YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* check whether sequence matches */
|
||||
if (_baseVersion != 0 /* use 0 to override check */) {
|
||||
if (_baseVersion != [storedVersion unsignedIntValue]) {
|
||||
|
|
|
@ -1,47 +1,3 @@
|
|||
Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.m
|
||||
===================================================================
|
||||
--- sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (révision 1557)
|
||||
+++ sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (copie de travail)
|
||||
@@ -713,6 +713,39 @@
|
||||
return ms;
|
||||
}
|
||||
|
||||
+/* GCSEOAdaptorChannel protocol */
|
||||
+static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \
|
||||
+ @" c_name VARCHAR (256) NOT NULL,\n"
|
||||
+ @" c_content VARCHAR (100000) NOT NULL,\n"
|
||||
+ @" c_creationdate INT4 NOT NULL,\n"
|
||||
+ @" c_lastmodified INT4 NOT NULL,\n"
|
||||
+ @" c_version INT4 NOT NULL,\n"
|
||||
+ @" c_deleted INT4 NULL\n"
|
||||
+ @")");
|
||||
+static NSString *sqlFolderACLFormat = (@"CREATE TABLE %@ (\n" \
|
||||
+ @" c_uid VARCHAR (256) NOT NULL,\n"
|
||||
+ @" c_object VARCHAR (256) NOT NULL,\n"
|
||||
+ @" c_role VARCHAR (80) NOT NULL\n"
|
||||
+ @")");
|
||||
+
|
||||
+- (NSException *) createGCSFolderTableWithName: (NSString *) tableName
|
||||
+{
|
||||
+ NSString *sql;
|
||||
+
|
||||
+ sql = [NSString stringWithFormat: sqlFolderFormat, tableName];
|
||||
+
|
||||
+ return [self evaluateExpressionX: sql];
|
||||
+}
|
||||
+
|
||||
+- (NSException *) createGCSFolderACLTableWithName: (NSString *) tableName
|
||||
+{
|
||||
+ NSString *sql;
|
||||
+
|
||||
+ sql = [NSString stringWithFormat: sqlFolderACLFormat, tableName];
|
||||
+
|
||||
+ return [self evaluateExpressionX: sql];
|
||||
+}
|
||||
+
|
||||
@end /* PostgreSQL72Channel */
|
||||
|
||||
@implementation PostgreSQL72Channel(PrimaryKeyGeneration)
|
||||
Index: sope-mime/NGImap4/NGImap4Connection.m
|
||||
===================================================================
|
||||
--- sope-mime/NGImap4/NGImap4Connection.m (révision 1557)
|
||||
|
@ -514,14 +470,11 @@ Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m
|
|||
===================================================================
|
||||
--- sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (révision 1557)
|
||||
+++ sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (copie de travail)
|
||||
@@ -19,88 +19,45 @@
|
||||
@@ -19,88 +19,30 @@
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
+#ifdef HAVE_STRNDUP
|
||||
+#define _GNU_SOURCE 1
|
||||
+#endif
|
||||
+
|
||||
+#include <string.h>
|
||||
+
|
||||
#include "NGMimeHeaderFieldParser.h"
|
||||
|
@ -530,18 +483,6 @@ Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m
|
|||
#include "common.h"
|
||||
-#include <string.h>
|
||||
|
||||
+#ifndef HAVE_STRNDUP
|
||||
+char *strndup(const char *str, size_t len)
|
||||
+{
|
||||
+ char *dup = (char *)malloc(len+1);
|
||||
+ if (dup) {
|
||||
+ strncpy(dup,str,len);
|
||||
+ dup[len]= '\0';
|
||||
+ }
|
||||
+ return dup;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
@implementation NGMimeRFC822DateHeaderFieldParser
|
||||
|
||||
-static Class CalDateClass = Nil;
|
||||
|
@ -626,7 +567,7 @@ Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m
|
|||
}
|
||||
|
||||
/*
|
||||
@@ -147,162 +104,110 @@
|
||||
@@ -147,162 +89,110 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -874,7 +815,7 @@ Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m
|
|||
/* remove leading chars (skip to first digit, the day of the month) */
|
||||
while (length > 0 && (!isdigit(*bytes))) {
|
||||
bytes++;
|
||||
@@ -312,7 +217,7 @@
|
||||
@@ -312,7 +202,7 @@
|
||||
if (length == 0) {
|
||||
NSLog(@"WARNING(%s): empty value for header field %@ ..",
|
||||
__PRETTY_FUNCTION__, _field);
|
||||
|
@ -883,7 +824,7 @@ Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m
|
|||
}
|
||||
|
||||
// TODO: should be a category on NSCalendarDate
|
||||
@@ -435,7 +340,7 @@
|
||||
@@ -435,7 +325,7 @@
|
||||
for (pe = bytes; isalnum(*pe) || *pe == '-' || *pe == '+'; pe++)
|
||||
;
|
||||
*pe = '\0';
|
||||
|
@ -892,7 +833,7 @@ Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m
|
|||
[self logWithFormat:
|
||||
@"WARNING: failed to parse RFC822 timezone: '%s' (value='%@')",
|
||||
bytes, _data];
|
||||
@@ -444,9 +349,9 @@
|
||||
@@ -444,9 +334,9 @@
|
||||
|
||||
/* construct and return */
|
||||
finished:
|
||||
|
@ -956,22 +897,6 @@ Index: sope-mime/NGMime/NGMimeBodyPart.m
|
|||
}
|
||||
|
||||
- (NSString *)contentId {
|
||||
Index: sope-mime/NGMime/GNUmakefile.preamble
|
||||
===================================================================
|
||||
--- sope-mime/NGMime/GNUmakefile.preamble (révision 1557)
|
||||
+++ sope-mime/NGMime/GNUmakefile.preamble (copie de travail)
|
||||
@@ -5,6 +5,11 @@
|
||||
-DLIBRARY_MINOR_VERSION=${MINOR_VERSION} \
|
||||
-DLIBRARY_SUBMINOR_VERSION=${SUBMINOR_VERSION} \
|
||||
|
||||
+ifeq ($(patsubstr GNU/%,glibc,$(shell uname -o)),glibc)
|
||||
+ADDITIONAL_CPPFLAGS += \
|
||||
+ -DHAVE_STRNDUP
|
||||
+endif
|
||||
+
|
||||
NGMime_INCLUDE_DIRS += \
|
||||
-I.. -I../.. \
|
||||
-I../../sope-core/NGStreams/ \
|
||||
Index: sope-mime/NGMime/NGMimeBodyParser.m
|
||||
===================================================================
|
||||
--- sope-mime/NGMime/NGMimeBodyParser.m (révision 1557)
|
||||
|
@ -1202,6 +1127,50 @@ Index: sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m
|
|||
}
|
||||
return data;
|
||||
}
|
||||
Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.m
|
||||
===================================================================
|
||||
--- sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (révision 1557)
|
||||
+++ sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (copie de travail)
|
||||
@@ -713,6 +713,39 @@
|
||||
return ms;
|
||||
}
|
||||
|
||||
+/* GCSEOAdaptorChannel protocol */
|
||||
+static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \
|
||||
+ @" c_name VARCHAR (256) NOT NULL,\n"
|
||||
+ @" c_content VARCHAR (100000) NOT NULL,\n"
|
||||
+ @" c_creationdate INT4 NOT NULL,\n"
|
||||
+ @" c_lastmodified INT4 NOT NULL,\n"
|
||||
+ @" c_version INT4 NOT NULL,\n"
|
||||
+ @" c_deleted INT4 NULL\n"
|
||||
+ @")");
|
||||
+static NSString *sqlFolderACLFormat = (@"CREATE TABLE %@ (\n" \
|
||||
+ @" c_uid VARCHAR (256) NOT NULL,\n"
|
||||
+ @" c_object VARCHAR (256) NOT NULL,\n"
|
||||
+ @" c_role VARCHAR (80) NOT NULL\n"
|
||||
+ @")");
|
||||
+
|
||||
+- (NSException *) createGCSFolderTableWithName: (NSString *) tableName
|
||||
+{
|
||||
+ NSString *sql;
|
||||
+
|
||||
+ sql = [NSString stringWithFormat: sqlFolderFormat, tableName];
|
||||
+
|
||||
+ return [self evaluateExpressionX: sql];
|
||||
+}
|
||||
+
|
||||
+- (NSException *) createGCSFolderACLTableWithName: (NSString *) tableName
|
||||
+{
|
||||
+ NSString *sql;
|
||||
+
|
||||
+ sql = [NSString stringWithFormat: sqlFolderACLFormat, tableName];
|
||||
+
|
||||
+ return [self evaluateExpressionX: sql];
|
||||
+}
|
||||
+
|
||||
@end /* PostgreSQL72Channel */
|
||||
|
||||
@implementation PostgreSQL72Channel(PrimaryKeyGeneration)
|
||||
Index: sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m
|
||||
===================================================================
|
||||
--- sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (révision 1557)
|
||||
|
|
|
@ -1,292 +0,0 @@
|
|||
#/usr/bin/perl
|
||||
|
||||
# TODO:
|
||||
# - partial delete: appointment tables only, contact tables only
|
||||
# - stats: nb of calendars, nb of events, nb of events with
|
||||
# participants, nb of recurrent events, nb of contacts, nb of
|
||||
# addressbooks, nb of contacts, etc
|
||||
|
||||
=head1 NAME
|
||||
|
||||
sogo-user
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
create-ldap-fburl [options] username ...
|
||||
|
||||
Options:
|
||||
-help brief help message
|
||||
-c, --config=FILE read configuration from FILE
|
||||
-i, --info show information on the user
|
||||
--delete delete user from SOGo databases
|
||||
--fburl update Free-Busy URL in LDAP directory
|
||||
-v, --verbose be verbose
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Apply various operations on a user with respect to her/his
|
||||
SOGo environment.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
=over
|
||||
|
||||
=item Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (c) 2007 Inverse groupe conseil
|
||||
|
||||
This program is available under the GPL.
|
||||
|
||||
=cut
|
||||
|
||||
#use diagnostics;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Config::IniFiles;
|
||||
#use Data::Dumper;
|
||||
use DBI;
|
||||
use Getopt::Long qw(:config bundling);
|
||||
#use Log::Log4perl;
|
||||
use Net::LDAP;
|
||||
use Pod::Usage;
|
||||
|
||||
use constant {
|
||||
CONF_FILE => "sogo.conf"
|
||||
};
|
||||
|
||||
my $help = '';
|
||||
my $configfile = CONF_FILE;
|
||||
my $info = '';
|
||||
my $delete = '';
|
||||
my $fburl = '';
|
||||
my $verbose = '';
|
||||
|
||||
GetOptions(
|
||||
"help|?" => \$help,
|
||||
"config|c=s" => \$configfile,
|
||||
"info|i" => \$info,
|
||||
"delete" => \$delete,
|
||||
"fburl" => \$fburl,
|
||||
"verbose|v" => \$verbose
|
||||
) or pod2usage( -verbose => 1);
|
||||
|
||||
pod2usage( -verbose => 2) if $help;
|
||||
pod2usage( -verbose => 1) unless ($help || $info || $delete || $fburl);
|
||||
pod2usage( -verbose => 1) if ($#ARGV < 0);
|
||||
|
||||
my $config;
|
||||
my $dbh;
|
||||
my $ldap;
|
||||
|
||||
$config = new Config::IniFiles( -file => $configfile, -nocase => 1);
|
||||
die "ERROR: Can't read configuration file $configfile: $!\n" unless $config;
|
||||
|
||||
die "ERROR: Missing \"url\" in section [sogo]\n" unless ($config->val('sogo', 'url'));
|
||||
|
||||
# Verify LDAP parameters
|
||||
foreach ('host', 'port', 'binddn', 'password', 'searchbase', 'uid_attr', 'mail_attr', 'fburl_attr') {
|
||||
unless ($config->val('ldap', $_)) {
|
||||
die "ERROR: Missing value for parameter \"$_\" in section [ldap].\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Verify DB parameters
|
||||
foreach ('uri', 'username', 'password') {
|
||||
unless ($config->val('database', $_)) {
|
||||
die "ERROR: Missing value for parameter \"$_\" in section [database].\n";
|
||||
}
|
||||
}
|
||||
|
||||
##
|
||||
# Functions
|
||||
|
||||
sub initDatabase
|
||||
{
|
||||
$dbh = DBI->connect($config->val('database', 'uri'),
|
||||
$config->val('database', 'username'),
|
||||
$config->val('database', 'password'),
|
||||
{ AutoCommit => 1, PrintError => 0 }) or die "ERROR: Can't connect to database: $DBI::errstr\n";
|
||||
}
|
||||
|
||||
sub initLdap
|
||||
{
|
||||
$ldap = new Net::LDAP($config->val('ldap', 'host'))
|
||||
or die "ERROR: Can't connect to ldap: $@\n";
|
||||
|
||||
my $msg = $ldap->bind($config->val('ldap', 'binddn'),
|
||||
password => $config->val('ldap', 'password'));
|
||||
if ($msg->is_error()) {
|
||||
die "ERROR: Can't bind to ldap: ".$msg->error()."\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub info
|
||||
{
|
||||
my $username = shift;
|
||||
my $results;
|
||||
my @entries;
|
||||
my $hash_ref;
|
||||
|
||||
&initLdap() unless $ldap;
|
||||
&initDatabase() unless $dbh;
|
||||
|
||||
# Fetch LDAP attributes
|
||||
$results = $ldap->search(base => $config->val('ldap', 'searchbase'),
|
||||
scope => 'sub',
|
||||
attrs => [$config->val('ldap', 'uid_attr'),
|
||||
$config->val('ldap', 'mail_attr'),
|
||||
$config->val('ldap', 'fburl_attr')],
|
||||
filter => sprintf('(%s=%s)', $config->val('ldap', 'uid_attr'), $username));
|
||||
if ($results->is_error()) {
|
||||
die "ERROR: Can't perform ldap search: ",$results->error(),"\n";
|
||||
}
|
||||
@entries = $results->entries;
|
||||
die "ERROR: Unknown user $username\n" if ($#entries < 0);
|
||||
foreach my $entry (@entries) {
|
||||
print "Username: ", $entry->get_value( $config->val('ldap', 'uid_attr') ), "\n";
|
||||
print "Mail: ", $entry->get_value( $config->val('ldap', 'mail_attr') ), "\n";
|
||||
print "Freebusy URL: ", $entry->get_value( $config->val('ldap', 'fburl_attr') ) || "(undefined)", "\n";
|
||||
}
|
||||
|
||||
# Retrive database tables information
|
||||
$hash_ref = $dbh->selectall_hashref("select c_folder_id, c_folder_type, c_location, c_quick_location, c_acl_location from sogo_folder_info where c_path2 = ?", ($config->val('database', 'uri') =~ /^dbi:Pg/)?'c_folder_id':'C_FOLDER_ID', undef, ($username))
|
||||
or die "Can't execute select statement: $DBI::errstr\n";
|
||||
|
||||
print "Tables:\n";
|
||||
foreach my $id (keys %{$hash_ref}) {
|
||||
print "\tType ", ($hash_ref->{$id}->{'C_FOLDER_TYPE'} || $hash_ref->{$id}->{'c_folder_type'})
|
||||
, ", ID ", $id, "\n";
|
||||
foreach my $col ('C_LOCATION', 'C_QUICK_LOCATION', 'C_ACL_LOCATION') {
|
||||
print "\t\t", ($hash_ref->{$id}->{$col} || $hash_ref->{$id}->{lc($col)}), "\n";
|
||||
}
|
||||
}
|
||||
print "\t(no table found)\n" unless (%{$hash_ref});
|
||||
}
|
||||
|
||||
sub delete
|
||||
{
|
||||
my $username = shift;
|
||||
my $hash_ref;
|
||||
|
||||
&initDatabase() unless $dbh;
|
||||
|
||||
# Select entries from sogo_folder_info
|
||||
$hash_ref = $dbh->selectall_hashref("select C_UID from sogo_user_profile where C_UID = ?",
|
||||
($config->val('database', 'uri') =~ /^dbi:Pg/)?'c_uid':'C_UID',
|
||||
undef, ($username))
|
||||
or die "ERROR: Can't execute select statement: $DBI::errstr\n";
|
||||
|
||||
if (%{$hash_ref}) {
|
||||
# Delete entries from sogo_user_profile
|
||||
$dbh->do("delete from sogo_user_profile where c_uid = ?", undef, ($username))
|
||||
or die "ERROR: Can't delete entries from sogo_user_profile: $DBI::errstr\n";
|
||||
}
|
||||
else {
|
||||
warn "No entries in sogo_user_profile\n";
|
||||
}
|
||||
|
||||
# Select entries from sogo_folder_info
|
||||
$hash_ref = $dbh->selectall_hashref("select c_folder_id, c_folder_type, c_location, c_quick_location, c_acl_location from sogo_folder_info where c_path2 = ?", ($config->val('database', 'uri') =~ /^dbi:Pg/)?'c_folder_id':'C_FOLDER_ID', undef, ($username))
|
||||
or die "Can't execute select statement: $DBI::errstr\n";
|
||||
|
||||
if (%{$hash_ref}) {
|
||||
# Delete entries from sogo_folder_info
|
||||
$dbh->do("delete from sogo_folder_info where c_path2 = ?", undef, ($username))
|
||||
or die "Can't delete entries from sogo_info_folder: $DBI::errstr\n";
|
||||
}
|
||||
else {
|
||||
die "No entries in sogo_folder_info\n";
|
||||
}
|
||||
|
||||
# Drop tables
|
||||
foreach my $id (keys %{$hash_ref}) {
|
||||
print "Folder ID $id, type ",($hash_ref->{$id}->{'C_FOLDER_TYPE'} || $hash_ref->{$id}->{'c_folder_type'}),"\n";
|
||||
foreach my $col ('C_LOCATION', 'C_QUICK_LOCATION', 'C_ACL_LOCATION') {
|
||||
$col = lc($col) unless ($hash_ref->{$id}->{$col});
|
||||
|
||||
if ($hash_ref->{$id}->{$col} =~ m#([^:]+)://([^:]+):([^@]+)@([^:]+):([^/]+)/([^/]+)/([^/]+)#) {
|
||||
my ($type, $username, $password, $host, $port, $db, $table) = ($1, $2, $3, $4, $5, $6, $7);
|
||||
my $uri;
|
||||
print "Dropping ",$hash_ref->{$id}->{$col},"\n";
|
||||
$uri = 'dbi:Pg:host=%s;port=%s;dbname=%s' if ($type eq 'http');
|
||||
$uri = 'dbi:Oracle:host=%s;port=%s;sid=%s' if ($type eq 'oracle');
|
||||
my $s = DBI->connect(sprintf($uri, $host, $port, $db), $username, $password, { AutoCommit => 1, PrintError => 0 }) or die "\tCan't connect: $!\n";
|
||||
$s->do("drop table $table") or warn "\tERROR: Can't drop table $table: $DBI::errstr\n";
|
||||
$s->disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub fburl
|
||||
{
|
||||
my $username = shift;
|
||||
my $results;
|
||||
my @entries;
|
||||
my $modified = '';
|
||||
|
||||
&initLdap() unless $ldap;
|
||||
|
||||
$results = $ldap->search(base => $config->val('ldap', 'searchbase'),
|
||||
scope => 'sub',
|
||||
attrs => ['objectClass',
|
||||
$config->val('ldap', 'uid_attr'),
|
||||
$config->val('ldap', 'mail_attr'),
|
||||
$config->val('ldap', 'fburl_attr')],
|
||||
filter => sprintf('(%s=%s)', $config->val('ldap', 'uid_attr'), $username));
|
||||
if ($results->is_error()) {
|
||||
die "ERROR: Can't perform ldap search: ",$results->error(),"\n";
|
||||
}
|
||||
@entries = $results->entries;
|
||||
die "ERROR: Unknown user $username\n" if ($#entries < 0);
|
||||
foreach my $entry (@entries) {
|
||||
my $caldav_objectclass = $config->val('ldap', 'caldav_objectclass');
|
||||
if (length($caldav_objectclass) > 0) {
|
||||
# Add objectClass if not present
|
||||
my @objectClasses = $entry->get_value('objectClass');
|
||||
#print "classes = ", join(", ", @objectClasses), "\n";
|
||||
unless (grep {/^$caldav_objectclass$/} @objectClasses) {
|
||||
print "Adding objectClass ", $caldav_objectclass,"\n";
|
||||
$entry->add('objectClass' => $caldav_objectclass);
|
||||
$modified = 1;
|
||||
}
|
||||
}
|
||||
# Add Freebusy URL if not present
|
||||
my $fburl_attr = $config->val('ldap', 'fburl_attr');
|
||||
if ($entry->get_value($fburl_attr)) {
|
||||
print "Freebusy URL already defined (",$entry->get_value($fburl_attr),")\n";
|
||||
}
|
||||
else {
|
||||
my $fburl = $config->val('sogo', 'url') . "/SOGo/dav/$username/freebusy.ifb";
|
||||
print "Adding attribute ", $fburl_attr, " with value ", $fburl, "\n";
|
||||
$entry->add($fburl_attr => $fburl);
|
||||
$modified = 1;
|
||||
}
|
||||
if ($modified) {
|
||||
# Perform update
|
||||
my $msg = $entry->update($ldap);
|
||||
if ($msg->is_error()) {
|
||||
print "ERROR: Can't update entry: \n";
|
||||
print $entry->dump();
|
||||
print $msg->error(),"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
##
|
||||
# Main
|
||||
|
||||
foreach my $username (@ARGV) {
|
||||
#print $username,"\n";
|
||||
|
||||
&info($username) if $info;
|
||||
&delete($username) if $delete;
|
||||
&fburl($username) if $fburl;
|
||||
}
|
||||
|
||||
$dbh->disconnect if $dbh;
|
||||
$ldap->unbind if $ldap;
|
|
@ -48,7 +48,6 @@
|
|||
#import <SaxObjC/XMLNamespaces.h>
|
||||
|
||||
// #import <NGObjWeb/SoClassSecurityInfo.h>
|
||||
#import <SOGo/SOGoCache.h>
|
||||
#import <SOGo/SOGoCustomGroupFolder.h>
|
||||
#import <SOGo/LDAPUserManager.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
|
@ -300,8 +299,8 @@ static NSNumber *sharedYes = nil;
|
|||
[r setStatus: 207];
|
||||
[r setContentEncoding: NSUTF8StringEncoding];
|
||||
[r setHeader: @"text/xml; charset=\"utf-8\"" forKey: @"content-type"];
|
||||
// [r setHeader: @"no-cache" forKey: @"pragma"];
|
||||
// [r setHeader: @"no-cache" forKey: @"cache-control"];
|
||||
[r setHeader: @"no-cache" forKey: @"pragma"];
|
||||
[r setHeader: @"no-cache" forKey: @"cache-control"];
|
||||
[r appendContentString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"];
|
||||
[r appendContentString: @"<D:multistatus xmlns:D=\"DAV:\""
|
||||
@" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">\r\n"];
|
||||
|
@ -404,11 +403,6 @@ static NSNumber *sharedYes = nil;
|
|||
obj = [NSException exceptionWithHTTPStatus:404 /* Not Found */];
|
||||
}
|
||||
|
||||
if (obj)
|
||||
[[SOGoCache sharedCache] registerObject: obj
|
||||
withName: _key
|
||||
inContainer: container];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ static BOOL sendEMailNotifications = NO;
|
|||
sm = [SoSecurityManager sharedSecurityManager];
|
||||
if (![sm validatePermission: SOGoCalendarPerm_ViewAllComponent
|
||||
onObject: self inContext: context])
|
||||
iCalString = [record objectForKey: @"c_content"];
|
||||
iCalString = content;
|
||||
else if (![sm validatePermission: SOGoCalendarPerm_ViewDAndT
|
||||
onObject: self inContext: context])
|
||||
{
|
||||
|
@ -165,7 +165,7 @@ static BOOL sendEMailNotifications = NO;
|
|||
if (secure)
|
||||
iCalString = [self secureContentAsString];
|
||||
else
|
||||
iCalString = [record objectForKey: @"c_content"];
|
||||
iCalString = content;
|
||||
|
||||
if ([iCalString length] > 0)
|
||||
calendar = [iCalCalendar parseSingleFromSource: iCalString];
|
||||
|
|
|
@ -48,11 +48,8 @@
|
|||
|
||||
- (NGVCard *) vCard
|
||||
{
|
||||
NSString *content;
|
||||
|
||||
if (!card)
|
||||
{
|
||||
content = [record objectForKey: @"c_content"];
|
||||
if ([[content uppercaseString] hasPrefix: @"BEGIN:VCARD"])
|
||||
card = [NGVCard parseSingleFromSource: content];
|
||||
else
|
||||
|
|
|
@ -104,7 +104,7 @@ static NSString *AgenorShareLoginMarker = @".-.";
|
|||
/* first check attributes directly bound to the application */
|
||||
if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
|
||||
return obj;
|
||||
|
||||
|
||||
if (![self isInHomeFolderBranchOfLoggedInAccount: userLogin]) {
|
||||
[self warnWithFormat:@ "User %@ tried to access mail hierarchy of %@",
|
||||
userLogin, [container nameInContainer]];
|
||||
|
|
|
@ -850,7 +850,7 @@ static BOOL debugSoParts = NO;
|
|||
}
|
||||
else
|
||||
clazz = Nil;
|
||||
|
||||
|
||||
return [clazz objectWithName:_key inContainer: self];
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ libSOGo_HEADER_FILES_INSTALL_DIR = /SOGo
|
|||
FHS_HEADER_DIRS = SOGo
|
||||
|
||||
libSOGo_HEADER_FILES = \
|
||||
SOGoCache.h \
|
||||
SOGoObject.h \
|
||||
SOGoContentObject.h \
|
||||
SOGoFolder.h \
|
||||
|
@ -57,7 +56,6 @@ libSOGo_HEADER_FILES = \
|
|||
WORequest+SOGo.h
|
||||
|
||||
libSOGo_OBJC_FILES = \
|
||||
SOGoCache.m \
|
||||
SOGoObject.m \
|
||||
SOGoContentObject.m \
|
||||
SOGoFolder.m \
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
@interface SOGoContentObject : SOGoObject
|
||||
{
|
||||
NSString *ocsPath;
|
||||
NSDictionary *record;
|
||||
NSString *content;
|
||||
BOOL isNew;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,9 +49,9 @@
|
|||
if ((self = [super initWithName: newName inContainer: newContainer]))
|
||||
{
|
||||
ocsPath = nil;
|
||||
record = [[self ocsFolder] recordOfEntryWithName: newName];
|
||||
[record retain];
|
||||
isNew = (!record);
|
||||
content = [[self ocsFolder] fetchContentWithName: newName];
|
||||
[content retain];
|
||||
isNew = (!content);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -59,11 +59,19 @@
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[record release];
|
||||
[content release];
|
||||
[ocsPath release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* notifications */
|
||||
|
||||
- (void) sleep
|
||||
{
|
||||
[content release]; content = nil;
|
||||
[super sleep];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (BOOL) isFolderish
|
||||
|
@ -128,25 +136,19 @@
|
|||
|
||||
- (NSString *) contentAsString
|
||||
{
|
||||
return [record objectForKey: @"c_content"];
|
||||
return content;
|
||||
}
|
||||
|
||||
- (NSException *) saveContentString: (NSString *) newContent
|
||||
baseVersion: (unsigned int) newBaseVersion
|
||||
{
|
||||
/* Note: "iCal multifolder saves" are implemented in the apt subclass! */
|
||||
GCSFolder *folder;
|
||||
GCSFolder *folder;
|
||||
NSException *ex;
|
||||
NSMutableDictionary *newRecord;
|
||||
|
||||
ex = nil;
|
||||
|
||||
if (record)
|
||||
newRecord = [NSMutableDictionary dictionaryWithDictionary: record];
|
||||
else
|
||||
newRecord = [NSMutableDictionary dictionary];
|
||||
[newRecord setObject: newContent forKey: @"c_content"];
|
||||
ASSIGN (record, newRecord);
|
||||
ASSIGN (content, newContent);
|
||||
|
||||
folder = [container ocsFolder];
|
||||
if (folder)
|
||||
|
@ -305,7 +307,7 @@
|
|||
folder = [self ocsFolder];
|
||||
if (folder)
|
||||
{
|
||||
versionValue = [record objectForKey: @"c_version"];
|
||||
versionValue = [folder versionOfContentWithName: [self nameInContainer]];
|
||||
sprintf (buf, "\"gcs%08d\"", [versionValue unsignedIntValue]);
|
||||
entityTag = [NSString stringWithCString: buf];
|
||||
}
|
||||
|
@ -323,7 +325,7 @@
|
|||
{
|
||||
NSCalendarDate *date;
|
||||
|
||||
date = [record objectForKey: @"c_creationdate"];
|
||||
date = [[self ocsFolder] creationDateOfEntryWithName: nameInContainer];
|
||||
|
||||
return [date rfc822DateString];
|
||||
}
|
||||
|
@ -332,19 +334,16 @@
|
|||
{
|
||||
NSCalendarDate *date;
|
||||
|
||||
date = [record objectForKey: @"c_lastmodified"];
|
||||
date = [[self ocsFolder] lastModificationOfEntryWithName: nameInContainer];
|
||||
|
||||
return [date rfc822DateString];
|
||||
}
|
||||
|
||||
- (NSString *) davContentLength
|
||||
{
|
||||
NSString *content;
|
||||
|
||||
content = [record objectForKey: @"c_content"];
|
||||
|
||||
return [NSString stringWithFormat: @"%u",
|
||||
[content lengthOfBytesUsingEncoding: NSISOLatin1StringEncoding]];
|
||||
[content
|
||||
lengthOfBytesUsingEncoding: NSISOLatin1StringEncoding]];
|
||||
}
|
||||
|
||||
- (NSException *) davMoveToTargetObject: (id) _target
|
||||
|
|
|
@ -62,7 +62,6 @@
|
|||
#import "NSDictionary+Utilities.h"
|
||||
#import "NSString+Utilities.h"
|
||||
|
||||
#import "SOGoCache.h"
|
||||
#import "SOGoObject.h"
|
||||
|
||||
@interface SOGoObject(Content)
|
||||
|
@ -561,19 +560,10 @@ static BOOL kontactGroupDAV = YES;
|
|||
acquire: (BOOL) acquire
|
||||
{
|
||||
id obj;
|
||||
SOGoCache *cache;
|
||||
|
||||
cache = [SOGoCache sharedCache];
|
||||
obj = [cache objectNamed: lookupName inContainer: self];
|
||||
if (!obj)
|
||||
{
|
||||
obj = [[self soClass] lookupKey: lookupName inContext: localContext];
|
||||
if (obj)
|
||||
{
|
||||
[obj bindToObject: self inContext: localContext];
|
||||
[cache registerObject: obj withName: lookupName inContainer: self];
|
||||
}
|
||||
}
|
||||
obj = [[self soClass] lookupKey: lookupName inContext: localContext];
|
||||
if (obj)
|
||||
[obj bindToObject: self inContext: localContext];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -32,11 +32,10 @@
|
|||
|
||||
#import "AgenorUserDefaults.h"
|
||||
#import "LDAPUserManager.h"
|
||||
#import "NSArray+Utilities.h"
|
||||
#import "SOGoCache.h"
|
||||
#import "SOGoDateFormatter.h"
|
||||
#import "SOGoObject.h"
|
||||
#import "SOGoPermissions.h"
|
||||
#import "NSArray+Utilities.h"
|
||||
|
||||
#import "SOGoUser.h"
|
||||
|
||||
|
@ -125,18 +124,10 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
|
|||
+ (SOGoUser *) userWithLogin: (NSString *) newLogin
|
||||
roles: (NSArray *) newRoles
|
||||
{
|
||||
SOGoCache *cache;
|
||||
SOGoUser *user;
|
||||
|
||||
cache = [SOGoCache sharedCache];
|
||||
user = [cache userNamed: newLogin];
|
||||
if (!user)
|
||||
{
|
||||
user = [[self alloc] initWithLogin: newLogin roles: newRoles];
|
||||
[user autorelease];
|
||||
[cache registerUser: user];
|
||||
}
|
||||
[user setPrimaryRoles: newRoles];
|
||||
user = [[self alloc] initWithLogin: newLogin roles: newRoles];
|
||||
[user autorelease];
|
||||
|
||||
return user;
|
||||
}
|
||||
|
@ -190,11 +181,6 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setPrimaryRoles: (NSArray *) newRoles
|
||||
{
|
||||
ASSIGN (roles, newRoles);
|
||||
}
|
||||
|
||||
- (void) setCurrentPassword: (NSString *) newPassword
|
||||
{
|
||||
ASSIGN (currentPassword, newPassword);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<!-- TODO: add iMIP actions -->
|
||||
|
||||
<input id="iCalendarAttachment" type="hidden"
|
||||
var:value="pathToAttachment"/>
|
||||
var:value="pathToAttachmentObject"/>
|
||||
|
||||
<var:if condition="couldParseCalendar" const:negate="1">
|
||||
<fieldset>
|
||||
|
|
Loading…
Reference in New Issue