This repository has been archived by the owner on Feb 22, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 103
/
core.py
143 lines (101 loc) · 4.18 KB
/
core.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# -*- coding: utf-8 -*-
"""
flask.ext.social.core
~~~~~~~~~~~~~~~~~~~~~
This module contains the Flask-Social core
:copyright: (c) 2012 by Matt Wright.
:license: MIT, see LICENSE for more details.
"""
from importlib import import_module
from flask import current_app
from flask_oauthlib.client import OAuthRemoteApp as BaseRemoteApp
from flask.ext.security import current_user
from werkzeug.local import LocalProxy
from .utils import get_config, update_recursive
from .views import create_blueprint
_security = LocalProxy(lambda: current_app.extensions['security'])
_social = LocalProxy(lambda: current_app.extensions['social'])
_datastore = LocalProxy(lambda: _social.datastore)
_logger = LocalProxy(lambda: current_app.logger)
default_config = {
'SOCIAL_BLUEPRINT_NAME': 'social',
'SOCIAL_URL_PREFIX': None,
'SOCIAL_CONNECT_ALLOW_VIEW': '/',
'SOCIAL_CONNECT_DENY_VIEW': '/',
'SOCIAL_POST_OAUTH_CONNECT_SESSION_KEY': 'post_oauth_connect_url',
'SOCIAL_POST_OAUTH_LOGIN_SESSION_KEY': 'post_oauth_login_url',
'SOCIAL_APP_URL': 'http://localhost'
}
class OAuthRemoteApp(BaseRemoteApp):
def __init__(self, id, module, install, *args, **kwargs):
BaseRemoteApp.__init__(self, None, **kwargs)
self.id = id
self.module = module
def get_connection(self):
return _social.datastore.find_connection(provider_id=self.id,
user_id=current_user.id)
def get_api(self):
module = import_module(self.module)
connection = self.get_connection()
if connection is None:
return None
return module.get_api(connection=connection,
consumer_key=self.consumer_key,
consumer_secret=self.consumer_secret)
def _get_state(app, datastore, providers, **kwargs):
config = get_config(app)
for key in providers.keys():
config.pop(key.upper())
for key, value in config.items():
kwargs[key.lower()] = value
kwargs.update(dict(
app=app,
datastore=datastore,
providers=providers))
return _SocialState(**kwargs)
class _SocialState(object):
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key.lower(), value)
def __getattr__(self, name):
try:
return self.providers[name]
except KeyError:
msg = "'_SocialState' object has no attribute '%s'" % name
raise AttributeError(msg)
def _get_token():
# Social doesn't use the builtin remote method calls feature of the
# Flask-OAuth extension so we don't need to return a token. This does,
# however, need to be configured
return None
class Social(object):
def __init__(self, app=None, datastore=None):
self.app = app
self.datastore = datastore
if app is not None and datastore is not None:
self._state = self.init_app(app, datastore)
def init_app(self, app, datastore=None):
"""Initialize the application with the Social extension
:param app: The Flask application
:param datastore: Connection datastore instance
"""
datastore = datastore or self.datastore
for key, value in default_config.items():
app.config.setdefault(key, value)
providers = dict()
for key, config in app.config.items():
if not key.startswith('SOCIAL_') or config is None or key in default_config:
continue
suffix = key.lower().replace('social_', '')
default_module_name = 'flask_social.providers.%s' % suffix
module_name = config.get('module', default_module_name)
module = import_module(module_name)
config = update_recursive(module.config, config)
providers[config['id']] = OAuthRemoteApp(**config)
providers[config['id']].tokengetter(_get_token)
state = _get_state(app, datastore, providers)
app.register_blueprint(create_blueprint(state, __name__))
app.extensions['social'] = state
return state
def __getattr__(self, name):
return getattr(self._state, name, None)