@@ -22,22 +22,39 @@ def verifyGitlabRequest(request: Request, token:str) -> bool:
2222 """Verify the GitLab token of a webhook request"""
2323 return request .headers .get (GITLAB_HEADER ) == token
2424
25- # TODO add IP whitelisting, limiting to one git type, automatic github IP whitelisting
25+ def verifyBasicAuth (request : Request , token :str ) -> bool :
26+ """Verify the basic authorization of a webhook request"""
27+ return str (request .authorization ) == token
28+
29+ # TODO add automatic github IP whitelisting
2630
2731class webhookBlueprint (Blueprint , gitWebhookBlueprintABC ):
2832 """Wrapper over the flask blueprint that creates an endpoint for receiving and processing git webhooks. Overwrite the processWebhook method to process the webhook data."""
2933
30- def __init__ (self , webhookToken :str | None , log :Logger | None = None , name :str = "webhook" , * args , ** kwargs ):
34+ def __init__ (self , webhookToken :str | None , log :Logger | None = None , name :str = "webhook" , github : bool = True , gitlab : bool = True , gitea : bool = True , ipWhitelist : list [ str ] | None = None , * args , ** kwargs ):
3135 super ().__init__ (name , self .__class__ .__name__ , * args , ** kwargs )
3236 self .log = log
3337 if webhookToken is None :
3438 if self .log is not None :
3539 self .log .warning ("No webhook token provided. THIS IS VERY UNSAFE" )
3640 self .webhookToken = webhookToken
41+ self .github = github
42+ self .gitlab = gitlab
43+ self .gitea = gitea
44+ self .ipWhitelist = ipWhitelist
3745 self .route ("/" , methods = ["POST" ])(self .receiveWebhook )
3846
3947 def receiveWebhook (self ) -> Response :
4048 """Receive webhook from GitHub and process it using the processWebhook method."""
49+ if self .ipWhitelist is not None :
50+ if request .remote_addr is None :
51+ if self .log is not None :
52+ self .log .warning ("Received a request with no IP address" )
53+ abort (403 )
54+ if request .remote_addr not in self .ipWhitelist :
55+ if self .log is not None :
56+ self .log .warning (f"Received a request from an unauthorized IP address: { request .remote_addr } " )
57+ abort (403 )
4158 if self .log is not None :
4259 self .log .debug ("Received a POST request to the webhook endpoint" )
4360 #check if the content type is json
@@ -46,18 +63,18 @@ def receiveWebhook(self) -> Response:
4663 self .log .warning (f"A request with an invalid content type: { request .content_type } " )
4764 abort (415 )
4865 if self .webhookToken is not None : #verification
49- if GITHUB_HEADER in request .headers :
66+ if GITHUB_HEADER in request .headers and self . github :
5067 if not verifyGithubRequest (request , self .webhookToken ):
5168 if self .log is not None :
5269 self .log .warning ("A request with an invalid GitHub signaturez" )
5370 abort (401 )
54- elif GITLAB_HEADER in request .headers :
71+ elif GITLAB_HEADER in request .headers and self . github :
5572 if not verifyGitlabRequest (request , self .webhookToken ):
5673 if self .log is not None :
5774 self .log .warning ("A request with an invalid GitLab token" )
5875 abort (401 )
59- elif request .authorization is not None : # basic authorization which is what Gitea uses
60- if not str (request . authorization ) == self .webhookToken :
76+ elif request .authorization is not None and self . gitea : # basic authorization which is what Gitea uses
77+ if not verifyBasicAuth (request , self .webhookToken ) :
6178 if self .log is not None :
6279 self .log .warning ("A request with an invalid basic authorization" )
6380 abort (401 )
0 commit comments