Packages

A module for parsing, mutating, and serializing Content-Security-Policy directives.

Current section

Files

Jump to
cosepo src cosepo.erl
Raw

src/cosepo.erl

-module(cosepo).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([serialize/1, merge/2, parse/1, set/2]).
-export_type([content_security_policy/0]).
-type content_security_policy() :: {content_security_policy,
list(cosepo@directive:directive())}.
-spec serialize(content_security_policy()) -> binary().
serialize(Content_security_policy) ->
_pipe = gleam@list:fold(
erlang:element(2, Content_security_policy),
<<""/utf8>>,
fun(Serialized_csp, Directive) ->
<<<<<<Serialized_csp/binary,
(cosepo@directive:get_name(Directive))/binary>>/binary,
(gleam@list:fold(
cosepo@directive:get_value(Directive),
<<""/utf8>>,
fun(Serialized_directive, Value) ->
<<<<Serialized_directive/binary, " "/utf8>>/binary,
Value/binary>>
end
))/binary>>/binary,
"; "/utf8>>
end
),
gleam@string:trim(_pipe).
-spec find_directive_by_name(content_security_policy(), binary()) -> {ok,
cosepo@directive:directive()} |
{error, nil}.
find_directive_by_name(Content_security_policy, Name) ->
gleam@list:find(
erlang:element(2, Content_security_policy),
fun(Directive) -> cosepo@directive:get_name(Directive) =:= Name end
).
-spec merge(content_security_policy(), cosepo@directive:directive()) -> content_security_policy().
merge(Content_security_policy, Directive) ->
_pipe = case find_directive_by_name(
Content_security_policy,
cosepo@directive:get_name(Directive)
) of
{error, _} ->
lists:append(
erlang:element(2, Content_security_policy),
[Directive]
);
{ok, Existing_directive} ->
Value = lists:append(
cosepo@directive:get_value(Existing_directive),
cosepo@directive:get_value(Directive)
),
_assert_subject = cosepo@directive:new_directive(
cosepo@directive:get_name(Directive),
Value
),
{ok, Next} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"cosepo"/utf8>>,
function => <<"merge"/utf8>>,
line => 113})
end,
[Next]
end,
{content_security_policy, _pipe}.
-spec parse(binary()) -> {ok, content_security_policy()} | {error, binary()}.
parse(Serialized_csp) ->
Csp = {ok, {content_security_policy, []}},
gleam@list:fold(
gleam@string:split(Serialized_csp, <<";"/utf8>>),
Csp,
fun(Accumulator, Directive) -> case Accumulator of
{error, E} ->
{error, E};
{ok, Valid_csp} ->
Trimmed_directive = gleam@string:trim(Directive),
case gleam@string:split(Trimmed_directive, <<" "/utf8>>) of
[] ->
{error, <<"Nothing to parse!"/utf8>>};
[Name] ->
case Name of
<<"upgrade-insecure-requests"/utf8>> ->
_assert_subject = cosepo@directive:new_directive(
<<"upgrade-insecure-requests"/utf8>>,
[]
),
{ok, Directive@1} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(
#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"cosepo"/utf8>>,
function => <<"parse"/utf8>>,
line => 37}
)
end,
{ok, merge(Valid_csp, Directive@1)};
<<""/utf8>> ->
{ok, Valid_csp};
_ ->
{error,
<<"missing directive values for "/utf8,
Trimmed_directive/binary>>}
end;
[Name@1 | Value] ->
case cosepo@directive:new_directive(
gleam@string:lowercase(Name@1),
Value
) of
{error, E@1} ->
{error, E@1};
{ok, New_directive} ->
{ok, merge(Valid_csp, New_directive)}
end
end
end end
).
-spec set(content_security_policy(), cosepo@directive:directive()) -> content_security_policy().
set(Content_security_policy, Directive) ->
_pipe = case find_directive_by_name(
Content_security_policy,
cosepo@directive:get_name(Directive)
) of
{error, _} ->
lists:append(
erlang:element(2, Content_security_policy),
[Directive]
);
{ok, Existing_directive} ->
_assert_subject = cosepo@directive:new_directive(
cosepo@directive:get_name(Existing_directive),
cosepo@directive:get_value(Directive)
),
{ok, Next} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"cosepo"/utf8>>,
function => <<"set"/utf8>>,
line => 135})
end,
[Next]
end,
{content_security_policy, _pipe}.