From dae5253e2578ff6a470579e70731af4bba972932 Mon Sep 17 00:00:00 2001
From: Florian Zeitz <florob@babelmonkeys.de>
Date: Tue, 11 Jun 2013 18:34:44 +0200
Subject: [PATCH] Add support for accepting Subscription Requests to CLI
 frontend

---
 src/gui/cli/JubCLIUI.h |  2 ++
 src/gui/cli/JubCLIUI.m | 72 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/src/gui/cli/JubCLIUI.h b/src/gui/cli/JubCLIUI.h
index 222fc27..6d3a3e4 100644
--- a/src/gui/cli/JubCLIUI.h
+++ b/src/gui/cli/JubCLIUI.h
@@ -15,10 +15,12 @@
 	JubChatClient *_client;
 	XMPPContactManager *_contactManager;
 	OFMutableDictionary *_commands;
+	OFMutableSet *_subRequests;
 }
 @property (readonly) JubChatClient *client;
 @property (readonly) XMPPContact *lastIn;
 @property (retain) JubCLIChatUI *sink;
+@property (readonly) OFMutableSet *subRequests;
 
 - (BOOL)Jub_userInputWithStream: (OFStream*)stream
 			   line: (OFString*)line
diff --git a/src/gui/cli/JubCLIUI.m b/src/gui/cli/JubCLIUI.m
index 3cf59c2..9a62767 100644
--- a/src/gui/cli/JubCLIUI.m
+++ b/src/gui/cli/JubCLIUI.m
@@ -134,10 +134,45 @@ BEGINCLICOMMAND(JubCLIRosterCommand, @":roster", nil, @"Shows your roster")
 }
 ENDCLICOMMAND
 
+BEGINCLICOMMAND(JubCLISubsCommand, @":subs",
+    @"[list | ack <who> | nak <who>]",
+    @"Lists, acknowledges or denies subscription requests")
+{
+	if ([parameters count] < 1) {
+		[of_stdout writeLine: @"Syntax: ':subs "
+		    @"[list | ack <who> | nak <who>]'"];
+		return;
+	}
+
+	OFString *action = parameters[0];
+	if (![action isEqual: @"list"] && ([parameters count] != 2)) {
+		[of_stdout writeLine: @"Syntax: ':subs "
+		    @"[list | ack <who> | nak <who>]'"];
+		return;
+	}
+
+	if ([action isEqual: @"list"]) {
+		for (OFString *request in _ui.subRequests)
+			[of_stdout writeLine: request];
+		return;
+	}
+
+	XMPPJID *JID = [XMPPJID JIDWithString: parameters[1]];
+
+	if ([action isEqual: @"ack"])
+		[_ui.client.contactManager sendSubscribedToJID: JID];
+	else if ([action isEqual: @"nak"])
+		[_ui.client.contactManager sendUnsubscribedToJID: JID];
+
+	[_ui.subRequests removeObject: parameters[1]];
+}
+ENDCLICOMMAND
+
 @implementation JubCLIUI
 @synthesize client = _client;
 @synthesize lastIn = _lastIn;
 @synthesize sink = _sink;
+@synthesize subRequests = _subRequests;
 
 - initWithClient: (JubChatClient*)client
 {
@@ -145,6 +180,7 @@ ENDCLICOMMAND
 
 	@try {
 		_commands =  [OFMutableDictionary new];
+		_subRequests =  [OFMutableSet new];
 		_client = [client retain];
 		_contactManager = client.contactManager;
 		[_contactManager addDelegate: self];
@@ -163,6 +199,8 @@ ENDCLICOMMAND
 
 		[self addCommand: [[[JubCLIRosterCommand alloc]
 				       initWithCLIUI: self] autorelease]];
+		[self addCommand: [[[JubCLISubsCommand alloc]
+				       initWithCLIUI: self] autorelease]];
 	} @catch (id e) {
 		[self release];
 		@throw e;
@@ -175,6 +213,7 @@ ENDCLICOMMAND
 {
 	[_contactManager removeDelegate: self];
 	[_client release];
+	[_subRequests release];
 	[_commands release];
 	[super dealloc];
 }
@@ -337,6 +376,39 @@ static void completionCallback(OFString *buf, OFList *lc)
 	return YES;
 }
 
+- (void)contactManager: (XMPPContactManager*)manager
+	 didAddContact: (XMPPContact*)contact
+{
+	XMPPRosterItem *rosterItem = contact.rosterItem;
+	OFString *subscription = rosterItem.subscription;
+	OFString *bareJID = [rosterItem.JID bareJID];
+
+	if ([subscription isEqual: @"from"] || [subscription isEqual: @"both"])
+		[_subRequests removeObject: bareJID];
+}
+
+-          (void)contactManager: (XMPPContactManager*)manager
+  didReceiveSubscriptionRequest: (XMPPPresence*)presence
+{
+	OFString *bareJID = [presence.from bareJID];
+	[_subRequests addObject: bareJID];
+	[of_stdout writeFormat: @"\r" BOLD("%@") @" send a request to "
+	    @"subscribe to your presence\r\n"
+	    @"Use the :subs command to answer it\n",
+	    bareJID];
+	[[Linenoise sharedLinenoise] refreshLine];
+}
+
+-            (void)contact: (XMPPContact*)contact
+  willUpdateWithRosterItem: (XMPPRosterItem*)rosterItem
+{
+	OFString *subscription = rosterItem.subscription;
+	OFString *bareJID = [rosterItem.JID bareJID];
+
+	if ([subscription isEqual: @"from"] || [subscription isEqual: @"both"])
+		[_subRequests removeObject: bareJID];
+}
+
 -  (void)contact: (XMPPContact*)contact
   didSendMessage: (XMPPMessage*)message
 {
-- 
2.39.5