14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program. If not, see <https://www.gnu.org/licenses/>.
16
16
17
+ require "json"
17
18
require "openssl"
19
+ require_relative "payload"
18
20
require_relative "response"
19
21
20
22
module Deployer
@@ -29,23 +31,70 @@ def call(env)
29
31
private
30
32
31
33
def process ( request , response )
32
- unless request . post?
33
- response . set ( :method_not_allowed , "must POST" )
34
- return
35
- end
36
-
37
- unless valid_signature? ( request )
38
- response . set ( :unauthorized , "Authorization failed" )
39
- return
34
+ begin
35
+ unless request . post?
36
+ raise RequestError . new ( :method_not_allowed , "must POST" )
37
+ end
38
+ verify_signature! ( request )
39
+ payload = parse_body! ( request )
40
+ process_payload! ( payload )
41
+ rescue RequestError => request_error
42
+ response . set ( request_error . status , request_error . message )
43
+ rescue => e
44
+ response . set ( :internal_server_error , e . message )
40
45
end
41
46
end
42
47
43
- def valid_signature? ( request )
48
+ def verify_signature! ( request )
44
49
hmac_sha256 = OpenSSL ::HMAC . hexdigest ( OpenSSL ::Digest . new ( "sha256" ) ,
45
50
ENV [ "SECRET_TOKEN" ] ,
46
51
request . body . read )
47
52
signature = "sha256=#{ hmac_sha256 } "
48
- Rack ::Utils . secure_compare ( signature , request . env [ "HTTP_X_HUB_SIGNATURE_256" ] )
53
+ unless Rack ::Utils . secure_compare ( signature , request . env [ "HTTP_X_HUB_SIGNATURE_256" ] )
54
+ raise RequestError . new ( :unauthorized , "Authorization failed" )
55
+ end
56
+ end
57
+
58
+ def parse_body! ( request )
59
+ unless request . media_type == "application/json"
60
+ raise RequestError . new ( :bad_request , "invalid payload format" )
61
+ end
62
+
63
+ body = request . body . read
64
+ if body . nil?
65
+ raise RequestError . new ( :bad_request , "request body is missing" )
66
+ end
67
+
68
+ begin
69
+ raw_payload = JSON . parse ( body )
70
+ rescue JSON ::ParserError
71
+ raise RequestError . new ( :bad_request , "invalid JSON format: <#{ $!. message } >" )
72
+ end
73
+
74
+ metadata = {
75
+ "x-github-event" => request . env [ "HTTP_X_GITHUB_EVENT" ]
76
+ }
77
+ Payload . new ( raw_payload , metadata )
78
+ end
79
+
80
+ def process_payload! ( payload )
81
+ case payload . event_name
82
+ when "ping"
83
+ # Do nothing because this is a kind of healthcheck.
84
+ nil
85
+ when "workflow_run"
86
+ return unless payload . released?
87
+ deploy ( payload )
88
+ else
89
+ raise RequestError . new ( :bad_request , "Unsupported event: <#{ payload . event_name } >" )
90
+ end
91
+ end
92
+
93
+ def deploy ( payload )
94
+ Thread . new do
95
+ # TODO: call rake tasks for sign packages.
96
+ # TODO: write down the errors into log files.
97
+ end
49
98
end
50
99
end
51
100
end
0 commit comments