From 13d255f8c499394c20e1ff3b2537ff524e0651f1 Mon Sep 17 00:00:00 2001
From: Aypac <github@aypac.de>
Date: Mon, 10 Jun 2019 15:31:49 +0200
Subject: [PATCH 1/4] Add meetup.com as examples

---
 docs/index.rst      | 12 +++++++-----
 example/example.ini |  7 +++++++
 example/server.py   | 28 ++++++++++++++++++++++++++--
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/docs/index.rst b/docs/index.rst
index 5d479ea..7a1cb6f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -55,16 +55,18 @@ sanction has been tested with the following OAuth2 providers:
 * StackExchange_
 * Instagram_
 * DeviantArt_
+* Meetup.com_
 
-.. _Facebook: https://developers.facebook.com/docs/authentication/
+.. _Facebook: https://developers.facebook.com/docs/authentication
 .. _Google: https://developers.google.com/accounts/docs/OAuth2
 .. _Foursquare: https://developer.foursquare.com/overview/auth
-.. _GitHub: http://developer.github.com/v3/oauth/
-.. _Instagram: http://instagram.com/developer/
+.. _GitHub: http://developer.github.com/v3/oauth
+.. _Instagram: http://instagram.com/developer
 .. _bitly: http://dev.bitly.com/api.html
 .. _StackExchange: https://api.stackexchange.com/docs
-.. _Instagram: http://instagram.com/developer/
-.. _DeviantArt: http://www.deviantart.com/developers/oauth2
+.. _Instagram: http://instagram.com/developer
+.. _DeviantArt: https://www.deviantart.com/developers/authentication
+.. _Meetup.com: https://www.meetup.com/meetup_api/auth/#oauth2-resources
 
 :note: The intention of the sanction library is to not only provide accessibility
        to the OAuth2 authorization code flow, but all server-side flows. However,
diff --git a/example/example.ini b/example/example.ini
index 46fa229..c84a81c 100644
--- a/example/example.ini
+++ b/example/example.ini
@@ -5,11 +5,13 @@ google.redirect_uri = http://localhost/login/google
 google.scope = https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile http://www.blogger.com/feeds/
 google.access_type = online
 
+# Facebook client is broken, need to request a new one!
 facebook.client_id = 285809954824916
 facebook.client_secret = d985f6a3ecaffd11d61b3cd026b8753a
 facebook.redirect_uri = http://localhost/login/facebook
 facebook.scope = read_stream,email,publish_stream
 
+# Foursquare client is broken, need to request a new one!
 foursquare.client_id = RNFFUX2WE5LDDD1NE2MUKGD5CESXKX0U4DJXPGDN24O0KENY
 foursquare.client_secret = OC5CIEMC0EYCBMR3PT1BG0WVPMIZKT1QM2KNA5ARC2GGWZRE
 foursquare.redirect_uri = http://localhost/login/foursquare
