diff --git a/lib/joscar-0.9.4-cvs-bin.jar b/lib/joscar-0.9.4-cvs-bin.jar index 71ecdd1b9..4d70443e9 100644 Binary files a/lib/joscar-0.9.4-cvs-bin.jar and b/lib/joscar-0.9.4-cvs-bin.jar differ diff --git a/src/net/java/sip/communicator/impl/protocol/icq/OperationSetPersistentPresenceIcqImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/OperationSetPersistentPresenceIcqImpl.java index d81f09052..3f8404518 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/OperationSetPersistentPresenceIcqImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/OperationSetPersistentPresenceIcqImpl.java @@ -798,10 +798,13 @@ public void setAuthorizationHandler(AuthorizationHandler handler) AuthCmdFactory authCmdFactory = new AuthCmdFactory(icqProvider, icqProvider.getAimConnection(), handler); + SsiCmdFactory ssiCmdFactory = + new SsiCmdFactory(icqProvider, icqProvider.getAimConnection(), handler); + ChannelFourCmdFactory channelFourFactory = ((OperationSetBasicInstantMessagingIcqImpl) icqProvider.getSupportedOperationSets() - .get(OperationSetBasicInstantMessagingIcqImpl.class.getName())). + .get(OperationSetBasicInstantMessaging.class.getName())). getChannelFourFactory(); channelFourFactory.addCommandHandler( @@ -812,6 +815,8 @@ public void setAuthorizationHandler(AuthorizationHandler handler) IcbmChannelFourCommand.MTYPE_AUTHOK, authCmdFactory); snacProcessor.addGlobalResponseListener(authCmdFactory); + snacProcessor.getCmdFactoryMgr().getDefaultFactoryList(). + registerAll(ssiCmdFactory); // incoming future authorization commands // facList.registerAll(new AuthFutureCmdFactory()); diff --git a/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AbstractAuthCommand.java b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AbstractAuthCommand.java index cef0f21de..1dd6e253a 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AbstractAuthCommand.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AbstractAuthCommand.java @@ -30,8 +30,21 @@ public abstract class AbstractAuthCommand * Use this command to send authorization request. */ public static final int CMD_AUTH_REQUEST = 0x0018; + /** A command subtype. + * Use this command to send authorization reply. */ public static final int CMD_AUTH_REPLY = 0x001a; + /** A command subtype. + * This command indicates that authorization reply is received. */ + public static final int CMD_AUTH_REPLY_RECV = 0x001b; + /** A command subtype. + * This command indicates that authorization request is received. */ + public static final int CMD_AUTH_REQUEST_RECV = 0x0019; + + /** A command subtype. + * This command indicates that authorization request is received. */ + public static final int CMD_YOU_WERE_ADDED_RECV = 0x001c; + protected AbstractAuthCommand(int command) { super(command); diff --git a/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AuthCmdFactory.java b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AuthCmdFactory.java index 06ef7b29d..e87ac9779 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AuthCmdFactory.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AuthCmdFactory.java @@ -9,17 +9,13 @@ import java.util.*; import net.java.sip.communicator.impl.protocol.icq.*; +import net.java.sip.communicator.impl.protocol.icq.message.imicbm.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; -import net.kano.joscar.*; import net.kano.joscar.flapcmd.*; import net.kano.joscar.snac.*; -import net.kano.joscar.snaccmd.*; -import net.kano.joscar.snaccmd.icbm.*; import net.kano.joscar.snaccmd.ssi.*; import net.kano.joustsim.oscar.*; -import net.kano.joustsim.Screenname; -import net.java.sip.communicator.impl.protocol.icq.message.imicbm.*; /** * Extending the normal messages factory as its not handling the channel 4 @@ -107,13 +103,13 @@ public void handleResponse(SnacResponseEvent snacResponseEvent) if (authRequest != null) { //SNAC(13,14) send future authorization grant to client - aimConnection.getIcbmService().sendSnac( - new AuthFutureCmd( - uinToAskForAuth, - authRequest.getReason())); +// aimConnection.getSsiService().sendSnac( +// new AuthFutureCmd( +// uinToAskForAuth, +// authRequest.getReason())); //SNAC(13,18) send authorization request - aimConnection.getIcbmService().sendSnac( + aimConnection.getSsiService().sendSnac( new RequestAuthCmd( uinToAskForAuth, authRequest.getReason())); @@ -122,13 +118,12 @@ public void handleResponse(SnacResponseEvent snacResponseEvent) BuddyAwaitingAuth newBuddy = new BuddyAwaitingAuth( buddyItem); - items.add(newBuddy); + buddiesToBeAdded.add(newBuddy); - CreateItemsCmd addCMD = new CreateItemsCmd( - buddiesToBeAdded); + CreateItemsCmd addCMD = new CreateItemsCmd(buddiesToBeAdded); logger.trace("Adding buddy as awaiting authorization"); - aimConnection.getIcbmService().sendSnac(addCMD); + aimConnection.getSsiService().sendSnac(addCMD); return; } diff --git a/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AuthReplyCmd.java b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AuthReplyCmd.java index 1b774241e..7e7566087 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AuthReplyCmd.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/AuthReplyCmd.java @@ -8,7 +8,9 @@ import java.io.*; +import net.java.sip.communicator.impl.protocol.icq.message.common.*; import net.kano.joscar.*; +import net.kano.joscar.flapcmd.*; /** * Sending authorization reply @@ -34,6 +36,29 @@ public AuthReplyCmd(String uin, String reason, boolean accepted) this.accepted = accepted; } + /** + * Incoming Command reply for our Authorization request + * @param packet SnacPacket the incoming packet + */ + public AuthReplyCmd(SnacPacket packet) + { + super(CMD_AUTH_REPLY_RECV); + + ByteBlock messageData = packet.getData(); + // parse data + int offset = 0; + short uinLen = BinaryTools.getUByte(messageData, offset++); + uin = OscarTools.getString(messageData.subBlock(offset, uinLen), "US-ASCII"); + offset += uinLen; + + accepted = + BinaryTools.getUByte(messageData, offset++) == FLAG_AUTH_ACCEPTED; + + int reasonLen = BinaryTools.getUShort(messageData, offset); + offset += 2; + reason = OscarTools.getString(messageData.subBlock(offset, reasonLen), "US-ASCII"); + } + /** * Writes this command's SNAC data block to the given stream. * @@ -64,4 +89,19 @@ public void writeData(OutputStream out) throws IOException BinaryTools.writeUShort(out, reasonBytes.length); out.write(reasonBytes); } + + public String getSender() + { + return uin; + } + + public String getReason() + { + return reason; + } + + public boolean isAccepted() + { + return accepted; + } } diff --git a/src/net/java/sip/communicator/impl/protocol/icq/message/auth/RequestAuthCmd.java b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/RequestAuthCmd.java index 4d945dbc5..5b54ae9b3 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/message/auth/RequestAuthCmd.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/RequestAuthCmd.java @@ -8,7 +8,9 @@ import java.io.*; +import net.java.sip.communicator.impl.protocol.icq.message.common.*; import net.kano.joscar.*; +import net.kano.joscar.flapcmd.*; /** * Command requesting authorization @@ -28,6 +30,26 @@ public RequestAuthCmd(String uin, String reason) this.reason = reason; } + /** + * Incoming Command Requesting our authorization + * @param packet SnacPacket incoming packet + */ + public RequestAuthCmd(SnacPacket packet) + { + super(CMD_AUTH_REQUEST_RECV); + + ByteBlock messageData = packet.getData(); + // parse data + int offset = 0; + short uinLen = BinaryTools.getUByte(messageData, offset++); + uin = OscarTools.getString(messageData.subBlock(offset, uinLen), "US-ASCII"); + offset += uinLen; + + int reasonLen = BinaryTools.getUShort(messageData, offset); + offset += 2; + reason = OscarTools.getString(messageData.subBlock(offset, reasonLen), "US-ASCII"); + } + /** * Writes this command's SNAC data block to the given stream. * @@ -49,4 +71,15 @@ public void writeData(OutputStream out) throws IOException BinaryTools.writeUShort(out, reasonBytes.length); out.write(reasonBytes); } + + public String getReason() + { + return reason; + } + + public String getSender() + { + return uin; + } + } diff --git a/src/net/java/sip/communicator/impl/protocol/icq/message/auth/SsiCmdFactory.java b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/SsiCmdFactory.java new file mode 100644 index 000000000..cdd1a043c --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/icq/message/auth/SsiCmdFactory.java @@ -0,0 +1,172 @@ +package net.java.sip.communicator.impl.protocol.icq.message.auth; + +import java.util.*; + +import net.java.sip.communicator.impl.protocol.icq.*; +import net.java.sip.communicator.service.protocol.*; +import net.kano.joscar.*; +import net.kano.joscar.flapcmd.*; +import net.kano.joscar.snac.*; +import net.kano.joscar.snaccmd.ssi.*; +import net.kano.joustsim.oscar.*; +import net.java.sip.communicator.service.protocol.AuthorizationResponse.AuthorizationResponseCode; +import net.java.sip.communicator.util.Logger; + +/** + * @author Damian Minkov + */ +public class SsiCmdFactory + extends ServerSsiCmdFactory +{ + private static final Logger logger = + Logger.getLogger(SsiCmdFactory.class); + + protected static List SUPPORTED_TYPES = null; + + private ProtocolProviderServiceIcqImpl icqProvider; + private AuthorizationHandler authorizationHandler; + private OperationSetPersistentPresenceIcqImpl operationSetPresence; + private AimConnection aimConnection = null; + + public SsiCmdFactory(ProtocolProviderServiceIcqImpl icqProvider, + AimConnection aimConnection, + AuthorizationHandler authorizationHandler) + { + this.icqProvider = icqProvider; + this.authorizationHandler = authorizationHandler; + this.aimConnection = aimConnection; + + List types = super.getSupportedTypes(); + ArrayList tempTypes = new ArrayList(types); + tempTypes.add(new CmdType( + SsiCommand.FAMILY_SSI, AbstractAuthCommand.CMD_AUTH_REPLY_RECV)); // 1b auth request reply + tempTypes.add(new CmdType( + SsiCommand.FAMILY_SSI, AbstractAuthCommand.CMD_AUTH_REQUEST_RECV)); // 19 auth request +// tempTypes.add(new CmdType( +// SsiCommand.FAMILY_SSI, AbstractAuthCommand.CMD_YOU_WERE_ADDED_RECV)); // 1c you were added + + this.SUPPORTED_TYPES = DefensiveTools.getUnmodifiable(tempTypes); + + this.operationSetPresence = + (OperationSetPersistentPresenceIcqImpl) + icqProvider.getSupportedOperationSets(). + get(OperationSetPresence.class.getName()); + } + + /** + * Attempts to convert the given SNAC packet to a + * SnacCommand. + * + * @param packet the packet to use for generation of a + * SnacCommand + * @return an appropriate SnacCommand for representing the + * given SnacPacket, or null if no such + * object can be created + */ + public SnacCommand genSnacCommand(SnacPacket packet) + { + int command = packet.getCommand(); + + if(command == AbstractAuthCommand.CMD_AUTH_REPLY_RECV) + { + logger.trace("Received Authorization Replay!"); + + AuthReplyCmd cmd = new AuthReplyCmd(packet); + + Contact srcContact = getContact(cmd.getSender()); + + AuthorizationResponseCode authResponseCode = null; + + if(cmd.isAccepted()) + authResponseCode = AuthorizationResponse.ACCEPT; + else + authResponseCode = AuthorizationResponse.REJECT; + + AuthorizationResponse authResponse = + new AuthorizationResponse(authResponseCode, cmd.getReason()); + +// try +// { +// // the contact must be subscribed again so the 0x66 - +// // awaiting authorization is removed +// if (cmd.isAccepted()) +// { +// operationSetPresence.subscribe(cmd.getSender()); +// } +// } +// catch (OperationFailedException ex) +// {} + + authorizationHandler.processAuthorizationResponse( + authResponse, srcContact); + + return cmd; + } + else + if(command == AbstractAuthCommand.CMD_AUTH_REQUEST_RECV) + { + logger.trace("Received Authorization Request!"); + + RequestAuthCmd cmd = new RequestAuthCmd(packet); + + AuthorizationRequest authRequest = new AuthorizationRequest(); + authRequest.setReason(cmd.getReason()); + + Contact srcContact = getContact(cmd.getSender()); + + AuthorizationResponse authResponse = + authorizationHandler.processAuthorisationRequest( + authRequest,srcContact); + + if (authResponse.getResponseCode() == + AuthorizationResponse.ACCEPT) + { + aimConnection.getInfoService().sendSnac( + new AuthReplyCmd( + String.valueOf(icqProvider.getAccountID(). + getAccountUserID()), + authResponse.getReason(), + true)); + } + else if (authResponse.getResponseCode() == + AuthorizationResponse.REJECT) + { + aimConnection.getInfoService().sendSnac( + new AuthReplyCmd( + String.valueOf(icqProvider.getAccountID(). + getAccountUserID()), + authResponse.getReason(), + false)); + } + + + return cmd; + } + + return super.genSnacCommand(packet); + } + + /** + * Returns a list of the SNAC command types this factory can possibly + * convert to SnacCommands. + * + * @return a list of command types that can be passed to + * genSnacCommand + */ + public List getSupportedTypes() + { + return SUPPORTED_TYPES; + } + + private Contact getContact(String uin) + { + Contact contact = + operationSetPresence.findContactByID(uin); + + if(contact == null) + contact = operationSetPresence.createVolatileContact(uin); + + return contact; + } + +} diff --git a/test/net/java/sip/communicator/slick/protocol/icq/IcqProtocolProviderSlick.java b/test/net/java/sip/communicator/slick/protocol/icq/IcqProtocolProviderSlick.java index 6a6f02b5f..c4aed8137 100644 --- a/test/net/java/sip/communicator/slick/protocol/icq/IcqProtocolProviderSlick.java +++ b/test/net/java/sip/communicator/slick/protocol/icq/IcqProtocolProviderSlick.java @@ -75,6 +75,7 @@ public void start(BundleContext bundleContext) throws Exception "Registering the IcqTesterAgent on icq has failed.(Possible " +"reasons: authetification failed, or Connection rate limit " +"exceeded.)"); + IcqSlickFixture.testerAgent.setAuthorizationRequired(); //initialize the tested account's contact list so that it could be ready //when testing starts. @@ -196,6 +197,7 @@ private void initializeTestedContactList() cListInitTesterAgent.register( System.getProperty(TESTED_IMPL_PWD_PROP_NAME, null) ); + cListInitTesterAgent.setAuthorizationRequired(); cListInitTesterAgent.initializeBuddyList(contactListToCreate); diff --git a/test/net/java/sip/communicator/slick/protocol/icq/IcqTesterAgent.java b/test/net/java/sip/communicator/slick/protocol/icq/IcqTesterAgent.java index 7ed14c0b0..72e8e8443 100644 --- a/test/net/java/sip/communicator/slick/protocol/icq/IcqTesterAgent.java +++ b/test/net/java/sip/communicator/slick/protocol/icq/IcqTesterAgent.java @@ -1135,36 +1135,6 @@ protected void writeChannelData(OutputStream out) } } -/* - private class AuthRequiredListener - implements SnacResponseListener - { - public void handleResponse(SnacResponseEvent snacResponseEvent) - { - if (snacResponseEvent.getSnacCommand() instanceof SsiDataModResponse) - { - SsiDataModResponse dataModResponse = - (SsiDataModResponse) snacResponseEvent.getSnacCommand(); - - int[] results = dataModResponse.getResults(); - List items = ( (ItemsCmd) snacResponseEvent.getRequest().getCommand()). - getItems(); - items = new LinkedList(items); - - for (int i = 0; i < results.length; i++) - { - int result = results[i]; - if (result == - SsiDataModResponse.RESULT_ICQ_AUTH_REQUIRED) - { - conn.sendSnac(new AuthReplyCmd("", "First Test - Not Accepted!", false)); - } - } - } - } - } - */ - private class AuthReplyCmd extends SsiCommand { @@ -1175,6 +1145,25 @@ private class AuthReplyCmd private String reason = null; private boolean accepted = false; + public AuthReplyCmd(SnacPacket packet) + { + super(0x001b); + + ByteBlock messageData = packet.getData(); + // parse data + int offset = 0; + short uinLen = BinaryTools.getUByte(messageData, offset++); + uin = OscarTools.getString(messageData.subBlock(offset, uinLen), "US-ASCII"); + offset += uinLen; + + accepted = BinaryTools.getUByte(messageData, offset++) == 1; + + int reasonLen = BinaryTools.getUShort(messageData, offset); + offset += 2; + reason = OscarTools.getString(messageData.subBlock(offset, reasonLen), "US-ASCII"); + } + + public AuthReplyCmd(String uin, String reason, boolean accepted) { super(0x001a); @@ -1210,12 +1199,10 @@ public void writeData(OutputStream out) } public class AuthCmdFactory - extends ClientIcbmCmdFactory + extends ServerSsiCmdFactory { List SUPPORTED_TYPES = null; - public static final int CHANNEL_AUTH = 0x0004; - public String responseReasonStr = null; public String requestReasonStr = null; public boolean ACCEPT = false; @@ -1224,140 +1211,173 @@ public AuthCmdFactory() { List types = super.getSupportedTypes(); ArrayList tempTypes = new ArrayList(types); - tempTypes.add(new CmdType(4, 7)); + tempTypes.add(new CmdType(SsiCommand.FAMILY_SSI, 0x001b)); // 1b auth request reply + tempTypes.add(new CmdType(SsiCommand.FAMILY_SSI, 0x0019)); // 19 auth request this.SUPPORTED_TYPES = DefensiveTools.getUnmodifiable(tempTypes); } + public List getSupportedTypes() + {return SUPPORTED_TYPES;} + public SnacCommand genSnacCommand(SnacPacket packet) { - if (AbstractIcbm.getIcbmChannel(packet) == CHANNEL_AUTH) - { - AuthOldMsgCmd messageCommand = new AuthOldMsgCmd(packet); - - int messageType = messageCommand.messageType; + int command = packet.getCommand(); - if (messageType == AuthOldMsgCmd.MTYPE_AUTHREQ) - { - requestReasonStr = messageCommand.reason; - - logger.trace("sending authorization " + ACCEPT); + // auth reply +// if (command == 0x001b) + // auth request + if (command == 25) + { + RequestAuthCmd cmd = new RequestAuthCmd(packet); + requestReasonStr = cmd.reason; + System.out.println("sending authorization " + ACCEPT); + logger.trace("sending authorization " + ACCEPT); + conn.sendSnac( + new AuthReplyCmd( + String.valueOf(cmd.uin), + responseReasonStr, + ACCEPT)); + return cmd; + } + else if (command == 26) // auth reply + { + AuthReplyCmd cmd = new AuthReplyCmd(packet); - conn.sendSnac( - new AuthReplyCmd( - String.valueOf(messageCommand.sender), - responseReasonStr, - ACCEPT)); - } - else - if (messageType == AuthOldMsgCmd.MTYPE_AUTHDENY) - { - // - } - else - if (messageType == AuthOldMsgCmd.MTYPE_AUTHOK) - { - // - } - else + System.out.println("cmd " + cmd); + System.out.println("is accepted " + cmd.accepted); + System.out.println("reason " + cmd.reason); - return messageCommand; + return cmd; } return super.genSnacCommand(packet); } - - public List getSupportedTypes() - { - return SUPPORTED_TYPES; - } } - private class AuthOldMsgCmd - extends AbstractImIcbm + public class RequestAuthCmd + extends SsiCommand { - private static final int TYPE_MESSAGE_DATA = 0x0005; - - public static final int MTYPE_AUTHREQ = 0x06; - public static final int MTYPE_AUTHDENY = 0x07; - public static final int MTYPE_AUTHOK = 0x08; - public static final int MTYPE_ADDED = 0x0c; - - private int messageType = -1; + String uin; + String reason; - private long sender; - private String reason; + public RequestAuthCmd(String uin, String reason) + { + super(0x0018); + this.uin = uin; + this.reason = reason; + } - public AuthOldMsgCmd(SnacPacket packet) + public RequestAuthCmd(SnacPacket packet) { - super(IcbmCommand.CMD_ICBM, packet); + super(0x0019); - DefensiveTools.checkNull(packet, "packet"); + ByteBlock messageData = packet.getData(); + // parse data + int offset = 0; + short uinLen = BinaryTools.getUByte(messageData, offset); + offset++; - ByteBlock snacData = getChannelData(); + uin = OscarTools.getString(messageData.subBlock(offset, uinLen),"US-ASCII"); - FullUserInfo userInfo = FullUserInfo.readUserInfo(snacData); + offset += uinLen; - ByteBlock tlvBlock = snacData.subBlock(userInfo.getTotalSize()); + int reasonLen = BinaryTools.getUShort(messageData, offset); + offset+=2; - TlvChain chain = TlvTools.readChain(tlvBlock); + reason = + OscarTools.getString(messageData.subBlock(offset, reasonLen), "US-ASCII"); + } - Tlv messageDataTlv = chain.getLastTlv(TYPE_MESSAGE_DATA); - ByteBlock messageData = messageDataTlv.getData(); + public void writeData(OutputStream out) throws IOException + { + byte[] uinBytes = BinaryTools.getAsciiBytes(uin); + BinaryTools.writeUByte(out, uinBytes.length); + out.write(uinBytes); - sender = LEBinaryTools.getUInt(messageData, 0); - messageType = LEBinaryTools.getUByte(messageData, 4); - int msgFlags = LEBinaryTools.getUByte(messageData, 5); - int textlen = LEBinaryTools.getUShort(messageData, 6); + if (reason == null) + { + reason = ""; + } - ByteBlock field = messageData.subBlock(8, textlen); - reason = OscarTools.getString(field, "US-ASCII"); + byte[] reasonBytes = BinaryTools.getAsciiBytes(reason); + BinaryTools.writeUShort(out, reasonBytes.length); + out.write(reasonBytes); } - - protected void writeChannelData(OutputStream out) - throws IOException - {} } - private static class LEBinaryTools + public void setAuthorizationRequired() { - public static final long UINT_MAX = 4294967295L; - public static final int USHORT_MAX = 65535; - public static final short UBYTE_MAX = 255; + logger.debug("sending auth required"); + conn.getSsiService().sendSnac(new SaveInfoRequest()); + } - public static long getUInt(final ByteBlock data, final int pos) + private class SaveInfoRequest + extends SnacCommand + { + public SaveInfoRequest() { - if (data.getLength() - pos < 4) - { - return -1; - } - - return ( ( (long) data.get(pos + 3) & 0xffL) << 24) - | ( ( (long) data.get(pos + 2) & 0xffL) << 16) - | ( ( (long) data.get(pos + 1) & 0xffL) << 8) - | ( (long) data.get(pos) & 0xffL); + super(21,2); } - public static short getUByte(final ByteBlock data, final int pos) + public void writeData(OutputStream out) + throws IOException { - if (data.getLength() - pos < 1) - { - return -1; - } + ByteArrayOutputStream icqout = new ByteArrayOutputStream(); + + ByteArrayOutputStream icqDataOut = new ByteArrayOutputStream(); + byte b[] = new byte[]{ + (byte)0xf8, (byte)0x02, // 0x02F8 User 'show web status' permissions + (byte)0x01, (byte)0x00, (byte)0x00, + (byte)0x0c, (byte)0x03, // 0x030C User authorization permissions + (byte)0x01, (byte)0x00, (byte)0x00 + }; + icqDataOut.write(b); + +// new Tlv(0x030C, ByteBlock.wrap(b)).write(icqDataOut); + + int hdrlen = 10; // The expected header length, not counting the length field itself. + int primary = 0x07D0; + int secondary = 0x0c3a; + + long icqUINlong = Long.parseLong(icqUIN.getFormatted()); + + int length = hdrlen + icqDataOut.size(); - return (short) (data.get(pos) & 0xff); + writeUShort(icqout, length); + writeUInt(icqout, icqUINlong); + writeUShort(icqout, primary); + writeUShort(icqout, 0); // the sequence + + writeUShort(icqout, secondary); + + icqDataOut.writeTo(icqout); + + logger.debug("now we will write data!"); + System.out.println("now we will write data!"); + new Tlv(0x0001, ByteBlock.wrap(icqout.toByteArray())).write(out); } - public static int getUShort(final ByteBlock data, final int pos) + public void writeUInt(final OutputStream out, final long number) + throws IOException { - if (data.getLength() - pos < 2) - { - return -1; - } + out.write(new byte[] { + (byte)((number) & 0xff), + (byte)((number >> 8) & 0xff), + (byte)((number >> 16) & 0xff), + (byte)((number >> 24) & 0xff) + }); + } - return ( (data.get(pos + 1) & 0xff) << 8) | (data.get(pos) & 0xff); + public void writeUShort(OutputStream out, int number) + throws IOException + { + out.write(new byte[] + { + (byte)(number & 0xff), + (byte)((number >> 8) & 0xff) + }); } } - } diff --git a/test/net/java/sip/communicator/slick/protocol/icq/TestOperationSetPresence.java b/test/net/java/sip/communicator/slick/protocol/icq/TestOperationSetPresence.java index 3f65a657c..6aad6d587 100644 --- a/test/net/java/sip/communicator/slick/protocol/icq/TestOperationSetPresence.java +++ b/test/net/java/sip/communicator/slick/protocol/icq/TestOperationSetPresence.java @@ -39,10 +39,6 @@ public class TestOperationSetPresence private OperationSetPresence operationSetPresence = null; private String statusMessageRoot = new String("Our status is now: "); - private AuthEventCollector authEventCollector = new AuthEventCollector(); -// private AuthCmdFactory authCmdFactory = new AuthCmdFactory(); - private Object authorizationLock = new Object(); - public TestOperationSetPresence(String name) { super(name); @@ -417,130 +413,137 @@ public void postTestSubscribe() // First create a subscription and verify that it really gets created. SubscriptionEventCollector subEvtCollector = new SubscriptionEventCollector(); - operationSetPresence.addSubsciptionListener(subEvtCollector); + AuthEventCollector authEventCollector = new AuthEventCollector(); -// operationSetPresence.setAuthorizationHandler(authEventCollector); + logger.trace("set Auth Handler"); + operationSetPresence.setAuthorizationHandler(authEventCollector); - synchronized(subEvtCollector){ + synchronized(authEventCollector) + { + authEventCollector.authorizationRequestReason = + "Please deny my request!"; + fixture.testerAgent.getAuthCmdFactory().responseReasonStr = + "First authorization I will Deny!!!"; + fixture.testerAgent.getAuthCmdFactory().ACCEPT = false; + operationSetPresence.subscribe(fixture.testerAgent.getIcqUIN()); + + // this one collects event that the buddy has been added + // to the list as awaiting + SubscriptionEventCollector moveEvtCollector + = new SubscriptionEventCollector(); + operationSetPresence.addSubsciptionListener(moveEvtCollector); + + logger.debug("Waiting for authorization error and authorization response..."); + authEventCollector.waitForAuthResponse(15000); + assertTrue("Error adding buddy not recieved or the buddy(" + + fixture.testerAgent.getIcqUIN() + + ") doesn't require authorization", + authEventCollector.isAuthorizationRequestSent); + + assertNotNull("Agent haven't received any reason for authorization", + fixture.testerAgent.getAuthCmdFactory().requestReasonStr); + assertEquals("Error sent request reason is not as the received one", + authEventCollector.authorizationRequestReason, + fixture.testerAgent.getAuthCmdFactory().requestReasonStr + ); + + logger.debug("authEventCollector.isAuthorizationResponseReceived " + + authEventCollector.isAuthorizationResponseReceived); + + assertTrue("Response not received!", + authEventCollector.isAuthorizationResponseReceived); + + boolean isAcceptedAuthReuest = + authEventCollector.response.getResponseCode().equals(AuthorizationResponse.ACCEPT); + assertEquals("Response is not as the sent one", + fixture.testerAgent.getAuthCmdFactory().ACCEPT, + isAcceptedAuthReuest); + assertNotNull("We didn't receive any reason! ", + authEventCollector.authorizationResponseString); + + assertEquals("The sent response reason is not as the received one", + fixture.testerAgent.getAuthCmdFactory().responseReasonStr, + authEventCollector.authorizationResponseString); + + // here we must wait for server to move the awaiting buddy + // to the first specified group + synchronized(moveEvtCollector){ + moveEvtCollector.waitForEvent(20000); + //don't want any more events + operationSetPresence.removeSubscriptionListener(moveEvtCollector); + } + + Contact c = operationSetPresence.findContactByID( + fixture.testerAgent.getIcqUIN()); + logger.debug("I will remove " + c + + " from group : " + c.getParentContactGroup()); + + UnsubscribeWait unsubscribeEvtCollector + = new UnsubscribeWait(); + operationSetPresence.addSubsciptionListener(unsubscribeEvtCollector); + synchronized(unsubscribeEvtCollector){ + operationSetPresence.unsubscribe(c); + logger.debug("Waiting to be removed..."); + unsubscribeEvtCollector.waitForUnsubscribre(20000); -// try -// { -// synchronized(authorizationLock) -// { -// authEventCollector.authorizationRequestReason = -// "Please deny my request!"; -// fixture.testerAgent.getAuthCmdFactory().responseReasonStr = -// "First authorization I will Deny!!!"; -// fixture.testerAgent.getAuthCmdFactory().ACCEPT = false; -// -// logger.trace("is contact there 1 = " + -// operationSetPresence.findContactByID(fixture.testerAgent.getIcqUIN())); -// - - operationSetPresence.subscribe(fixture.testerAgent.getIcqUIN()); - -// logger.debug("Waiting for authorization error and authorization response..."); -// authorizationLock.wait(5000); -// -// assertTrue("Error adding buddy not recieved or the buddy(" + -// fixture.testerAgent.getIcqUIN() + -// ") doesn't require authorization", -// authEventCollector.isAuthorizationRequestSent); -// -// assertNotNull("Agent haven't received any reason for authorization", -// fixture.testerAgent.getAuthCmdFactory().requestReasonStr); - -// not working for now -// assertEquals("Error sent request reason is not as the received one", -// authEventCollector.authorizationRequestReason, -// fixture.testerAgent.getAuthCmdFactory().requestReasonStr -// ); - -// assertTrue("Response not received!", -// authEventCollector.isAuthorizationResponseReceived); -// -// boolean isAcceptedAuthReuest = -// authEventCollector.response.getResponseCode().equals(AuthorizationResponse.ACCEPT); -// -// assertEquals("Response is not as the sent one", -// fixture.testerAgent.getAuthCmdFactory().ACCEPT, -// isAcceptedAuthReuest); -// assertNotNull("We didn't receive any reason! ", -// authEventCollector.authorizationResponseString); - -// the same as request reason -// assertEquals("The sent response reason is not as the received one", -// fixture.testerAgent.getAuthCmdFactory().responseReasonStr, -// authEventCollector.authorizationResponseString); - -// logger.trace("is contact there 2 = " + -// operationSetPresence.findContactByID(fixture.testerAgent.getIcqUIN())); - -// operationSetPresence.unsubscribe( -// operationSetPresence.findContactByID( -// fixture.testerAgent.getIcqUIN())); - - // so we haven't asserted so everithing is fine lets try to be authorized -// authEventCollector.authorizationRequestReason = -// "Please accept my request!"; -// fixture.testerAgent.getAuthCmdFactory().responseReasonStr = -// "Second authorization I will Accept!!!"; -// fixture.testerAgent.getAuthCmdFactory().ACCEPT = true; -// -// // clear some things -// authEventCollector.isAuthorizationRequestSent = false; -// authEventCollector.authorizationRequestReason = null; -// authEventCollector.isAuthorizationResponseReceived = false; -// authEventCollector.authorizationResponseString = null; - - // subscribe again so we can trigger again the authorization procedure -// operationSetPresence.subscribe(fixture.testerAgent.getIcqUIN()); - -// logger.debug("Waiting for response..."); -// authorizationLock.wait(5000); -// -// assertTrue("Error adding buddy not recieved or the buddy(" + -// fixture.testerAgent.getIcqUIN() + -// ") doesn't require authorization", -// authEventCollector.isAuthorizationRequestSent); -// -// assertNotNull("Agent haven't received any reason for authorization", -// fixture.testerAgent.getAuthCmdFactory().requestReasonStr); - - // not working for now -// assertEquals("Error sent request reason", -// authEventCollector.authorizationRequestReason, -// fixture.testerAgent.getAuthCmdFactory().requestReasonStr -// ); - - -// suspect that response is never received just the buddy is added -// assertTrue("Response not received!", -// authEventCollector.isAuthorizationResponseReceived); -// -// isAcceptedAuthReuest = -// authEventCollector.response.getResponseCode().equals(AuthorizationResponse.ACCEPT); -// -// assertEquals("Response is not as the sent one", -// fixture.testerAgent.getAuthCmdFactory().ACCEPT, -// isAcceptedAuthReuest); -// -// assertNotNull("We didn't receive any reason! ", -// authEventCollector.authorizationResponseString); - -// the same as request reason -// assertEquals("The sent response reason", -// fixture.testerAgent.getAuthCmdFactory().responseReasonStr, -// authEventCollector.authorizationResponseString); -// } -// } -// catch (InterruptedException ex) -// { -// logger.debug("Interrupted while waiting ... ", ex); -// } + logger.debug("Received unsubscribed ok or we lost patients!"); + //don't want any more events + operationSetPresence.removeSubscriptionListener(unsubscribeEvtCollector); + } + + // so we haven't asserted so everithing is fine lets try to be authorized + authEventCollector.authorizationRequestReason = + "Please accept my request!"; + fixture.testerAgent.getAuthCmdFactory().responseReasonStr = + "Second authorization I will Accept!!!"; + fixture.testerAgent.getAuthCmdFactory().ACCEPT = true; + + // clear some things + authEventCollector.isAuthorizationRequestSent = false; + authEventCollector.isAuthorizationResponseReceived = false; + authEventCollector.authorizationResponseString = null; + + + logger.debug("I will add buddy does it exists ? " + + (operationSetPresence.findContactByID(fixture.testerAgent.getIcqUIN()) != null)); + // add the listener beacuse now our authorization will be accepted + // and so the buddy will be finally added to the list + operationSetPresence.addSubsciptionListener(subEvtCollector); + // subscribe again so we can trigger again the authorization procedure + operationSetPresence.subscribe(fixture.testerAgent.getIcqUIN()); + + logger.debug("Waiting ... Subscribe must fail and the authorization process " + + "to be trigered again so waiting for auth response ..."); + authEventCollector.waitForAuthResponse(15000); + + assertTrue("Error adding buddy not recieved or the buddy(" + + fixture.testerAgent.getIcqUIN() + + ") doesn't require authorization", + authEventCollector.isAuthorizationRequestSent); + + assertNotNull("Agent haven't received any reason for authorization", + fixture.testerAgent.getAuthCmdFactory().requestReasonStr); + + // not working for now + assertEquals("Error sent request reason", + authEventCollector.authorizationRequestReason, + fixture.testerAgent.getAuthCmdFactory().requestReasonStr + ); + + + // wait for authorization process to be finnished + // the modification of buddy (server will inform us + // that he removed - awaiting authorization flag) + Object obj = new Object(); + synchronized(obj) + { + logger.debug("wait for authorization process to be finnished"); + obj.wait(10000); + logger.debug("Stop waiting!"); + } subEvtCollector.waitForEvent(10000); //don't want any more events @@ -620,7 +623,7 @@ public void postTestSubscribe() + testerAgentNewStatus.getStatusName() + " state."); } //we may already have the event, but it won't hurt to check. - contactPresEvtCollector.waitForEvent(10000); + contactPresEvtCollector.waitForEvent(12000); operationSetPresence .removeContactPresenceStatusListener(contactPresEvtCollector); } @@ -1047,19 +1050,69 @@ public AuthorizationRequest createAuthorizationRequest(Contact contact) public void processAuthorizationResponse(AuthorizationResponse response, Contact sourceContact) { - isAuthorizationResponseReceived = true; - this.response = response; - authorizationResponseString = response.getReason(); + synchronized(this) + { + isAuthorizationResponseReceived = true; + this.response = response; + authorizationResponseString = response.getReason(); - logger.trace("processAuthorizationResponse '" + - authorizationResponseString + "' " + - response.getResponseCode() + " " + - sourceContact); + logger.trace("processAuthorizationResponse '" + + authorizationResponseString + "' " + + response.getResponseCode() + " " + + sourceContact); - synchronized(authorizationLock) + notifyAll(); + } + } + + public void waitForAuthResponse(long waitFor) + { + synchronized(this){ + if(isAuthorizationResponseReceived) return; + try{ + wait(waitFor); + } + catch (InterruptedException ex){ + logger.debug( + "Interrupted while waiting for a subscription evt", ex); + } + } + } + + } + + private class UnsubscribeWait implements SubscriptionListener + { + public void waitForUnsubscribre(long waitFor) + { + synchronized(this){ + try{ + wait(waitFor); + } + catch (InterruptedException ex){ + logger.debug( + "Interrupted while waiting for a subscription evt", ex); + } + } + } + + public void subscriptionRemoved(SubscriptionEvent evt) + { + synchronized(this) { - authorizationLock.notifyAll(); + logger.debug("Got subscriptionRemoved " + evt); + notifyAll(); } } + + public void subscriptionCreated(SubscriptionEvent evt) + {} + public void subscriptionFailed(SubscriptionEvent evt) + {} + public void subscriptionMoved(SubscriptionMovedEvent evt) + {} + public void subscriptionResolved(SubscriptionEvent evt) + {} } + }