001/**
002 *
003 * Copyright the original author or authors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.privacy.packet;
018
019/**
020 * A privacy item acts a rule that when matched defines if a packet should be blocked or not.
021 *
022 * Privacy Items can handle different kind of blocking communications based on JID, group,
023 * subscription type or globally by:<ul>
024 * <li>Allowing or blocking messages.
025 * <li>Allowing or blocking inbound presence notifications.
026 * <li>Allowing or blocking outbound presence notifications.
027 * <li>Allowing or blocking IQ stanzas.
028 * <li>Allowing or blocking all communications.
029 * </ul>
030 * @author Francisco Vives
031 */
032public class PrivacyItem {
033    /**
034     * Value for subscription type rules.
035     */
036    public static final String SUBSCRIPTION_BOTH = "both";
037    public static final String SUBSCRIPTION_TO = "to";
038    public static final String SUBSCRIPTION_FROM = "from";
039    public static final String SUBSCRIPTION_NONE = "none";
040
041    /** allow is the action associated with the item, it can allow or deny the communication. */
042    private final boolean allow;
043    /** order is a non-negative integer that is unique among all items in the list. */
044    private final int order;
045
046    /**
047     * Type defines if the rule is based on JIDs, roster groups or presence subscription types.
048     * Available values are: [jid|group|subscription]
049     */
050    private final Type type;
051
052    /**
053     * The value hold the element identifier to apply the action. If the type is "jid", then the
054     * 'value' attribute MUST contain a valid Jabber ID. If the type is "group", then the
055     * 'value' attribute SHOULD contain the name of a group in the user's roster. If the type is
056     * "subscription", then the 'value' attribute MUST be one of "both", "to", "from", or
057     * "none".
058     */
059    private final String value;
060
061    /** blocks incoming IQ stanzas. */
062    private boolean filterIQ = false;
063    /** filterMessage blocks incoming message stanzas. */
064    private boolean filterMessage = false;
065    /** blocks incoming presence notifications. */
066    private boolean filterPresenceIn = false;
067    /** blocks outgoing presence notifications. */
068    private boolean filterPresenceOut = false;
069
070    /**
071     * Creates a new fall-through privacy item.
072     *
073     * This is usually the last item in a privacy list and has no 'type' attribute.
074     *
075     * @param allow true if this is an allow item
076     * @param order the order of this privacy item
077     */
078    public PrivacyItem(boolean allow, int order) {
079        this(null, null, allow, order);
080    }
081
082    /**
083     * Creates a new privacy item.
084     *
085     * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
086     * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
087     * in the user's roster.
088     * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
089     * "from", or "none".
090     *
091     * @param type the type.
092     * @param value the value of the privacy item
093     * @param allow true if this is an allow item
094     * @param order the order of this privacy item
095     */
096    public PrivacyItem(Type type, String value, boolean allow, int order) {
097        this.type = type;
098        this.value = value;
099        this.allow = allow;
100        this.order = order;
101    }
102
103    /**
104     * Returns the action associated with the item, it MUST be filled and will allow or deny
105     * the communication.
106     *
107     * @return the allow communication status.
108     */
109    public boolean isAllow() {
110                return allow;
111        }
112
113    /**
114     * Returns whether the receiver allow or deny incoming IQ stanzas or not.
115     *
116     * @return the iq filtering status.
117     */
118    public boolean isFilterIQ() {
119                return filterIQ;
120        }
121
122    /**
123     * Sets whether the receiver allows or denies incoming IQ stanzas or not.
124     *
125     * @param filterIQ indicates if the receiver allows or denies incoming IQ stanzas.
126     */
127    public void setFilterIQ(boolean filterIQ) {
128                this.filterIQ = filterIQ;
129        }
130
131    /**
132     * Returns whether the receiver allows or denies incoming messages or not.
133     *
134     * @return the message filtering status.
135     */
136    public boolean isFilterMessage() {
137                return filterMessage;
138        }
139
140    /**
141     * Sets wheather the receiver allows or denies incoming messages or not.
142     *
143     * @param filterMessage indicates if the receiver allows or denies incoming messages or not.
144     */
145    public void setFilterMessage(boolean filterMessage) {
146                this.filterMessage = filterMessage;
147        }
148
149    /**
150     * Returns whether the receiver allows or denies incoming presence or not.
151     *
152     * @return the iq filtering incoming presence status.
153     */
154    public boolean isFilterPresenceIn() {
155                return filterPresenceIn;
156        }
157
158    /**
159     * Sets whether the receiver allows or denies incoming presence or not.
160     *
161     * @param filterPresenceIn indicates if the receiver allows or denies filtering incoming presence.
162     */
163    public void setFilterPresenceIn(boolean filterPresenceIn) {
164                this.filterPresenceIn = filterPresenceIn;
165        }
166
167    /**
168     * Returns whether the receiver allows or denies incoming presence or not.
169     *
170     * @return the iq filtering incoming presence status.
171     */
172    public boolean isFilterPresenceOut() {
173                return filterPresenceOut;
174        }
175
176    /**
177     * Sets whether the receiver allows or denies outgoing presence or not.
178     *
179     * @param filterPresenceOut indicates if the receiver allows or denies filtering outgoing presence
180     */
181    public void setFilterPresenceOut(boolean filterPresenceOut) {
182                this.filterPresenceOut = filterPresenceOut;
183        }
184
185    /**
186     * Returns the order where the receiver is processed. List items are processed in
187     * ascending order.
188     *
189     * The order MUST be filled and its value MUST be a non-negative integer
190     * that is unique among all items in the list.
191     *
192     * @return the order number.
193     */
194    public int getOrder() {
195                return order;
196        }
197
198    /**
199     * Returns the type hold the kind of communication it will allow or block.
200     * It MUST be filled with one of these values: jid, group or subscription.
201     *
202     * @return the type of communication it represent.
203     */
204    public Type getType() {
205        return type;
206        }
207
208    /**
209     * Returns the element identifier to apply the action.
210     *
211     * If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
212     * If the type is "group", then the 'value' attribute SHOULD contain the name of a group
213     * in the user's roster.
214     * If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
215     * "from", or "none".
216     *
217     * @return the identifier to apply the action.
218     */
219    public String getValue() {
220        return value;
221        }
222
223    /**
224     * Returns whether the receiver allows or denies every kind of communication.
225     *
226     * When filterIQ, filterMessage, filterPresenceIn and filterPresenceOut are not set
227     * the receiver will block all communications.
228     *
229     * @return the all communications status.
230     */
231    public boolean isFilterEverything() {
232                return !(this.isFilterIQ() || this.isFilterMessage() || this.isFilterPresenceIn()
233                                || this.isFilterPresenceOut());
234        }
235
236        /**
237         * Answer an xml representation of the receiver according to the RFC 3921.
238         *
239         * @return the text xml representation.
240     */
241    public String toXML() {
242        StringBuilder buf = new StringBuilder();
243        buf.append("<item");
244        if (this.isAllow()) {
245                buf.append(" action=\"allow\"");
246        } else {
247                buf.append(" action=\"deny\"");
248        }
249        buf.append(" order=\"").append(getOrder()).append("\"");
250        if (getType() != null) {
251            buf.append(" type=\"").append(getType()).append("\"");
252        }
253        if (getValue() != null) {
254            buf.append(" value=\"").append(getValue()).append("\"");
255        }
256        if (isFilterEverything()) {
257                buf.append("/>");
258        } else {
259                buf.append(">");
260                if (this.isFilterIQ()) {
261                buf.append("<iq/>");
262            }
263                if (this.isFilterMessage()) {
264                buf.append("<message/>");
265            }
266                if (this.isFilterPresenceIn()) {
267                buf.append("<presence-in/>");
268            }
269                if (this.isFilterPresenceOut()) {
270                buf.append("<presence-out/>");
271            }
272                buf.append("</item>");
273        }
274        return buf.toString();
275    }
276
277    /**
278     * Type defines if the rule is based on JIDs, roster groups or presence subscription types.
279     */
280    public static enum Type {
281        /**
282         * JID being analyzed should belong to a roster group of the list's owner.
283         */
284        group,
285        /**
286         * JID being analyzed should have a resource match, domain match or bare JID match.
287         */
288        jid,
289        /**
290         * JID being analyzed should belong to a contact present in the owner's roster with the
291         * specified subscription status.
292         */
293        subscription
294    }
295}