<commit_before>%%%-------------------------------------------------------------------
%%% @author <NAME> <<EMAIL>>
%%% @copyright (C) 2014, <NAME>
%%% 
%%% This file is provided to you under the Apache License,
%%% Version 2.0 (the "License"); you may not use this file
%%% except in compliance with the License.  You may obtain
%%% a copy of the License at
%%% 
%%%   http://www.apache.org/licenses/LICENSE-2.0
%%% 
%%% Unless required by applicable law or agreed to in writing,
%%% software distributed under the License is distributed on an
%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%%% KIND, either express or implied.  See the License for the
%%% specific language governing permissions and limitations
%%% under the License.
%%% 
%%% @doc
%%%
%%% @end
%%% Created : 15 May 2014 by <NAME> <<EMAIL>>
%%%-------------------------------------------------------------------
-module(occi_acl).
-compile({parse_transform, lager_transform}).

-include("occi.hrl").
-include("occi_acl.hrl").

-export([check/3]).

-spec check(acl_op(), acl_node(), acl_user()) -> allow | deny.
check(Op, capabilities, User) ->
    Acls = occi_config:get(acl, []),
    check_acls(Acls, {Op, capabilities, User});
check(Op, #uri{path=Path}, User) ->
    Acls = occi_config:get(acl, []),
    check_acls(Acls, {Op, Path, User}).

%%%
%%% Priv
%%%
check_acls([], _) ->
    % Default policy. Should be configurable ?
    deny;
check_acls([ Acl | Acls ], Action) ->
    case match(Acl, Action) of
	false -> check_acls(Acls, Action);
	{true, Policy} -> Policy
    end.

match({P, O,   N,   U},           {O, N, U}) -> {true, P};
match({P, O,   N,   '_'},         {O, N, _}) -> {true, P};
match({P, O,   N,   anonymous},   {O, N, _}) -> {true, P};
match({P, O,   '_', U},           {O, _, U}) -> {true, P};
match({P, O,   '_', '_'},         {O, _, _}) -> {true, P};
match({P, O,   '_', anonymous},   {O, _, _}) -> {true, P};
match({P, '_', N,   U},           {_, N, U}) -> {true, P};
match({P, '_', N,   '_'},         {_, N, _}) -> {true, P};
match({P, '_', N,   anonymous},   {_, N, _}) -> {true, P};
match({P, '_', '_', U},           {_, _, U}) -> {true, P};
match({P, '_', '_', '_'},         _)         -> {true, P};
match({P, '_', '_', anonymous},   _)         -> {true, P};
match(_,                          _)         -> false.<commit_msg>Add path prefix matching for ACL<commit_after>%%%-------------------------------------------------------------------
%%% @author <NAME> <<EMAIL>>
%%% @copyright (C) 2014, <NAME>
%%% 
%%% This file is provided to you under the Apache License,
%%% Version 2.0 (the "License"); you may not use this file
%%% except in compliance with the License.  You may obtain
%%% a copy of the License at
%%% 
%%%   http://www.apache.org/licenses/LICENSE-2.0
%%% 
%%% Unless required by applicable law or agreed to in writing,
%%% software distributed under the License is distributed on an
%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%%% KIND, either express or implied.  See the License for the
%%% specific language governing permissions and limitations
%%% under the License.
%%% 
%%% @doc
%%%
%%% @end
%%% Created : 15 May 2014 by <NAME> <<EMAIL>>
%%%-------------------------------------------------------------------
-module(occi_acl).
-compile({parse_transform, lager_transform}).

-include("occi.hrl").
-include("occi_acl.hrl").

-export([check/3]).

-spec check(acl_op(), acl_node(), acl_user()) -> allow | deny.
check(Op, capabilities, User) ->
    Acls = occi_config:get(acl, []),
    check_acls(Acls, {Op, capabilities, User});
check(Op, #uri{path=Path}, User) ->
    Acls = occi_config:get(acl, []),
    check_acls(Acls, {Op, list_to_binary(Path), User}).

%%%
%%% Priv
%%%
check_acls([], _) ->
    % Default policy. Should be configurable ?
    deny;
check_acls([ Acl | Acls ], Action) ->
    case match(Acl, Action) of
	false -> check_acls(Acls, Action);
	{true, Policy} -> Policy
    end.

match({P, O,   capabilities,   U},           {O, capabilities, U}) -> 
    {true, P};
match({P, O,   capabilities,   '_'},         {O, capabilities, _}) -> 
    {true, P};
match({P, O,   capabilities,   anonymous},   {O, capabilities, _}) -> 
    {true, P};
match({P, O,   Prefix,         U},           {O, Path,         U}) -> 
    match_path(Prefix, Path, P);
match({P, O,   Prefix,         '_'},         {O, Path,         _}) -> 
    match_path(Prefix, Path, P);
match({P, O,   Prefix,         anonymous},   {O, Path,         _}) -> 
    match_path(Prefix, Path, P);
match({P, O,   '_',            U},           {O, _,            U}) -> 
    {true, P};
match({P, O,   '_',            '_'},         {O, _,            _}) -> 
    {true, P};
match({P, O,   '_',            anonymous},   {O, _,            _}) -> 
    {true, P};
match({P, '_', capabilities,   U},           {_, capabilities, U}) -> 
    {true, P};
match({P, '_', capabilities,   '_'},         {_, capabilities, _}) -> 
    {true, P};
match({P, '_', capabilities,   anonymous},   {_, capabilities, _}) -> 
    {true, P};
match({P, '_', Prefix,         U},           {_, Path,         U}) -> 
    match_path(Prefix, Path, P);
match({P, '_', Prefix,         '_'},         {_, Path,         _}) -> 
    match_path(Prefix, Path, P);
match({P, '_', Prefix,         anonymous},   {_, Path,         _}) -> 
    match_path(Prefix, Path, P);
match({P, '_', '_',            U},           {_, _,            U}) -> 
    {true, P};
match({P, '_', '_',            '_'},         _)                    -> 
    {true, P};
match({P, '_', '_',            anonymous},   _)                    -> 
    {true, P};
match(_,                                     _)                    -> 
    false.

match_path(Prefix, Path, P) ->
    match_path2(filename:split(Prefix), filename:split(Path), P).

match_path2([], _Path, P) ->
    lager:debug("### match path: [] -> ~p : true~n", [_Path]),
    {true, P};
match_path2(_Prefix, [], _P) ->
    lager:debug("### match path: ~p -> [] : false~n", [_Prefix]),
    false;
match_path2([ H | Prefix ], [ H | Path ], P) ->
    lager:debug("### match path: [ ~p | ~p ] -> [ ~p | ~p ] : next~n", [H, Prefix, H, Path]),
    match_path2(Prefix, Path, P);
match_path2([ _H1 | _Prefix ], [ _H2 | _Path ], _P) ->
    lager:debug("### match path: [ ~p | ~p ] -> [ ~p | ~p ] : false~n", [_H1, _Prefix, _H2, _Path]),
    false.
{'fraction_non_alphanumeric': 0.24723713293337543, 'fraction_numerical': 0.006315124723713293, 'mean_word_length': 2.1330365974282888, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1646060', 'n_tokens_mistral': 2171, 'n_tokens_neox': 2121, 'n_words': 572}