kopia lustrzana https://github.com/snarfed/bridgy-fed
				
				
				
			activitypub: implement HTTP Signatures using httpsig library
thanks @ahknight!pull/27/head
							rodzic
							
								
									2699de6903
								
							
						
					
					
						commit
						b123088158
					
				|  | @ -3,6 +3,7 @@ | ||||||
| bs4 | bs4 | ||||||
| feedparser | feedparser | ||||||
| granary>=1.8 | granary>=1.8 | ||||||
|  | httpsig | ||||||
| mf2py>=1.0.4 | mf2py>=1.0.4 | ||||||
| mf2util>=0.5.0 | mf2util>=0.5.0 | ||||||
| mock | mock | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ import urllib2 | ||||||
| from django_salmon import magicsigs, utils | from django_salmon import magicsigs, utils | ||||||
| import feedparser | import feedparser | ||||||
| from granary import atom, microformats2 | from granary import atom, microformats2 | ||||||
|  | from httpsig.sign import HeaderSigner | ||||||
| import mf2py | import mf2py | ||||||
| import mock | import mock | ||||||
| from mock import call | from mock import call | ||||||
|  | @ -105,9 +106,12 @@ class WebmentionTest(testutil.TestCase): | ||||||
|             ], |             ], | ||||||
|         }, kwargs['json']) |         }, kwargs['json']) | ||||||
| 
 | 
 | ||||||
|         expected_headers = copy.copy(common.HEADERS) |         headers = kwargs['headers'] | ||||||
|         expected_headers['Content-Type'] = activitypub.CONTENT_TYPE_AS |         self.assertEqual(activitypub.CONTENT_TYPE_AS, headers['Content-Type']) | ||||||
|         self.assertEqual(expected_headers, kwargs['headers']) | 
 | ||||||
|  |         expected_key = MagicKey.get_by_id('a') | ||||||
|  |         rsa_key = kwargs['auth'].header_signer._rsa._key | ||||||
|  |         self.assertEqual(expected_key.private_pem(), rsa_key.exportKey()) | ||||||
| 
 | 
 | ||||||
|     def test_salmon(self, mock_get, mock_post): |     def test_salmon(self, mock_get, mock_post): | ||||||
|         orig_atom = requests_response("""\ |         orig_atom = requests_response("""\ | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ TODO tests: | ||||||
| * actor/attributedTo could be string URL | * actor/attributedTo could be string URL | ||||||
| * salmon rel via webfinger via author.name + domain | * salmon rel via webfinger via author.name + domain | ||||||
| """ | """ | ||||||
|  | import datetime | ||||||
| import json | import json | ||||||
| import logging | import logging | ||||||
| import urlparse | import urlparse | ||||||
|  | @ -15,6 +16,7 @@ import django_salmon | ||||||
| from django_salmon import magicsigs, utils | from django_salmon import magicsigs, utils | ||||||
| import feedparser | import feedparser | ||||||
| from granary import atom, microformats2 | from granary import atom, microformats2 | ||||||
|  | from httpsig.requests_auth import HTTPSignatureAuth | ||||||
| import mf2py | import mf2py | ||||||
| import mf2util | import mf2util | ||||||
| from oauth_dropins.webutil import util | from oauth_dropins.webutil import util | ||||||
|  | @ -93,10 +95,27 @@ class WebmentionHandler(webapp2.RequestHandler): | ||||||
|             source_obj['inReplyTo'], |             source_obj['inReplyTo'], | ||||||
|         ]) |         ]) | ||||||
| 
 | 
 | ||||||
|         # deliver source object to target actor's inbox |         # prepare HTTP Signature (required by Mastodon) | ||||||
|  |         # https://w3c.github.io/activitypub/#authorization-lds | ||||||
|  |         # https://tools.ietf.org/html/draft-cavage-http-signatures-07 | ||||||
|  |         # https://github.com/tootsuite/mastodon/issues/4906#issuecomment-328844846 | ||||||
|  |         source_domain = urlparse.urlparse(source).netloc | ||||||
|  |         key = models.MagicKey.get_or_create(source_domain) | ||||||
|  | 
 | ||||||
|  |         acct = 'acct:me@%s' % source_domain | ||||||
|  |         auth = HTTPSignatureAuth(secret=key.private_pem(), key_id=acct, | ||||||
|  |                                  algorithm='rsa-sha256') | ||||||
|  | 
 | ||||||
|  |         # deliver source object to target actor's inbox. | ||||||
|  |         headers = { | ||||||
|  |             'Content-Type': activitypub.CONTENT_TYPE_AS, | ||||||
|  |             # required for HTTP Signature | ||||||
|  |             # https://tools.ietf.org/html/draft-cavage-http-signatures-07#section-2.1.3 | ||||||
|  |             'Date': datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT'), | ||||||
|  |         } | ||||||
|         resp = common.requests_post( |         resp = common.requests_post( | ||||||
|             urlparse.urljoin(target, inbox_url), json=source_obj, |             urlparse.urljoin(target, inbox_url), json=source_obj, auth=auth, | ||||||
|             headers={'Content-Type': activitypub.CONTENT_TYPE_AS}, log=True) |             headers=headers, log=True) | ||||||
| 
 | 
 | ||||||
|     def send_salmon(self, source_obj, target_url=None, target_resp=None): |     def send_salmon(self, source_obj, target_url=None, target_resp=None): | ||||||
|         # fetch target HTML page, extract Atom rel-alternate link |         # fetch target HTML page, extract Atom rel-alternate link | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Ryan Barrett
						Ryan Barrett