Authorization for SIP protocol, implement subscribe for presence.winfo rfc3857, rfc3858, rfc5025. Add block and polite-block to the currently available allow rules in xcap implementation and using them fo the sip authorization.

Fix - do not subscribe for not in contactlist contacts and for terminated subscriptions.
Remove warning for not found AAAA and A records, warn when both are not found.
Change some config properties for autoaway.
cusax-fix
Damian Minkov 15 years ago
parent 16ce6691ab
commit 04238adfb0

@ -90,6 +90,15 @@ public class ContactSipImpl
*/
private final Address sipAddress;
/**
* Current subscription state of the contact.
* One of:
* SubscriptionStateHeader.PENDING,
* SubscriptionStateHeader.ACTIVE,
* SubscriptionStateHeader.TERMINATED.
*/
private String subscriptionState;
/**
* Creates an instance of a meta contact with the specified string used
* as a name and identifier.
@ -533,4 +542,27 @@ public String getStatusMessage()
{
return null;
}
/**
* Current subscription state of the contact.
* One of:
* SubscriptionStateHeader.PENDING,
* SubscriptionStateHeader.ACTIVE,
* SubscriptionStateHeader.TERMINATED.
*
* @return current subscription state.
*/
public String getSubscriptionState()
{
return subscriptionState;
}
/**
* Change current subscription state.
* @param subscriptionState the new state.
*/
public void setSubscriptionState(String subscriptionState)
{
this.subscriptionState = subscriptionState;
}
}

@ -702,8 +702,8 @@ public boolean processRequest(RequestEvent requestEvent)
logger.debug("received a message from an unknown contact: "
+ fromHeader.getAddress().getURI().toString());
//create the volatile contact
from = opSetPersPresence
.createVolatileContact(fromHeader.getAddress());
from = opSetPersPresence.createVolatileContact(
fromHeader.getAddress().getURI().toString());
}
// answer ok

