* Added a new tool: 'sogo-tool expire-sessions'

Along with the associated new cronjob, this allows
         user sessions expiration without a custom script.

       * While there, sort tools in sogo-tool output

Monotone-Parent: 73baf2c24acbb1fb98296fc8ab448b3b3c5ba7a7
Monotone-Revision: 858274c7be3ad2a6383c2f85c8ad10907bb43292

Monotone-Author: jraby@inverse.ca
Monotone-Date: 2012-04-04T20:14:52
maint-2.0.2
Jean Raby 2012-04-04 20:14:52 +00:00
parent b906cf066a
commit e034585c2b
5 changed files with 195 additions and 3 deletions

View File

@ -1,3 +1,11 @@
2012-04-04 Jean Raby <jraby@inverse.ca>
* Added a new tool: 'sogo-tool expire-sessions'
Along with the associated new cronjob, this allows
user sessions expiration without a custom script.
* While there, sort tools in sogo-tool output
2012-04-03 Francis Lachapelle <flachapelle@inverse.ca>
* Tools/SOGoToolRemoveDoubles.m (-removeDoublesFromFolder)

View File

@ -4,6 +4,11 @@
# Make sure to set authname and authpassword with the credentials of a sieve admin
#0 0 * * * sogo /usr/sbin/sogo-tool expire-autoreply authname:authpassword
# Session cleanup - runs every minute
# - Ajust the nbMinutes parameter to suit your needs
# Example: Sessions without activity since 60 minutes will be dropped:
#* * * * * sogo /usr/sbin/sogo-tool expire-sessions 60
# Email alarms - runs every minutes
#* * * * * sogo /usr/sbin/sogo-ealarms-notify

View File

@ -18,7 +18,8 @@ $(SOGO_TOOL)_OBJC_FILES += \
SOGoToolRemove.m \
SOGoToolRenameUser.m \
SOGoToolUserPreferences.m \
SOGoToolExpireAutoReply.m
SOGoToolExpireAutoReply.m \
SOGoToolExpireUserSessions.m
TOOL_NAME += $(SOGO_TOOL)
###

View File

@ -0,0 +1,178 @@
/* SOGoToolExpireUserSessions.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc.
*
* Author: Jean Raby <jraby@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 <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <GDLAccess/EOAdaptorChannel.h>
#import <GDLContentStore/GCSChannelManager.h>
#import <GDLContentStore/NSURL+GCS.h>
#import <NGExtensions/NSNull+misc.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoUserDefaults.h>
#import "SOGoTool.h"
@interface SOGoToolExpireUserSessions : SOGoTool
@end
@implementation SOGoToolExpireUserSessions
+ (void) initialize
{
}
+ (NSString *) command
{
return @"expire-sessions";
}
+ (NSString *) description
{
return @"Expires user sessions without activity for specified number of minutes";
}
- (void) usage
{
fprintf (stderr, "expire-sessions [nbMinutes]\n\n"
" nbMinutes Number of minutes of inactivity after which a user session will be expired\n"
"\n"
"The SOGoSessionExpireMinutes user default will be used if nbMinutes is not specified\n"
"The expire-sessions action should be configured as a cronjob.\n");
}
- (BOOL) expireUserSessionOlderThan: (int) nbMinutes
{
BOOL rc;
EOAdaptorChannel *channel;
GCSChannelManager *cm;
NSArray *attrs, *qValues;
NSDictionary *qresult;
NSException *ex;
NSString *sql, *sessionsFolderURL;
NSURL *tableURL;
NSUserDefaults *ud;
unsigned int now, oldest;
int sessionsToDelete;
rc=YES;
ud = [NSUserDefaults standardUserDefaults];
now = [[NSCalendarDate calendarDate] timeIntervalSince1970];
oldest = now - (nbMinutes * 60);
sessionsFolderURL = [ud stringForKey: @"OCSSessionsFolderURL"];
if (!sessionsFolderURL)
{
if (verbose)
NSLog(@"Couldn't read OCSSessionsFolderURL");
return rc = NO;
}
tableURL = [[NSURL alloc] initWithString: sessionsFolderURL];
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: tableURL];
if (!channel)
{
/* FIXME: nice error msg */
NSLog(@"Can't aquire channel");
return rc=NO;
}
sql = [NSString stringWithFormat: @"SELECT count(*) FROM %@ WHERE c_lastseen <= %d;",
[tableURL gcsTableName], oldest];
ex = [channel evaluateExpressionX: sql];
if (ex)
{
NSLog(@"%@", [ex reason]);
[ex raise];
return rc=NO;
}
attrs = [channel describeResults: NO];
/* only one row */
qresult = [channel fetchAttributes: attrs withZone: NULL];
qValues = [qresult allValues];
sessionsToDelete = [[qValues objectAtIndex: 0] intValue];
if (sessionsToDelete)
{
if (verbose)
NSLog(@"Will be removing %d sessions", sessionsToDelete);
[channel cancelFetch];
sql = [NSString stringWithFormat: @"DELETE FROM %@ WHERE c_lastseen <= %d;",
[tableURL gcsTableName], oldest];
if (verbose)
NSLog(@"Removing sessions older than %d minute(s)", nbMinutes);
ex = [channel evaluateExpressionX: sql];
if (ex)
{
NSLog(@"An exception occured while deleting old sessions: %@", [ex reason]);
[ex raise];
return rc=NO;
}
}
else
{
if (verbose)
NSLog(@"No session to remove", sessionsToDelete);
}
[cm releaseChannel: channel];
return rc;
}
- (BOOL) run
{
BOOL rc;
int sessionExpireMinutes=0;
rc = NO;
if ([arguments count])
{
sessionExpireMinutes = [[arguments objectAtIndex: 0] intValue];
}
if (sessionExpireMinutes > 0)
{
rc = [self expireUserSessionOlderThan: sessionExpireMinutes];
}
else
{
[self usage];
}
return rc;
}
@end

View File

@ -143,11 +143,11 @@
[helpString appendString: @" argument1, ...\targuments passed to the"
@" specified command\n\n"];
[helpString appendString: @" Available commands:\n"];
toolsEnum = [[tools allKeys] objectEnumerator];
toolsEnum = [[[tools allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectEnumerator];
while ((command = [toolsEnum nextObject]))
{
currentTool = [tools objectForKey: command];
[helpString appendFormat: @"\t%@\t-- %@\n",
[helpString appendFormat: @"\t%-20@-- %@\n",
command, [currentTool objectAtIndex: 1]];
}