@@ -31,7 +33,12 @@ stackexchange.client_secret = BzBMVkgaukCaJwe5PCViBA((
 stackexchange.redirect_uri = http://localhost/login/stackexchange
 stackexchange.key = IoYZPCrlYCgBXIuM8VixlA(( 
 
+# Deviantart client is broken, need to request a new one!
 deviantart.client_id = 216
 deviantart.client_secret = aaae25721430bf4231cb47980f273115
 deviantart.redirect_uri = http://localhost/login/deviantart
 
+meetup.client_id = k6on8hhfo415306rfo9tmkepqm
+meetup.client_secret = lprm9ng3c3p5bchasip667vlda
+meetup.redirect_uri = http://localhost/login/meetup
+meetup.scope = basic
\ No newline at end of file
diff --git a/example/server.py b/example/server.py
index cc0f148..de62119 100755
--- a/example/server.py
+++ b/example/server.py
@@ -65,6 +65,8 @@ class Handler(BaseHTTPRequestHandler):
         '/oauth2/stackexchange': 'handle_stackexchange',
         '/login/deviantart': 'handle_deviantart_login',
         '/oauth2/deviantart': 'handle_deviantart',
+        '/login/meetup': 'handle_meetup_login',
+        '/oauth2/meetup': 'handle_meetup',
     }
 
     def do_GET(self):
@@ -94,6 +96,7 @@ def handle_root(self, data):
             <a href='/oauth2/instagram'>Instagram</a>,
             <a href='/oauth2/foursquare'>Foursquare</a>,
             <a href='/oauth2/deviantart'>Deviant Art</a>,
+            <a href='/oauth2/meetup'>Meetup.com</a>,
         '''.encode(ENCODING_UTF8))
 
     def handle_stackexchange(self, data):
@@ -320,6 +323,28 @@ def handle_deviantart_login(self, data):
         self.dump_client(c)
         data = c.request('/user/whoami')
         self.dump_response(data)
+		
+    def handle_meetup(self, data):
+        self.send_response(302)
+        c = Client(auth_endpoint='https://secure.meetup.com/oauth2/authorize',
+                client_id=config['meetup.client_id'])
+        self.send_header('Location', c.auth_uri(
+            scope=config['meetup.scope'],
+            redirect_uri='http://localhost/login/meetup'))
+        self.end_headers()
+
+    @success
+    def handle_meetup_login(self, data):
+        c = Client(token_endpoint='https://secure.meetup.com/oauth2/access',
+            resource_endpoint='https://api.meetup.com',
+            client_id=config['meetup.client_id'],
+            client_secret=config['meetup.client_secret'])
+        c.request_token(code=data['code'],
+            redirect_uri='http://localhost/login/meetup')
+
+        self.dump_client(c)
+        data = c.request('/2/member/self/')
+        self.dump_response(data)
 
 
 if __name__ == '__main__':
@@ -327,5 +352,4 @@ def handle_deviantart_login(self, data):
     server_address = ('', 80)
     server = HTTPServer(server_address, Handler)
     l.info('Starting server on %sport %s \nPress <ctrl>+c to exit' % server_address)
-    server.serve_forever()
-
+server.serve_forever()
\ No newline at end of file

From 5caf135e87caab67feb1c2465f256d5560559357 Mon Sep 17 00:00:00 2001
From: Aypac <github@aypac.de>
Date: Mon, 10 Jun 2019 17:19:26 +0200
Subject: [PATCH 2/4] Sometimes, the response_type shall not be 'code'

---
 sanction/__init__.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sanction/__init__.py b/sanction/__init__.py
index a4946d7..4ed1c6f 100644
--- a/sanction/__init__.py
+++ b/sanction/__init__.py
@@ -76,10 +76,10 @@ def auth_uri(self, redirect_uri=None, scope=None, scope_delim=None,
         :param **kwargs: Any other querystring parameters to be passed to the
                          provider.
         """
-        kwargs.update({
-            'client_id': self.client_id,
-            'response_type': 'code',
-        })
+		
+        kwargs['client_id'] = self.client_id
+		if 'response_type' in kwargs:
+			kwargs['response_type'] = 'code'
 
         if scope is not None:
             kwargs['scope'] = scope

From 068a00697392cb9e776c3f552be5b3fd8b221e1c Mon Sep 17 00:00:00 2001
From: Aypac <github@aypac.de>
Date: Mon, 10 Jun 2019 17:21:14 +0200
Subject: [PATCH 3/4] indentation error

---
 sanction/__init__.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sanction/__init__.py b/sanction/__init__.py
index 4ed1c6f..cac9176 100644
--- a/sanction/__init__.py
+++ b/sanction/__init__.py
@@ -78,8 +78,8 @@ def auth_uri(self, redirect_uri=None, scope=None, scope_delim=None,
         """
 		
         kwargs['client_id'] = self.client_id
-		if 'response_type' in kwargs:
-			kwargs['response_type'] = 'code'
+        if 'response_type' in kwargs:
+            kwargs['response_type'] = 'code'
 
         if scope is not None:
             kwargs['scope'] = scope

From 7c7a40f452865ba933e5a5f58237465e691624c0 Mon Sep 17 00:00:00 2001
From: Aypac <github@aypac.de>
Date: Mon, 10 Jun 2019 17:23:42 +0200
Subject: [PATCH 4/4] fix logic error

---
 sanction/__init__.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sanction/__init__.py b/sanction/__init__.py
index cac9176..edf8553 100644
--- a/sanction/__init__.py
+++ b/sanction/__init__.py
@@ -76,9 +76,9 @@ def auth_uri(self, redirect_uri=None, scope=None, scope_delim=None,
         :param **kwargs: Any other querystring parameters to be passed to the
                          provider.
         """
-		
+        
         kwargs['client_id'] = self.client_id
-        if 'response_type' in kwargs:
+        if not 'response_type' in kwargs:
             kwargs['response_type'] = 'code'
 
         if scope is not None: