@@ -101,16 +101,144 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException
101101 GogsResults result = new GogsResults ();
102102
103103 try {
104- internalDoIndex (result , req , rsp );
104+ String event = req .getHeader ("X-Gogs-Event" );
105+ if ("push" .equals (event )) {
106+ internalDoIndex (result , req , rsp );
107+ }
108+ else {
109+ internalDoIndexRelease (result , req , rsp );
110+ }
105111
106112 } catch (final RuntimeException re ) {
107113 LOGGER .severe (re .toString ());
108- result .setStatus (500 , "GogsWebHook execution error." );
114+ result .setStatus (500 , re . toString () );
109115 exitWebHook (result , rsp );
110116 return ;
111117 }
112118 }
113119
120+ void internalDoIndexRelease (GogsResults result , StaplerRequest req , StaplerResponse rsp ) throws IOException {
121+ GogsPayloadProcessor payloadProcessor = new GogsPayloadProcessor ();
122+ //Check that we have something to process
123+ checkNotNull (req , "Null request submitted to doIndex method" );
124+ checkNotNull (rsp , "Null reply submitted to doIndex method" );
125+
126+ // Get X-Gogs-Delivery header with deliveryID
127+ String gogsDelivery = req .getHeader ("X-Gogs-Delivery" );
128+ if (gogsDelivery == null || gogsDelivery .isEmpty ()) {
129+ gogsDelivery = "Triggered by Jenkins-Gogs-Plugin. Delivery ID unknown." ;
130+ } else {
131+ gogsDelivery = "Gogs-ID: " + gogsDelivery ;
132+ }
133+
134+ // Get X-Gogs-Signature
135+ String gogsSignature = req .getHeader ("X-Gogs-Signature" );
136+ if (gogsSignature == null || gogsSignature .isEmpty ()) {
137+ gogsSignature = null ;
138+ }
139+
140+
141+ // Get queryStringMap from the URI
142+ String queryString = checkNotNull (req .getQueryString (), "The queryString in the request is null" );
143+ Map queryStringMap = checkNotNull (splitQuery (queryString ), "Null queryStringMap" );
144+
145+ //Do we have the job name parameter ?
146+ if (!queryStringMap .containsKey ("job" )) {
147+ result .setStatus (404 , "Parameter 'job' is missing." );
148+ exitWebHookRelease (result , rsp );
149+ return ;
150+ }
151+ Object jobObject = queryStringMap .get ("job" );
152+ String jobName ;
153+ if (jobObject == null ) {
154+ result .setStatus (404 , "No value assigned to parameter 'job'" );
155+ exitWebHookRelease (result , rsp );
156+ return ;
157+ } else {
158+ jobName = jobObject .toString ();
159+ }
160+
161+ final Object branchName = queryStringMap .get ("branch" );
162+
163+ String body = IOUtils .toString (req .getInputStream (), DEFAULT_CHARSET );
164+ if (!body .isEmpty () && req .getRequestURI ().contains ("/" + URLNAME + "/" )) {
165+ JSONObject jsonObject = JSONObject .fromObject (body );
166+
167+ JSONObject release = (JSONObject ) jsonObject .getJSONObject ("release" );
168+ String tagName = release .getString ("tag_name" );
169+ String contentType = req .getContentType ();
170+ if (contentType != null && contentType .startsWith ("application/x-www-form-urlencoded" )) {
171+ body = URLDecoder .decode (body , DEFAULT_CHARSET );
172+ }
173+ if (body .startsWith ("payload=" )) {
174+ body = body .substring (8 );
175+ }
176+
177+ String jSecret = null ;
178+ boolean foundJob = false ;
179+ payloadProcessor .setPayload ("ref" , tagName );
180+ SecurityContext saveCtx = ACL .impersonate (ACL .SYSTEM );
181+
182+ try {
183+ Job job = GogsUtils .find (jobName , Job .class );
184+
185+ if (job != null ) {
186+ foundJob = true ;
187+ /* secret is stored in the properties of Job */
188+ final GogsProjectProperty property = (GogsProjectProperty ) job .getProperty (GogsProjectProperty .class );
189+ if (property != null ) { /* only if Gogs secret is defined on the job */
190+ jSecret = Secret .toString (property .getGogsSecret ()); /* Secret provided by Jenkins */
191+ }
192+ }
193+
194+ if (job != null ) {
195+ foundJob = true ;
196+ /* secret is stored in the properties of Job */
197+ final GogsProjectProperty property = (GogsProjectProperty ) job .getProperty (GogsProjectProperty .class );
198+ if (property != null ) { /* only if Gogs secret is defined on the job */
199+ jSecret = Secret .toString (property .getGogsSecret ()); /* Secret provided by Jenkins */
200+ }
201+ }
202+ } finally {
203+ SecurityContextHolder .setContext (saveCtx );
204+ }
205+
206+ String gSecret = null ;
207+ if (gogsSignature == null ) {
208+ gSecret = jsonObject .optString ("secret" , null ); /* Secret provided by Gogs < 0.10.x */
209+ } else {
210+ try {
211+ if (gogsSignature .equals (encode (body , jSecret ))) {
212+ gSecret = jSecret ;
213+ // now hex is right, continue to old logic
214+ }
215+ } catch (Exception e ) {
216+ LOGGER .warning (e .getMessage ());
217+ }
218+ }
219+
220+ if (!foundJob ) {
221+ String msg = String .format ("Job '%s' is not defined in Jenkins" , jobName );
222+ result .setStatus (404 , msg );
223+ LOGGER .warning (msg );
224+ } else if (isNullOrEmpty (jSecret ) && isNullOrEmpty (gSecret )) {
225+ /* No password is set in Jenkins and Gogs, run without secrets */
226+ result = payloadProcessor .triggerJobs (jobName , gogsDelivery );
227+ } else if (!isNullOrEmpty (jSecret ) && jSecret .equals (gSecret )) {
228+ /* Password is set in Jenkins and Gogs, and is correct */
229+ result = payloadProcessor .triggerJobs (jobName , gogsDelivery );
230+ } else {
231+ /* Gogs and Jenkins secrets differs */
232+ result .setStatus (403 , "Incorrect secret" );
233+ }
234+ } else {
235+ result .setStatus (404 , "No payload or URI contains invalid entries." );
236+ }
237+
238+ exitWebHookRelease (result , rsp );
239+
240+
241+ }
114242 void internalDoIndex (GogsResults result , StaplerRequest req , StaplerResponse rsp ) throws IOException {
115243
116244 GogsPayloadProcessor payloadProcessor = new GogsPayloadProcessor ();
@@ -168,15 +296,16 @@ void internalDoIndex(GogsResults result, StaplerRequest req, StaplerResponse rsp
168296 String body = IOUtils .toString (req .getInputStream (), DEFAULT_CHARSET );
169297 if (!body .isEmpty () && req .getRequestURI ().contains ("/" + URLNAME + "/" )) {
170298 JSONObject jsonObject = JSONObject .fromObject (body );
171- JSONObject commits = (JSONObject ) jsonObject .getJSONArray ("commits" ).get (0 );
172- String message = (String ) commits .get ("message" );
173-
174- if (message .startsWith ("[IGNORE]" )) {
175- // Ignore commits starting with message "[IGNORE]"
176- result .setStatus (200 , "Ignoring push" );
177- exitWebHook (result , rsp );
178- return ;
179- }
299+
300+ JSONObject commits = (JSONObject ) jsonObject .getJSONArray ("commits" ).get (0 );
301+ String message = (String ) commits .get ("message" );
302+ if (message .startsWith ("[IGNORE]" )) {
303+ // Ignore commits starting with message "[IGNORE]"
304+ result .setStatus (200 , "Ignoring push" );
305+ exitWebHook (result , rsp );
306+ return ;
307+ }
308+
180309
181310 String ref = jsonObject .getString ("ref" );
182311 LOGGER .fine ("found ref " + ref );
@@ -304,6 +433,19 @@ private void exitWebHook(GogsResults result, StaplerResponse resp) throws IOExce
304433 printer .print (json .toString ());
305434 }
306435
436+
437+ private void exitWebHookRelease (GogsResults result , StaplerResponse resp ) throws IOException {
438+ if (result .getStatus () != 200 ) {
439+ LOGGER .warning (result .getMessage ());
440+ }
441+ //noinspection MismatchedQueryAndUpdateOfCollection
442+ JSONObject json = new JSONObject ();
443+ json .element ("result" , result .getStatus () == 200 ? "OK" : "ERROR" );
444+ resp .setStatus (result .getStatus ());
445+ resp .addHeader ("Content-Type" , "application/json" );
446+ PrintWriter printer = resp .getWriter ();
447+ printer .print (json .toString ());
448+ }
307449 /**
308450 * Converts Querystring into Map<String,String>
309451 *
0 commit comments