@ -130,13 +130,22 @@ public class OperationSetPresenceSipImpl
private static final String TUPLE_ID = "t" + (long)(Math.random() * 10000);
private static final String PERSON_ID = "p" + (long)(Math.random() * 10000);
// XML documents types
/**
* XML documents types.
* The notify body content as said in rfc3856.
*/
private static final String PIDF_XML = "pidf+xml";
/**
* XML documents types.
* The notify body content as said in rfc3857.
*/
private static final String WATCHERINFO_XML = "watcherinfo+xml";
// pidf elements and attributes
private static final String PRESENCE_ELEMENT= "presence";
private static final String NS_ELEMENT = "xmlns";
private static final String NS_VALUE = "urn:ietf:params:xml:ns:pidf";
private static final String PIDF_NS_VALUE = "urn:ietf:params:xml:ns:pidf";
private static final String ENTITY_ATTRIBUTE= "entity";
private static final String TUPLE_ELEMENT = "tuple";
private static final String ID_ATTRIBUTE = "id";
@ -171,6 +180,16 @@ public class OperationSetPresenceSipImpl
// namespace wildcard
private static final String ANY_NS = "*";
private static final String WATCHERINFO_NS_VALUE
= "urn:ietf:params:xml:ns:watcherinfo";
private static final String WATCHERINFO_ELEMENT= "watcherinfo";
private static final String STATE_ATTRIBUTE = "state";
private static final String VERSION_ATTRIBUTE = "version";
private static final String WATCHERLIST_ELEMENT= "watcher-list";
private static final String RESOURCE_ATTRIBUTE = "resource";
private static final String PACKAGE_ATTRIBUTE = "package";
private static final String WATCHER_ELEMENT= "watcher";
/**
* The <code>EventPackageNotifier</code> which provides the ability of this
* instance to act as a notifier for the presence event package.
@ -183,6 +202,51 @@ public class OperationSetPresenceSipImpl
*/
private final EventPackageSubscriber subscriber;
/**
* The <code>EventPackageSubscriber</code> which provides the ability of
* this instance to act as a subscriber for the presence.winfo event package.
*/
private final EventPackageSubscriber watcherInfoSubscriber;
/**
* The authorization handler, asking client for authentication.
*/
private AuthorizationHandler authorizationHandler = null;
/**
* Watcher status from the watchers info list.
*/
private enum WatcherStatus
{
PENDING("pending"),
ACTIVE("active"),
WAITING("waiting"),
TERMINATED("terminated");
/**
* The value.
*/
private String value;
/**
* Creates <>tt WatcherStatus</tt>
* @param v value.
*/
WatcherStatus(String v)
{
this.value = v;
}
/**
* Returns the string representation of this status.
* @return
*/
public String getValue()
{
return this.value;
}
}
/**
* Creates an instance of this operation set keeping a reference to the
* specified parent <tt>provider</tt>.
@ -247,11 +311,21 @@ protected Subscription createSubscription(
fromAddress, eventId);
}
};
this.watcherInfoSubscriber
= new EventPackageSubscriber(
this.parentProvider,
"presence.winfo",
this.subscriptionDuration,
WATCHERINFO_XML,
this.timer,
REFRESH_MARGIN);
}
else
{
this.subscriber = null;
this.notifier = null;
this.watcherInfoSubscriber = null;
}
// Notifier part of the presence event package and PUBLISH
@ -1565,7 +1639,7 @@ public ContactSipImpl getLocalContactForDst(Address destination)
*/
public void setAuthorizationHandler(AuthorizationHandler handler)
{
// authorizations aren't supported by this implementation
this.authorizationHandler = handler;
}
/**
@ -1639,7 +1713,7 @@ public Contact createUnresolvedContact(String contactId,
* create.
* @return the newly created volatile contact.
*/
public ContactSipImpl createVolatileContact(Address contactAddress)
public ContactSipImpl createVolatileContact(String contactAddress)
{
try
{
@ -1654,7 +1728,7 @@ public ContactSipImpl createVolatileContact(Address contactAddress)
.createGroup(rootGroup, "NotInContactList", false);
}
return ssContactList.createContact(volatileGroup,
contactAddress.getURI().toString(), false);
contactAddress, false);
}
catch (OperationFailedException ex)
{
@ -1874,7 +1948,7 @@ public byte[] getPidfPresenceStatus(ContactSipImpl contact)
// <presence>
Element presence = doc.createElement(PRESENCE_ELEMENT);
presence.setAttribute(NS_ELEMENT, NS_VALUE);
presence.setAttribute(NS_ELEMENT, PIDF_NS_VALUE);
presence.setAttribute(RPID_NS_ELEMENT, RPID_NS_VALUE);
presence.setAttribute(DM_NS_ELEMENT, DM_NS_VALUE);
presence.setAttribute(ENTITY_ATTRIBUTE, contactUri);
@ -1985,7 +2059,7 @@ public void setPidfPresenceStatus(String presenceDoc)
logger.debug("parsing:\n" + presenceDoc);
// <presence>
NodeList presList = doc.getElementsByTagNameNS(NS_VALUE,
NodeList presList = doc.getElementsByTagNameNS(PIDF_NS_VALUE,
PRESENCE_ELEMENT);
if (presList.getLength() == 0)
@ -2405,6 +2479,178 @@ else if (getTextContent(basic).equalsIgnoreCase(
}
}
/**
* Parses watchers info document rfc3858.
* @param watcherInfoDoc the doc.
* @param subscriber the subscriber which receives lists.
*/
public void setWatcherInfoStatus(
WatcherInfoSubscriberSubscription subscriber,
String watcherInfoDoc)
{
if(this.authorizationHandler == null)
{
logger.warn("AuthorizationHandler missing!");
return;
}
Document doc = convertDocument(watcherInfoDoc);
if (doc == null)
return;
if (logger.isDebugEnabled())
logger.debug("parsing:\n" + watcherInfoDoc);
// <watcherinfo>
NodeList watchList = doc.getElementsByTagNameNS(
WATCHERINFO_NS_VALUE, WATCHERINFO_ELEMENT);
if (watchList.getLength() == 0)
{
watchList = doc.getElementsByTagNameNS(
ANY_NS, WATCHERINFO_ELEMENT);
if (watchList.getLength() == 0)
{
logger.error("no watcherinfo element in this document");
return;
}
}
if (watchList.getLength() > 1)
{
logger.warn("more than one watcherinfo element in this document");
}
Node watcherInfoNode = watchList.item(0);
if (watcherInfoNode.getNodeType() != Node.ELEMENT_NODE)
{
logger.error("the watcherinfo node is not an element");
return;
}
Element watcherInfo = (Element)watcherInfoNode;
// we don't take in account whether the state is full or partial.
if(logger.isDebugEnabled())
logger.debug("Watcherinfo is with state: "
+ watcherInfo.getAttribute(STATE_ATTRIBUTE));
int currentVersion = -1;
try
{
currentVersion =
Integer.parseInt(watcherInfo.getAttribute(VERSION_ATTRIBUTE));
}
catch(Throwable t)
{
logger.error("Cannot parse version!", t);
}
if(currentVersion != -1 && currentVersion <= subscriber.version)
{
logger.warn("Document version is old, ignore it.");
return;
}
else
subscriber.version = currentVersion;
// we need watcher list only for our resource
Element wlist = XMLUtils.locateElement(
watcherInfo, WATCHERLIST_ELEMENT, RESOURCE_ATTRIBUTE,
parentProvider.getRegistrarConnection()
.getAddressOfRecord().getURI().toString());
if(wlist == null ||
!wlist.getAttribute(PACKAGE_ATTRIBUTE).equals(PRESENCE_ELEMENT))
{
logger.error("Watcher list for us is missing in this document!");
return;
}
NodeList watcherList = wlist.getElementsByTagNameNS(ANY_NS,
WATCHER_ELEMENT);
for(int i = 0; i < watcherList.getLength(); i++)
{
Node watcherNode = watcherList.item(i);
if (watcherNode.getNodeType() != Node.ELEMENT_NODE)
{
logger.error("the watcher node is not an element");
return;
}
Element watcher = (Element)watcherNode;
String status = watcher.getAttribute(STATUS_ELEMENT);
String contactID = getTextContent(watcher);
//String event - subscribe, approved, deactivated, probation,
//rejected, timeout, giveup, noresource
if(status == null || contactID == null)
{
logger.warn("Status or contactID missing for watcher!");
continue;
}
if(status.equals("waiting") || status.equals("pending"))
{
ContactSipImpl contact = resolveContactID(contactID);
if(contact != null)
{
logger.warn("We are not supposed to have this contact in our " +
"list or its just rerequest of authorization!");
}
else
{
contact = createVolatileContact(contactID);
}
AuthorizationRequest req = new AuthorizationRequest();
AuthorizationResponse response = authorizationHandler
.processAuthorisationRequest(req, contact);
if(response.getResponseCode() == AuthorizationResponse.ACCEPT)
{
try
{
if(ssContactList.addContactToWhiteList(contact))
ssContactList.updatePresRules();
}
catch(XCapException ex)
{
logger.error("Cannot save presence rules!", ex);
}
}
else if(response.getResponseCode()
== AuthorizationResponse.REJECT)
{
try
{
if(ssContactList.addContactToBlockList(contact))
ssContactList.updatePresRules();
}
catch(XCapException ex)
{
logger.error("Cannot save presence rules!", ex);
}
}
else if(response.getResponseCode()
== AuthorizationResponse.IGNORE)
{
try
{
if(ssContactList.addContactToPoliteBlockList(contact))
ssContactList.updatePresRules();
}
catch(XCapException ex)
{
logger.error("Cannot save presence rules!", ex);
}
}
}
}
}
/**
* Checks whether to URIs are equal with safe null check.
* @param uri1 to be compared.
@ -2498,7 +2744,7 @@ private NodeList getPidfChilds(Element element, String childName)
{
NodeList res;
res = element.getElementsByTagNameNS(NS_VALUE, childName);
res = element.getElementsByTagNameNS(PIDF_NS_VALUE, childName);
if (res.getLength() == 0)
{
@ -2605,7 +2851,9 @@ else if (curPriority < priority)
*/
public void forcePollContact(ContactSipImpl contact)
{
if (this.presenceEnabled == false || !contact.isResolvable())
if (this.presenceEnabled == false
|| !contact.isResolvable()
|| !contact.isPersistent())
return;
// Attempt to subscribe.
@ -2860,6 +3108,22 @@ else if (evt.getNewState().equals(RegistrationState.REGISTERED))
// start polling the offline contacts
timer.schedule(pollingTask, pollingTaskPeriod, pollingTaskPeriod);
if(this.useDistantPA)
{
try
{
watcherInfoSubscriber.subscribe(
new WatcherInfoSubscriberSubscription(
parentProvider.getRegistrarConnection()
.getAddressOfRecord()));
}
catch (OperationFailedException ex)
{
logger.error("Failed to create and send the subcription " +
"for watcher info.", ex);
}
}
}
else if (evt.getNewState().equals(RegistrationState.CONNECTION_FAILED))
{
@ -3109,6 +3373,37 @@ protected void processActiveRequest(
{
if (rawContent != null)
setPidfPresenceStatus(new String(rawContent));
SubscriptionStateHeader stateHeader =
(SubscriptionStateHeader)requestEvent.getRequest()
.getHeader(SubscriptionStateHeader.NAME);
if(stateHeader != null)
{
if(SubscriptionStateHeader.PENDING
.equals(stateHeader.getState()))
{
contact.setSubscriptionState(
SubscriptionStateHeader.PENDING);
}
else if(SubscriptionStateHeader.ACTIVE
.equals(stateHeader.getState()))
{
// if contact was in pending state
// our authorization request was accepted
if(SubscriptionStateHeader.PENDING
.equals(contact.getSubscriptionState())
&& authorizationHandler != null)
{
authorizationHandler.processAuthorizationResponse(
new AuthorizationResponse(
AuthorizationResponse.ACCEPT, ""),
contact);
}
contact.setSubscriptionState(
SubscriptionStateHeader.ACTIVE);
}
}
}
/*
@ -3199,6 +3494,143 @@ protected void processTerminatedRequest(
// to the contact
if (SubscriptionStateHeader.DEACTIVATED.equals(reasonCode))
forcePollContact(contact);
SubscriptionStateHeader stateHeader =
(SubscriptionStateHeader)requestEvent.getRequest()
.getHeader(SubscriptionStateHeader.NAME);
if(stateHeader != null
&& SubscriptionStateHeader.TERMINATED
.equals(stateHeader.getState()))
{
if(SubscriptionStateHeader.REJECTED
.equals(stateHeader.getReasonCode()))
{
if(SubscriptionStateHeader.PENDING
.equals(contact.getSubscriptionState()))
{
authorizationHandler.processAuthorizationResponse(
new AuthorizationResponse(
AuthorizationResponse.REJECT, ""),
contact);
}
// as this contact is rejected we mark it as not resolvable
// so we won't subscribe again (in offline poll task)
contact.setResolvable(false);
}
contact.setSubscriptionState(
SubscriptionStateHeader.TERMINATED);
}
}
}
/**
* Represents a subscription to the presence.winfo event package.
*
* @author Damian Minkov
*/
private class WatcherInfoSubscriberSubscription
extends EventPackageSubscriber.Subscription
{
private int version = -1;
/**
* Initializes a new <tt>Subscription</tt> instance with a specific
* subscription <tt>Address</tt>/Request URI and an id tag of the
* associated Event headers of value <tt>null</tt>.
*
* @param toAddress the subscription <tt>Address</tt>/Request URI which
* is to be the target of the SUBSCRIBE requests associated with
* the new instance
*/
public WatcherInfoSubscriberSubscription(Address toAddress)
{
super(toAddress);
}
/**
* Notifies this <tt>Subscription</tt> that an active NOTIFY
* <tt>Request</tt> has been received and it may process the
* specified raw content carried in it.
*
* @param requestEvent the <tt>RequestEvent</tt> carrying the full
* details of the received NOTIFY <tt>Request</tt> including the raw
* content which may be processed by this <tt>Subscription</tt>
* @param rawContent an array of bytes which represents the raw
* content carried in the body of the received NOTIFY <tt>Request</tt>
* and extracted from the specified <tt>RequestEvent</tt>
* for the convenience of the implementers
*/
@Override
protected void processActiveRequest(
RequestEvent requestEvent, byte[] rawContent)
{
if (rawContent != null)
setWatcherInfoStatus(this, new String(rawContent));
}
/**
* Notifies this <tt>Subscription</tt> that a <tt>Response</tt>
* to a previous SUBSCRIBE <tt>Request</tt> has been received with a
* status code in the failure range and it may process the status code
* carried in it.
*
* @param responseEvent the <tt>ResponseEvent</tt> carrying the
* full details of the received <tt>Response</tt> including the status
* code which may be processed by this <tt>Subscription</tt>
* @param statusCode the status code carried in the <tt>Response</tt>
* and extracted from the specified <tt>ResponseEvent</tt>
* for the convenience of the implementers
*/
@Override
protected void processFailureResponse(
ResponseEvent responseEvent, int statusCode)
{
logger.error("Cannot subscripe to presence watcher info!");
}
/**
* Notifies this <tt>Subscription</tt> that a <tt>Response</tt>
* to a previous SUBSCRIBE <tt>Request</tt> has been received with a
* status code in the success range and it may process the status code
* carried in it.
*
* @param responseEvent the <tt>ResponseEvent</tt> carrying the
* full details of the received <tt>Response</tt> including the status
* code which may be processed by this <tt>Subscription</tt>
* @param statusCode the status code carried in the <tt>Response</tt>
* and extracted from the specified <tt>ResponseEvent</tt>
* for the convenience of the implementers
*/
@Override
protected void processSuccessResponse(
ResponseEvent responseEvent, int statusCode)
{
if(logger.isDebugEnabled())
logger.debug("Subscriped to presence watcher info! status:"
+ statusCode);
}
/**
* Notifies this <tt>Subscription</tt> that a terminating NOTIFY
* <tt>Request</tt> has been received and it may process the reason
* code carried in it.
*
* @param requestEvent the <tt>RequestEvent</tt> carrying the
* full details of the received NOTIFY <tt>Request</tt> including the
* reason code which may be processed by this <tt>Subscription</tt>
* @param reasonCode the code of the reason for the termination carried
* in the NOTIFY <tt>Request</tt> and extracted from the specified
* <tt>RequestEvent</tt> for the convenience of the implementers.
*/
@Override
protected void processTerminatedRequest(
RequestEvent requestEvent, String reasonCode)
{
logger.error("Subscription to presence watcher info terminated!");
}
}
}

@ -206,7 +206,7 @@ public boolean processMessage(RequestEvent requestEvent)
{
//create the volatile contact
from = opSetPersPresence.createVolatileContact(
fromHeader.getAddress());
fromHeader.getAddress().getURI().toString());
}
// parse content

@ -2803,6 +2803,9 @@ private void resolveAddresses(
if(addressObj6 != null && !resultAddresses.contains(addressObj6))
resultAddresses.add(addressObj6);
}
if(addressObj4 == null && addressObj6 == null)
logger.warn("No AAAA and A record found for " + address);
}
/**

@ -36,12 +36,23 @@ public class ServerStoredContactListSipImpl
/**
* Root group name.
*/
private static String ROOT_GROUP_NAME = "RootGroup";
private final static String ROOT_GROUP_NAME = "RootGroup";
/**
* "White" rule identifier.
* Default "White" rule identifier.
*/
private static String WHITE_RULE_ID = "sip_communicator";
private final static String DEFAULT_WHITE_RULE_ID = "presence_allow";
/**
* Default "Block" rule identifier.
*/
private final static String DEFAULT_BLOCK_RULE_ID = "presence_block";
/**
* Default "Polite Block" rule identifier.
*/
private final static String DEFAULT_POLITE_BLOCK_RULE_ID
= "presence_polite_block";
/**
* The provider that is on top of us.
@ -52,8 +63,7 @@ public class ServerStoredContactListSipImpl
* The operation set that created us and that we could use when dispatching
* subscription events.
*/
private final AbstractOperationSetPersistentPresence<ProtocolProviderServiceSipImpl>
parentOperationSet;
private final OperationSetPresenceSipImpl parentOperationSet;
/**
* Listeners that would receive event notifications for changes in group
@ -71,11 +81,6 @@ public class ServerStoredContactListSipImpl
*/
private RulesetType presRules;
/**
* Current "white" rule.
*/
private RuleType whiteRule;
/**
* Creates a ServerStoredContactList wrapper for the specified BuddyList.
*
@ -85,8 +90,7 @@ public class ServerStoredContactListSipImpl
*/
ServerStoredContactListSipImpl(
ProtocolProviderServiceSipImpl sipProvider,
AbstractOperationSetPersistentPresence<ProtocolProviderServiceSipImpl>
parentOperationSet)
OperationSetPresenceSipImpl parentOperationSet)
{
this.sipProvider = sipProvider;
this.parentOperationSet = parentOperationSet;
@ -226,7 +230,10 @@ public synchronized ContactSipImpl createUnresolvedContact(
contactId),
ex);
}
logger.trace("createUnresolvedContact " + contactId);
if(logger.isTraceEnabled())
logger.trace("createUnresolvedContact " + contactId);
ContactSipImpl newUnresolvedContact = new ContactSipImpl(contactAddress,
sipProvider);
parentGroup.addContact(newUnresolvedContact);
@ -285,7 +292,21 @@ synchronized public ContactSipImpl createContact(
" is not a valid string.", ex);
}
ContactSipImpl newContact = new ContactSipImpl(contactAddress,
ContactSipImpl newContact = parentOperationSet.resolveContactID(
contactAddress.getURI().toString());
if(newContact != null && !newContact.isPersistent() &&
!newContact.getParentContactGroup().isPersistent())
{
// this is a contact from not in contact list group
// we must remove it
ContactGroupSipImpl oldParentGroup =
(ContactGroupSipImpl)newContact.getParentContactGroup();
oldParentGroup.removeContact(newContact);
fireContactRemoved(oldParentGroup, newContact);
}
newContact = new ContactSipImpl(contactAddress,
sipProvider);
newContact.setPersistent(persistent);
String name = ((SipURI) contactAddress.getURI()).getUser();
@ -311,19 +332,21 @@ synchronized public ContactSipImpl createContact(
xCapClient.isResourceListsSupported())
{
newContact.setXCapResolved(true);
}
// Update pres-rules if needed
if (!isContactExistsInWhiteRule(contactId))
{
// Update pres-rules
addContactToWhiteList(newContact);
try
{
updatePresRules();
// Update pres-rules if needed
if (!isContactInWhiteRule(contactId))
{
// Update pres-rules
if(addContactToWhiteList(newContact))
updatePresRules();
}
}
catch (XCapException e)
{
logger.error("Error while creating XCAP contact", e);
logger.error("Cannot add contact to white list while " +
"creating it", e);
}
}
}
@ -347,12 +370,34 @@ synchronized public void removeContact(ContactSipImpl contact)
throw new IllegalArgumentException(
"Removing contact cannot be null");
}
logger.trace("removeContact " + contact.getUri());
if(logger.isTraceEnabled())
logger.trace("removeContact " + contact.getUri());
ContactGroupSipImpl parentGroup =
(ContactGroupSipImpl) contact.getParentContactGroup();
parentGroup.removeContact(contact);
if (contact.isPersistent())
{
try
{
// when removing contact add it to polite block list, cause
// as soon as we remove it we will receive notification
// for authorization (watcher info - pending)
boolean updateRules = removeContactFromWhiteList(contact);
updateRules = removeContactFromBlockList(contact)
|| updateRules;
updateRules = removeContactFromPoliteBlockList(contact)
|| updateRules;
if(updateRules)
updatePresRules();
}
catch (XCapException e)
{
logger.error("Error while removing XCAP contact", e);
}
// Update resoure-lists
try
{
@ -365,19 +410,6 @@ synchronized public void removeContact(ContactSipImpl contact)
"Error while removing XCAP contact",
OperationFailedException.NETWORK_FAILURE, e);
}
// Update pres-rules if contact doesn't exist
if (!isContactPersistent(contact.getUri()))
{
removeContactFromWhiteList(contact);
try
{
updatePresRules();
}
catch (XCapException e)
{
logger.error("Error while removing XCAP contact", e);
}
}
}
fireContactRemoved(parentGroup, contact);
}
@ -609,6 +641,19 @@ synchronized public void removeGroup(ContactGroupSipImpl group)
try
{
updateResourceLists();
Iterator<Contact> iter = group.contacts();
boolean updateRules = false;
while(iter.hasNext())
{
ContactSipImpl c = (ContactSipImpl)iter.next();
updateRules = removeContactFromWhiteList(c) || updateRules;
updateRules = removeContactFromBlockList(c) || updateRules;
updateRules = removeContactFromPoliteBlockList(c)
|| updateRules;
}
if(updateRules)
updatePresRules();
}
catch (XCapException e)
{
@ -833,34 +878,33 @@ synchronized public void init()
// Process pres-rules
if (xCapClient.isPresRulesSupported())
{
// Get pres-rules and analyze it
presRules = xCapClient.getPresRules();
for (RuleType rule : presRules.getRules())
{
if (rule.getId().equals(WHITE_RULE_ID))
{
whiteRule = rule;
break;
}
}
// Get white pres-rules and analyze it
RuleType whiteRule = getRule(SubHandlingType.Allow);
boolean updateRules = false;
// If "white" rule is available refresh it
if (whiteRule != null)
if (whiteRule == null)
{
presRules.getRules().remove(whiteRule);
whiteRule = createWhiteRule();
presRules.getRules().add(whiteRule);
}
whiteRule = createWhiteRule();
presRules.getRules().add(whiteRule);
// Add contacts into the "white" rule
// Add contacts into the "white" rule if missing
List<ContactSipImpl> uniqueContacts =
getUniqueContacts(rootGroup);
for (ContactSipImpl contact : uniqueContacts)
{
if(contact.isPersistent())
if(contact.isPersistent()
&& !isContactInRule(whiteRule, contact.getUri()))
{
addContactToWhiteList(contact);
addContactToRule(whiteRule, contact);
updateRules = true;
}
}
updatePresRules();
if(updateRules)
updatePresRules();
}
}
catch (XCapException e)
@ -884,7 +928,6 @@ synchronized public void destroy()
contact.setResolved(false);
}
presRules = null;
whiteRule = null;
}
/**
@ -895,7 +938,7 @@ synchronized public void destroy()
private static RuleType createWhiteRule()
{
RuleType whiteList = new RuleType();
whiteList.setId(WHITE_RULE_ID);
whiteList.setId(DEFAULT_WHITE_RULE_ID);
ConditionsType conditions = new ConditionsType();
whiteList.setConditions(conditions);
@ -904,73 +947,119 @@ private static RuleType createWhiteRule()
actions.setSubHandling(SubHandlingType.Allow);
whiteList.setActions(actions);
TransfomationsType transfomations = new TransfomationsType();
TransformationsType transformations = new TransformationsType();
ProvideServicePermissionType servicePermission =
new ProvideServicePermissionType();
servicePermission.setAllServices(
new ProvideServicePermissionType.AllServicesType());
transfomations.setServicePermission(servicePermission);
transformations.setServicePermission(servicePermission);
ProvidePersonPermissionType personPermission =
new ProvidePersonPermissionType();
personPermission.setAllPersons(
new ProvidePersonPermissionType.AllPersonsType());
transfomations.setPersonPermission(personPermission);
transformations.setPersonPermission(personPermission);
ProvideDevicePermissionType devicePermission =
new ProvideDevicePermissionType();
devicePermission.setAllDevices(
new ProvideDevicePermissionType.AllDevicesType());
transfomations.setDevicePermission(devicePermission);
whiteList.setTransformations(transfomations);
transformations.setDevicePermission(devicePermission);
whiteList.setTransformations(transformations);
return whiteList;
}
/**
* Adds contact to the "white" rule.
* Creates "block" rule.
*
* @param contact the contact to add.
* @return created rule.
*/
private void addContactToWhiteList(ContactSipImpl contact)
private static RuleType createBlockRule()
{
XCapClient xCapClient = sipProvider.getXCapClient();
if (!xCapClient.isConnected() || !xCapClient.isPresRulesSupported())
{
return;
}
IdentityType identity;
if (whiteRule.getConditions().getIdentities().size() == 0)
RuleType blackList = new RuleType();
blackList.setId(DEFAULT_BLOCK_RULE_ID);
ConditionsType conditions = new ConditionsType();
blackList.setConditions(conditions);
ActionsType actions = new ActionsType();
actions.setSubHandling(SubHandlingType.Block);
blackList.setActions(actions);
TransformationsType transformations = new TransformationsType();
blackList.setTransformations(transformations);
return blackList;
}
/**
* Creates "polite block" rule.
*
* @return created rule.
*/
private static RuleType createPoliteBlockRule()
{
RuleType blackList = new RuleType();
blackList.setId(DEFAULT_POLITE_BLOCK_RULE_ID);
ConditionsType conditions = new ConditionsType();
blackList.setConditions(conditions);
ActionsType actions = new ActionsType();
actions.setSubHandling(SubHandlingType.PoliteBlock);
blackList.setActions(actions);
TransformationsType transformations = new TransformationsType();
blackList.setTransformations(transformations);
return blackList;
}
/**
* Finds the rule with the given action type.
* @param type the action type to search for.
* @return the rule if any or null.
*/
private RuleType getRule(SubHandlingType type)
throws XCapException
{
if(presRules == null)
{
identity = new IdentityType();
whiteRule.getConditions().getIdentities().add(identity);
XCapClient xCapClient = sipProvider.getXCapClient();
if (!xCapClient.isConnected() ||
!xCapClient.isResourceListsSupported())
{
return null;
}
presRules = xCapClient.getPresRules();
}
else
for (RuleType rule : presRules.getRules())
{
identity = whiteRule.getConditions().getIdentities().get(0);
if (rule.getActions().getSubHandling().equals(type))
{
return rule;
}
}
OneType one = new OneType();
one.setId(contact.getUri());
identity.getOneList().add(one);
return null;
}
/**
* Indicates whether or not contact is exists in the "white" rule.
* Checks whether the contact in the specified rule.
*
* @param contactUri the contact uri.
* @return true if contact is exists, false if not.
* @param rule the rule.
* @param contactUri the contact uri to check.
* @return is the contact in the rule.
*/
private boolean isContactExistsInWhiteRule(String contactUri)
private static boolean isContactInRule(RuleType rule, String contactUri)
{
XCapClient xCapClient = sipProvider.getXCapClient();
if (!xCapClient.isConnected() || !xCapClient.isPresRulesSupported())
{
return false;
}
IdentityType identity;
if (whiteRule.getConditions().getIdentities().size() == 0)
if (rule.getConditions().getIdentities().size() == 0)
{
return false;
}
identity = whiteRule.getConditions().getIdentities().get(0);
identity = rule.getConditions().getIdentities().get(0);
for (OneType one : identity.getOneList())
{
if (one.getId().equals(contactUri))
@ -982,19 +1071,49 @@ private boolean isContactExistsInWhiteRule(String contactUri)
}
/**
* Removes contact from the "white" rule.
* Adds contact to the rule.
*
* @param contact the contact to remove.
* @param contact the contact to add.
* @param rule the rule to use to add contact to.
* @return true if present rules were updated, false otherwise.
*/
private void removeContactFromWhiteList(ContactSipImpl contact)
private static boolean addContactToRule(RuleType rule, ContactSipImpl contact)
{
XCapClient xCapClient = sipProvider.getXCapClient();
if (!xCapClient.isConnected() || !xCapClient.isPresRulesSupported())
if(isContactInRule(rule, contact.getUri()))
return false;
IdentityType identity;
if (rule.getConditions().getIdentities().size() == 0)
{
return;
identity = new IdentityType();
rule.getConditions().getIdentities().add(identity);
}
else
{
identity = rule.getConditions().getIdentities().get(0);
}
OneType one = new OneType();
one.setId(contact.getUri());
identity.getOneList().add(one);
return true;
}
/**
* Removes contact from the rule.
*
* @param contact the contact to remove.
* @param rule the rule to use to remove contact from.
* @return true if present rules were updated, false otherwise.
*/
private static boolean removeContactFromRule(
RuleType rule, ContactSipImpl contact)
{
if(rule.getConditions().getIdentities().size() == 0)
return false;
IdentityType identity =
whiteRule.getConditions().getIdentities().get(0);
rule.getConditions().getIdentities().get(0);
OneType contactOne = null;
for (OneType one : identity.getOneList())
{
@ -1004,14 +1123,179 @@ private void removeContactFromWhiteList(ContactSipImpl contact)
break;
}
}
if (contactOne != null)
{
identity.getOneList().remove(contactOne);
}
if (identity.getOneList().size() == 0)
{
whiteRule.getConditions().getIdentities().remove(identity);
rule.getConditions().getIdentities().remove(identity);
rule.getConditions().getIdentities().remove(identity);
}
return true;
}
/**
* Adds contact to the "white" rule.
*
* @param contact the contact to add.
* @return true if present rules were updated, false otherwise.
*/
boolean addContactToWhiteList(ContactSipImpl contact)
throws XCapException
{
RuleType whiteRule = getRule(SubHandlingType.Allow);
RuleType blockRule = getRule(SubHandlingType.Block);
RuleType politeBlockRule = getRule(SubHandlingType.PoliteBlock);
if(whiteRule == null)
{
whiteRule = createWhiteRule();
presRules.getRules().add(whiteRule);
}
boolean updateRule =
addContactToRule(whiteRule, contact);
if(blockRule != null)
updateRule = removeContactFromRule(blockRule, contact)
|| updateRule;
if(politeBlockRule != null)
updateRule = removeContactFromRule(politeBlockRule, contact)
|| updateRule;
return updateRule;
}
/**
* Adds contact to the "block" rule.
*
* @param contact the contact to add.
*/
boolean addContactToBlockList(ContactSipImpl contact)
throws XCapException
{
RuleType whiteRule = getRule(SubHandlingType.Allow);
RuleType blockRule = getRule(SubHandlingType.Block);
RuleType politeBlockRule = getRule(SubHandlingType.PoliteBlock);
if(blockRule == null)
{
blockRule = createBlockRule();
presRules.getRules().add(blockRule);
}
boolean updateRule =
addContactToRule(blockRule, contact);
if(whiteRule != null)
updateRule = removeContactFromRule(whiteRule, contact)
|| updateRule;
if(politeBlockRule != null)
updateRule = removeContactFromRule(politeBlockRule, contact)
|| updateRule;
return updateRule;
}
/**
* Adds contact to the "polite block" rule.
*
* @param contact the contact to add.
*/
boolean addContactToPoliteBlockList(ContactSipImpl contact)
throws XCapException
{
RuleType whiteRule = getRule(SubHandlingType.Allow);
RuleType blockRule = getRule(SubHandlingType.Block);
RuleType politeBlockRule = getRule(SubHandlingType.PoliteBlock);
if(politeBlockRule == null)
{
politeBlockRule = createPoliteBlockRule();
presRules.getRules().add(politeBlockRule);
}
boolean updateRule =
addContactToRule(politeBlockRule, contact);
if(whiteRule != null)
updateRule = removeContactFromRule(whiteRule, contact)
|| updateRule;
if(blockRule != null)
updateRule = removeContactFromRule(blockRule, contact)
|| updateRule;
return updateRule;
}
/**
* Indicates whether or not contact is exists in the "white" rule.
*
* @param contactUri the contact uri.
* @return true if contact is exists, false if not.
*/
private boolean isContactInWhiteRule(String contactUri)
throws XCapException
{
RuleType whiteRule = getRule(SubHandlingType.Allow);
if(whiteRule == null)
return false;
return isContactInRule(whiteRule, contactUri);
}
/**
* Removes contact from the "white" rule.
*
* @param contact the contact to remove.
* @return true if present rules were updated, false otherwise.
*/
boolean removeContactFromWhiteList(ContactSipImpl contact)
throws XCapException
{
RuleType whiteRule = getRule(SubHandlingType.Allow);
if(whiteRule != null)
return removeContactFromRule(whiteRule, contact);
else
return false;
}
/**
* Removes contact from the "block" rule.
*
* @param contact the contact to remove.
* @return true if present rules were updated, false otherwise.
*/
boolean removeContactFromBlockList(ContactSipImpl contact)
throws XCapException
{
RuleType blockRule = getRule(SubHandlingType.Block);
if(blockRule != null)
return removeContactFromRule(blockRule, contact);
else
return false;
}
/**
* Removes contact from the "polite block" rule.
*
* @param contact the contact to remove.
* @return true if present rules were updated, false otherwise.
*/
boolean removeContactFromPoliteBlockList(ContactSipImpl contact)
throws XCapException
{
RuleType blockRule = getRule(SubHandlingType.PoliteBlock);
if(blockRule != null)
return removeContactFromRule(blockRule, contact);
else
return false;
}
/**
@ -1323,7 +1607,7 @@ synchronized private void updateResourceLists()
*
* @throws XCapException if there is some error during operation.
*/
synchronized private void updatePresRules()
synchronized void updatePresRules()
throws XCapException
{
XCapClient xCapClient = sipProvider.getXCapClient();

@ -33,7 +33,7 @@ public class RuleType
/**
* The transformations element.
*/
private TransfomationsType transformations;
private TransformationsType transformations;
/**
* Gets the value of the conditions property.
@ -80,7 +80,7 @@ public void setActions(ActionsType actions)
*
* @return the transformations property.
*/
public TransfomationsType getTransformations()
public TransformationsType getTransformations()
{
return transformations;
}
@ -90,7 +90,7 @@ public TransfomationsType getTransformations()
*
* @param transformations the uri to set.
*/
public void setTransformations(TransfomationsType transformations)
public void setTransformations(TransformationsType transformations)
{
this.transformations = transformations;
}

@ -18,7 +18,7 @@
*
* @author Grigorii Balutsel
*/
public class TransfomationsType
public class TransformationsType
{
/**
* The service-permissions element.

@ -150,11 +150,11 @@ public static Element elementFromActions(
* @return the transfomations object.
* @throws Exception if there is some error during parsing.
*/
public static TransfomationsType transformationsFromElement(
public static TransformationsType transformationsFromElement(
Element element)
throws Exception
{
TransfomationsType transfomations = new TransfomationsType();
TransformationsType transfomations = new TransformationsType();
if (!CommonPolicyParser.NAMESPACE
.equals(getNamespaceUri(element)) ||
!CommonPolicyParser.TRANSFORMATIONS_ELEMENT
@ -236,7 +236,7 @@ else if (PROVIDE_PERSONS_ELEMENT.equals(localName))
* @throws Exception if there is some error during creating.
*/
public static Element elementFromTransfomations(
Document document, TransfomationsType transformations)
Document document, TransformationsType transformations)
throws Exception
{
Element element = document.createElementNS(CommonPolicyParser.NAMESPACE,

@ -14,6 +14,8 @@
*/
public final class Preferences
{
public static final String ENABLE = "at.liwest.communicator.plugin.statusupdate.enable";
public static final String TIMER = "at.liwest.communicator.plugin.statusupdate.timer";
public static final String ENABLE =
"net.java.sip.communicator.plugin.statusupdate.enable";
public static final String TIMER =
"net.java.sip.communicator.plugin.statusupdate.timer";
}

@ -821,7 +821,7 @@ public static InetSocketAddress getARecord(String domain, int port)
}
else
{
logger.warn("No A record found for: " + domain);
//No A record found
return null;
}
}
@ -858,7 +858,7 @@ public static InetSocketAddress getAAAARecord(String domain, int port)
}
else
{
logger.warn("No AAAA record found for: " + domain);
//"No AAAA record found
return null;
}
}

@ -296,7 +296,7 @@ private static void validatePresRules(RulesetType ruleset)
"The actions we set is not read properly",
actions.getAny().size() == 0);
// transformations
TransfomationsType transfomations = rule.getTransformations();
TransformationsType transfomations = rule.getTransformations();
assertNull(
"The transfomations we set is not read properly",
transfomations.getDevicePermission());

Loading…
Cancel
Save