./ct_report/coverage/mongoose_privacy.COVER.html

1 %%%-------------------------------------------------------------------
2 %%% @author bartek <bartlomiej.gorny@erlang-solutions.com>
3 %%% @copyright (C) 2017, Erlang Solutions sp. z o.o.
4 %%% @doc Generic functions for checking packet against privacy rules. Works by
5 %%% calling 'privacy_check_packet' hooks to which various handlers might be attached.
6 %%%
7 %%% @end
8 %%% Created : 06. Feb 2017 11:37
9 %%%-------------------------------------------------------------------
10 -module(mongoose_privacy).
11 -author("bartek").
12
13 -include("jlib.hrl").
14 -include("mod_privacy.hrl").
15
16 %% API
17 -export([privacy_check_packet/5, privacy_check_packet/6]).
18
19 -type direction() :: in | out.
20 -type decision() :: allow | deny | block.
21 -type userlist() :: #userlist{}.
22 -export_type([direction/0, decision/0, userlist/0]).
23
24 %%% API %%%
25
26 %% @doc abbreviated version - in most cases we have 'from' in Acc, but sometimes
27 %% the caller wants something different (e.g. mod_last which swaps addresses)
28 %% the first arg can be accumulator, if we are checking its element, or a tuple
29 %% {Acc, El} for cases where one acc triggers sending many messages which have to be checked
30 -spec privacy_check_packet(Acc :: mongoose_acc:t() | {mongoose_acc:t(), exml:element()},
31 JID :: jid:jid(),
32 PrivacyList :: userlist(),
33 To :: jid:jid(),
34 Dir :: direction()) -> {decision(), mongoose_acc:t()}.
35 privacy_check_packet(Acc0, JID, PrivacyList, To, Dir) ->
36 3544 Acc1 = case Acc0 of
37
:-(
{Acc, #xmlel{}} -> Acc;
38 3544 _ -> Acc0
39 end,
40 3544 From = mongoose_acc:from_jid(Acc1),
41 3544 privacy_check_packet(Acc0, JID, PrivacyList, From, To, Dir).
42
43 %% @doc check packet, store result in accumulator, return acc and result for quick check
44 %% Acc can be either a single argument (an Accumulator) or a tuple of {Acc, Stanza}
45 %% in the latter case name and type to check against privacy lists are taken from the Stanza
46 -spec privacy_check_packet(Acc :: mongoose_acc:t() | {mongoose_acc:t(), exml:element()},
47 JID :: jid:jid(),
48 PrivacyList :: userlist(),
49 From :: jid:jid(),
50 To :: jid:jid(),
51 Dir :: direction()) -> {decision(), mongoose_acc:t()}.
52 privacy_check_packet(Acc0, #jid{luser = LUser, lserver = LServer} = JID,
53 PrivacyList, From, To, Dir) ->
54 % see if we have just Acc or also stanza to check - may have different name/type
55 3547 {Acc, Name, Type} = case Acc0 of
56 {A, #xmlel{name = SName} = Stanza} ->
57
:-(
SType = exml_query:attr(Stanza, <<"type">>, undefined),
58
:-(
{A, SName, SType};
59 _ ->
60 3547 {Acc0, mongoose_acc:stanza_name(Acc0), mongoose_acc:stanza_type(Acc0)}
61 end,
62 % check if it is there, if not then set default and run a hook
63 3547 Key = {cached_check, LServer, LUser, From, To, Name, Type, Dir},
64 3547 case mongoose_acc:get(privacy, Key, undefined, Acc) of
65 undefined ->
66 3547 Acc1 = mongoose_hooks:privacy_check_packet(Acc, JID, PrivacyList,
67 {From, To, Name, Type}, Dir),
68 3547 Res = mongoose_acc:get(hook, result, Acc1),
69 3547 {Res, mongoose_acc:set(privacy, Key, Res, Acc1)};
70 Res ->
71
:-(
{Res, Acc}
72 end.
Line Hits Source