Skip to content

Commit

Permalink
Merge pull request #66 from inaka/jfacorro.58.github.api.oauth
Browse files Browse the repository at this point in the history
[#58] Added support for OAuth.
  • Loading branch information
elbrujohalcon committed Jul 25, 2014
2 parents b27ea85 + f388eb6 commit f22c859
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 25 deletions.
13 changes: 11 additions & 2 deletions src/elvis.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
-export([
rock/0,
rock/1,
webhook/1
webhook/1,
webhook/2
]).

-export([start/0]).
Expand Down Expand Up @@ -80,7 +81,15 @@ git_hook(Config) ->
%% @doc Should receive the payload of a Github event and act accordingly.
-spec webhook(webhook:request()) -> ok | {error, term()}.
webhook(Request) ->
elvis_webhook:event(Request).
Credentials = elvis_github:basic_auth_credentials(),
elvis_webhook:event(Credentials, Request).

%% @doc Receives github credentials (basic or OAuth) and the payload
%% from an event, acting accordingly.
-spec webhook(elvis_github:credentials(), webhook:request()) ->
ok | {error, term()}.
webhook(Credentials, Request) ->
elvis_webhook:event(Credentials, Request).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Private
Expand Down
33 changes: 25 additions & 8 deletions src/elvis_github.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

%% Pull Requests
-export([
basic_auth_credentials/0,
pull_req_files/3,
pull_req_comment_line/7,
pull_req_comments/3
Expand All @@ -18,7 +19,9 @@
repository/0
]).

-type credentials() :: {Username :: string(), Password :: string()}.
-type credentials() ::
{basic, Username :: string(), Password :: string()}
| {oauth, Token :: string()}.
-type repository() :: string(). %% "username/reponame"
-type result() :: ok | {ok, any()} | {error, term()}.

Expand All @@ -32,6 +35,13 @@
%% Public API
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% @doc Gets the github basic auth credentials form the elvis app environment.
-spec basic_auth_credentials() -> credentials().
basic_auth_credentials() ->
User = application:get_env(elvis, github_user, ""),
Password = application:get_env(elvis, github_password, ""),
{basic, User, Password}.

-spec pull_req_files(credentials(), repository(), integer()) ->
result().
pull_req_files(Credentials, Repo, PR) ->
Expand Down Expand Up @@ -65,7 +75,7 @@ pull_req_comments(Cred, Repo, PR) ->
-spec file_content(credentials(), repository(), string(), string()) ->
{ok, binary()}.
file_content(Cred, Repo, CommitId, Filename) ->
Url = make_url(raw_contents, {Repo, CommitId, Filename}),
Url = make_url(file_content, {Repo, CommitId, Filename}),
case auth_req(Cred, Url) of
{ok, Result} ->
JsonResult = jiffy:decode(Result, [return_maps]),
Expand All @@ -85,7 +95,7 @@ make_url({pull_req, Subentity}, {Repo, PR}) ->
SubentityStr = elvis_utils:to_str(Subentity),
Url = ?GITHUB_API ++ "/repos/~s/pulls/~p/" ++ SubentityStr,
io_lib:format(Url, [Repo, PR]);
make_url(raw_contents, {Repo, CommitId, Filename}) ->
make_url(file_content, {Repo, CommitId, Filename}) ->
Url = ?GITHUB_API ++ "/repos/~s/contents/~s?ref=~s",
io_lib:format(Url, [Repo, Filename, CommitId]).

Expand All @@ -95,10 +105,10 @@ auth_req(Credentials, Url) ->

-spec auth_req(credentials(), string(), ibrowse:method(), ibrowse:body()) ->
{ok, string()} | {error, term()}.
auth_req({Username, Password}, Url, Method, Body) ->
Options = [{basic_auth, {Username, Password}},
{ssl_options, [{depth, 0}]}],
Headers = [{"User-Agent", "Elvis-Webhook"}],
auth_req(Cred, Url, Method, Body) ->
Options0 = [{ssl_options, [{depth, 0}]}],
Headers0 = [{"User-Agent", "Elvis-Webhook"}],
{Options, Headers} = authorization(Cred, Options0, Headers0),
lager:info("[Github API] ~s", [Url]),
case ibrowse:send_req(Url, Headers, Method, Body, Options) of
{ok, "200", _RespHeaders, RespBody} ->
Expand All @@ -107,7 +117,14 @@ auth_req({Username, Password}, Url, Method, Body) ->
{ok, RespBody};
{ok, "302", RespHeaders, _} ->
RedirectUrl = proplists:get_value("Location", RespHeaders),
auth_req({Username, Password}, RedirectUrl, Method, Body);
auth_req(Cred, RedirectUrl, Method, Body);
{ok, Status, RespHeaders, RespBody} ->
{error, {Status, RespHeaders, RespBody}}
end.

authorization({basic, Username, Password}, Options0, Headers) ->
Options = [{basic_auth, {Username, Password}} | Options0],
{Options, Headers};
authorization({oauth, Token}, Options, Headers0) ->
Headers = [{"Authorization", "token " ++ Token} | Headers0],
{Options, Headers}.
26 changes: 11 additions & 15 deletions src/elvis_webhook.erl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-module(elvis_webhook).

-export([event/1]).
-export([event/2]).

-export_type([request/0]).

Expand All @@ -19,8 +19,8 @@
%%% Public API
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

-spec event(request()) -> ok | {error, term()}.
event(#{headers := Headers, body := Body}) ->
-spec event(elvis_github:credentials(), request()) -> ok | {error, term()}.
event(Cred, #{headers := Headers, body := Body}) ->
HeaderName = <<"x-github-event">>,
case maps:is_key(HeaderName, Headers) of
false ->
Expand All @@ -29,7 +29,7 @@ event(#{headers := Headers, body := Body}) ->
EventName = maps:get(HeaderName, Headers),
EventData = jiffy:decode(Body, [return_maps]),
Config = elvis_config:default(),
event(Config, EventName, EventData)
event(Config, Cred, EventName, EventData)
end.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Expand All @@ -39,12 +39,15 @@ event(#{headers := Headers, body := Body}) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Events

-spec event(elvis_config:config(), event(), map()) -> ok | {error, term()}.
-spec event(elvis_config:config(),
elvis_github:credentials(),
event(),
map()) -> ok | {error, term()}.
event(LocalConfig,
Cred,
<<"pull_request">>,
#{<<"number">> := PR, <<"repository">> := Repository}) ->
Repo = binary_to_list(maps:get(<<"full_name">>, Repository)),
Cred = github_credentials(),
Config = repo_config(Cred, Repo, LocalConfig),

{ok, GithubFiles} = elvis_github:pull_req_files(Cred, Repo, PR),
Expand All @@ -61,10 +64,10 @@ event(LocalConfig,
ok -> ok
end;

event(_Config, <<"ping">>, _Data) ->
event(_Config, _Cred, <<"ping">>, _Data) ->
ok;

event(_Config, Event, _Data) ->
event(_Config, _Cred, Event, _Data) ->
{error, io_lib:format("Nothing to do for event: ~p.~n", [Event])}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Expand All @@ -91,13 +94,6 @@ repo_config(Cred, Repo, LocalConfig) ->
LocalConfig
end.

%% @doc Gets the github
-spec github_credentials() -> elvis_github:credentials().
github_credentials() ->
User = application:get_env(elvis, github_user, ""),
Password = application:get_env(elvis, github_password, ""),
{User, Password}.

%% @doc Gets a raw_url for a file and extracts the commit id from it.
-spec commit_id_from_raw_url(string(), string()) -> string().
commit_id_from_raw_url(Url, Filename) ->
Expand Down

0 comments on commit f22c859

Please sign in to comment.