JABMakeGroupBuddiesAction.m [plain text]
//
// JABMakeGroupBuddiesAction.m
// ChatServer/jabber_autobuddy
//
// Created by Steve Peralta on 7/18/08.
// Copyright 2008 Apple. All rights reserved.
//
#import "JABMakeGroupBuddiesAction.h"
#import "JABAddRosterUserAction.h"
#include <membershipPriv.h>
#include <membership.h>
enum {
RosterGroupAction_None = 0,
RosterGroupAction_Add,
RosterGroupAction_Delete
};
@implementation JABMakeGroupBuddiesAction
@synthesize groupName = _groupName;
//------------------------------------------------------------------------------
- (id) initWithCommandOptions: (NSDictionary *) cmdOpts
{
self = [super initWithCommandOptions: cmdOpts];
self.groupName = [cmdOpts objectForKey: CMDOPT_KEY_GROUPNAME];
return self;
}
- (void) dealloc
{
self.groupName = nil;
[super dealloc];
}
//------------------------------------------------------------------------------
- (void) addRosterItemForOwner: (NSString *) ownerJid andBuddy: (NSString *) buddyJid
{
// Create a roster-group entry for the pair
// set up an local autorelease pool to limit high-water memory usage
NSAutoreleasePool *aPool = [[NSAutoreleasePool alloc] init];
do { // not a loop
// check group membership for pair
BOOL bAreMembers = [self verifyGroupMembershipForOwner: ownerJid
andBuddy: buddyJid];
// check if the pairing exists in our special auto-add group
BOOL bExists = [_database verifyRosterGroup: _groupName
forOwner: ownerJid
andBuddy: buddyJid];
if (![self checkDatabaseStatus])
break; // operation failed -- abort processing
// Select the roster-groups/roster-items action to be taken
NSInteger iRGAction = RosterGroupAction_None;
if (bAreMembers && !bExists) // members that need to be added
iRGAction = RosterGroupAction_Add;
else if (!bAreMembers && bExists) // non-member that need to be removed
iRGAction = RosterGroupAction_Delete;
// Execute the action
switch (iRGAction) {
case RosterGroupAction_Add:
// Use base-class to handle creation of roster-item pair
[super addRosterItemForOwner: ownerJid andBuddy: buddyJid];
if (OPRESULT_OK != self.result) break; // query failed -- abort
// add the roster-group entry for the new roster-item
// NOTE: it is not necessary to perform the reverse pairing here
// as it will will be performed when the buddyJid becomes
// the ownerJid in a later iteration.
[_database insertRosterGroup: _groupName
forOwner: ownerJid
andBuddy: buddyJid
source: __PRETTY_FUNCTION__
line: __LINE__];
[self checkDatabaseStatus];
break; // done
case RosterGroupAction_Delete:
// Pairings outside the group are automatically removed ONLY IF
// they also exist in the roster-groups table. This extra check
// reduces the possibility of deleting user-added buddy pairings.
[_database deleteRosterGroup: _groupName
forOwner: ownerJid
andBuddy: buddyJid
source: __PRETTY_FUNCTION__
line: __LINE__];
if (![self checkDatabaseStatus]) break; // operation failed -- abort processing
// ...and remove the roster-item
[_database deleteRosterItemForOwner: ownerJid
andBuddy: buddyJid
source: __PRETTY_FUNCTION__
line: __LINE__];
[self checkDatabaseStatus];
break; // done
default: ; // no action required
} // switch
} while (0); // not a loop
[aPool drain];
}
//------------------------------------------------------------------------------
- (BOOL) verifyGroupMembershipForOwner: (NSString *) ownerJid andBuddy: (NSString *) buddyJid
{
// verify group membership for both parties
if (![self isGroupMemberJid: ownerJid])
return NO;
return [self isGroupMemberJid: buddyJid];
}
//------------------------------------------------------------------------------
- (BOOL) isGroupMemberJid: (NSString *) aJid
{
// Isolate the user name from the jid and verify that it's a directory user
NSString *userName = [[aJid componentsSeparatedByString: @"@"] objectAtIndex: 0];
if (nil == userName) {
[self logMalformedJidError: aJid];
self.result = OPRESULT_FAILED;
return NO;
}
// Figure if user (short name) is member of asked group (short name).
if ([userName UTF8String] == NULL || [_groupName UTF8String] == NULL)
return NO;
uuid_t user_uuid;
if (0 != mbr_user_name_to_uuid([userName UTF8String], user_uuid))
return NO;
uuid_t group_uuid;
if (0 != mbr_group_name_to_uuid([_groupName UTF8String], group_uuid))
return NO;
int isMember;
if (0 != mbr_check_membership(user_uuid, group_uuid, &isMember))
return NO;
return (0 != isMember);
}
@end