| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| -module(hk_browser_capability). |
|
|
| -export([operations/0, is_granted/2, validate_args/2]). |
|
|
| -type operation() :: create_session | close_session | open_tab | close_tab |
| | navigate | back | forward | reload | read_page |
| | query_element | click | type | scroll | screenshot |
| | extract_links. |
|
|
| -export_type([operation/0]). |
|
|
| -spec operations() -> [operation()]. |
| operations() -> |
| [create_session, close_session, open_tab, close_tab, |
| navigate, back, forward, reload, read_page, |
| query_element, click, type, scroll, screenshot, extract_links]. |
|
|
| |
| |
| |
| |
| |
| -spec is_granted([term()], operation() | {operation(), map()}) -> boolean(). |
| is_granted(Capabilities, {navigate, #{url := Url}}) -> |
| lists:any( |
| fun (navigate) -> true; |
| ({navigate, #{allowed_domains := Domains}}) -> host_allowed(Url, Domains); |
| (_) -> false |
| end, |
| Capabilities); |
| is_granted(Capabilities, Op) when is_atom(Op) -> |
| lists:any( |
| fun (G) when G =:= Op -> true; |
| ({G, _}) when G =:= Op -> true; |
| (_) -> false |
| end, |
| Capabilities). |
|
|
| |
| |
| |
| |
| |
| -spec validate_args(operation(), map()) -> {ok, map()} | {error, term()}. |
| validate_args(navigate, #{url := Url} = Args) when is_binary(Url) -> |
| case valid_url(Url) of |
| true -> {ok, Args}; |
| false -> {error, {invalid_url, Url}} |
| end; |
| validate_args(navigate, _) -> |
| {error, missing_url}; |
| validate_args(open_tab, #{url := Url} = Args) when is_binary(Url) -> |
| case valid_url(Url) of |
| true -> {ok, Args}; |
| false -> {error, {invalid_url, Url}} |
| end; |
| validate_args(Op, #{selector := Selector} = Args) |
| when Op =:= click; Op =:= type; Op =:= query_element -> |
| case is_binary(Selector) andalso byte_size(Selector) > 0 andalso byte_size(Selector) < 2048 of |
| true when Op =:= type -> |
| case Args of |
| #{text := Text} when is_binary(Text), byte_size(Text) =< 10000 -> {ok, Args}; |
| #{text := _} -> {error, text_too_long}; |
| _ -> {error, missing_text} |
| end; |
| true -> {ok, Args}; |
| false -> {error, invalid_selector} |
| end; |
| validate_args(scroll, #{delta_y := Dy} = Args) when is_integer(Dy), Dy >= -100000, Dy =< 100000 -> |
| {ok, Args}; |
| validate_args(Op, Args) when Op =:= close_session; Op =:= close_tab; Op =:= back; |
| Op =:= forward; Op =:= reload; Op =:= read_page; |
| Op =:= screenshot; Op =:= extract_links; Op =:= create_session -> |
| {ok, Args}; |
| validate_args(Op, _Args) -> |
| {error, {invalid_arguments, Op}}. |
|
|
| |
|
|
| valid_url(Url) -> |
| case uri_string:parse(Url) of |
| #{scheme := Scheme} when Scheme =:= <<"http">>; Scheme =:= <<"https">>; |
| Scheme =:= <<"about">>; Scheme =:= <<"data">> -> |
| true; |
| _ -> |
| false |
| end. |
|
|
| host_allowed(Url, Domains) -> |
| case uri_string:parse(Url) of |
| #{host := Host} -> lists:member(Host, Domains); |
| _ -> false |
| end. |
|
|