Revision bef3bf46

b/snf-astakos-app/astakos/im/backends.py
61 61
    according to the INVITATIONS_ENABLED setting
62 62
    (if True returns ``astakos.im.backends.InvitationsBackend`` and if False
63 63
    returns ``astakos.im.backends.SimpleBackend``).
64
    
64

  
65 65
    If the backend cannot be located ``django.core.exceptions.ImproperlyConfigured``
66 66
    is raised.
67 67
    """
......
93 93
        """
94 94
        self.request = request
95 95
        self.invitation = get_invitation(request)
96
    
96

  
97 97
    def get_signup_form(self, provider):
98 98
        """
99
        Returns the form class name 
99
        Returns the form class name
100 100
        """
101 101
        invitation = self.invitation
102 102
        initial_data = self.get_signup_initial_data(provider)
......
104 104
        main = provider.capitalize() if provider == 'local' else 'ThirdParty'
105 105
        suffix  = 'UserCreationForm'
106 106
        formclass = '%s%s%s' % (prefix, main, suffix)
107
        return globals()[formclass](initial_data, ip=self.request.META['REMOTE_ADDR'])
108
    
107
        ip = self.request.META.get('REMOTE_ADDR',
108
                self.request.META.get('HTTP_X_REAL_IP', None))
109
        return globals()[formclass](initial_data, ip=ip)
110

  
109 111
    def get_signup_initial_data(self, provider):
110 112
        """
111 113
        Returns the necassary registration form depending the user is invited or not
112
        
114

  
113 115
        Throws Invitation.DoesNotExist in case ``code`` is not valid.
114 116
        """
115 117
        request = self.request
......
128 130
            if provider == request.POST.get('provider', ''):
129 131
                initial_data = request.POST
130 132
        return initial_data
131
    
133

  
132 134
    def _is_preaccepted(self, user):
133 135
        """
134 136
        If there is a valid, not-consumed invitation code for the specific user
......
141 143
            invitation.consume()
142 144
            return True
143 145
        return False
144
    
146

  
145 147
    @transaction.commit_manually
146 148
    def signup(self, form, admin_email_template_name='im/admin_notification.txt'):
147 149
        """
......
149 151
        (has a valid invitation code) the user is activated and if the request
150 152
        param ``next`` is present redirects to it.
151 153
        In any other case the method returns the action status and a message.
152
        
154

  
153 155
        The method uses commit_manually decorator in order to ensure the user
154 156
        will be created only if the procedure has been completed successfully.
155 157
        """
......
170 172
        except socket.error, e:
171 173
            status = messages.ERROR
172 174
            message = _(e.strerror)
173
        
175

  
174 176
        # rollback in case of error
175 177
        if status == messages.ERROR:
176 178
            transaction.rollback()
......
186 188
    """
187 189
    def __init__(self, request):
188 190
        self.request = request
189
    
191

  
190 192
    def get_signup_form(self, provider):
191 193
        """
192 194
        Returns the form class name
......
199 201
        if request.method == 'POST':
200 202
            if provider == request.POST.get('provider', ''):
201 203
                initial_data = request.POST
202
        return globals()[formclass](initial_data, ip=self.request.META['REMOTE_ADDR'])
203
    
204
        ip = self.request.META.get('REMOTE_ADDR',
205
                self.request.META.get('HTTP_X_REAL_IP', None))
206
        return globals()[formclass](initial_data, ip=ip)
207

  
204 208
    @transaction.commit_manually
205 209
    def signup(self, form, email_template_name='im/activation_email.txt', admin_email_template_name='im/admin_notification.txt'):
206 210
        """
207 211
        Creates an inactive user account and sends a verification email.
208
        
212

  
209 213
        The method uses commit_manually decorator in order to ensure the user
210 214
        will be created only if the procedure has been completed successfully.
211
        
215

  
212 216
        ** Arguments **
213
        
217

  
214 218
        ``email_template_name``
215 219
            A custom template for the verification email body to use. This is
216 220
            optional; if not specified, this will default to
217 221
            ``im/activation_email.txt``.
218
        
222

  
219 223
        ** Templates **
220 224
            im/activation_email.txt or ``email_template_name`` keyword argument
221
        
225

  
222 226
        ** Settings **
223
        
227

  
224 228
        * DEFAULT_CONTACT_EMAIL: service support email
225 229
        * DEFAULT_FROM_EMAIL: from email
226 230
        """
......
242 246
                status = messages.ERROR
243 247
                name = 'strerror'
244 248
                message = getattr(e, name) if hasattr(e, name) else e
245
        
249

  
246 250
        # rollback in case of error
247 251
        if status == messages.ERROR:
248 252
            transaction.rollback()
b/snf-astakos-app/astakos/im/target/twitter.py
1 1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
# 
2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
5 5
# conditions are met:
6
# 
6
#
7 7
#   1. Redistributions of source code must retain the above
8 8
#      copyright notice, this list of conditions and the following
9 9
#      disclaimer.
10
# 
10
#
11 11
#   2. Redistributions in binary form must reproduce the above
12 12
#      copyright notice, this list of conditions and the following
13 13
#      disclaimer in the documentation and/or other materials
14 14
#      provided with the distribution.
15
# 
15
#
16 16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
......
25 25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
28
#
29 29
# The views and conclusions contained in the software and
30 30
# documentation are those of the authors and should not be
31 31
# interpreted as representing official policies, either expressed
......
49 49
from astakos.im.settings import TWITTER_KEY, TWITTER_SECRET, INVITATIONS_ENABLED, IM_MODULES
50 50

  
51 51
# It's probably a good idea to put your consumer's OAuth token and
52
# OAuth secret into your project's settings. 
52
# OAuth secret into your project's settings.
53 53
consumer = oauth.Consumer(TWITTER_KEY, TWITTER_SECRET)
54 54
client = oauth.Client(consumer)
55 55

  
......
72 72
    request_token = dict(urlparse.parse_qsl(content))
73 73
    if request.GET.get('next'):
74 74
        request_token['next'] = request.GET['next']
75
    
75

  
76 76
    # Step 2. Store the request token in a session for later use.
77 77
    response = HttpResponse()
78 78
    request.session['Twitter-Request-Token'] = value=json.dumps(request_token)
79
    
79

  
80 80
    # Step 3. Redirect the user to the authentication URL.
81 81
    url = "%s?oauth_token=%s" % (authenticate_url, request_token['oauth_token'])
82 82
    response['Location'] = url
83 83
    response.status_code = 302
84
    
84

  
85 85
    return response
86 86

  
87 87
@requires_anonymous
......
91 91
    if not data:
92 92
        raise Exception("Request token cookie not found.")
93 93
    del request.session['Twitter-Request-Token']
94
    
94

  
95 95
    request_token = json.loads(data)
96 96
    if not hasattr(request_token, '__getitem__'):
97 97
        raise BadRequest('Invalid data formating')
......
101 101
    except:
102 102
        raise BadRequest('Invalid request token cookie formatting')
103 103
    client = oauth.Client(consumer, token)
104
    
104

  
105 105
    # Step 2. Request the authorized access token from Twitter.
106 106
    resp, content = client.request(access_token_url, "GET")
107 107
    if resp['status'] != '200':
108 108
        raise Exception("Invalid response from Twitter.")
109
    
109

  
110 110
    """
111 111
    This is what you'll get back from Twitter. Note that it includes the
112 112
    user's user_id and screen_name.
113 113
    {
114 114
        'oauth_token_secret': 'IcJXPiJh8be3BjDWW50uCY31chyhsMHEhqJVsphC3M',
115
        'user_id': '120889797', 
115
        'user_id': '120889797',
116 116
        'oauth_token': '120889797-H5zNnM3qE0iFoTTpNEHIz3noL9FKzXiOxwtnyVOD',
117 117
        'screen_name': 'heyismysiteup'
118 118
    }
119 119
    """
120 120
    access_token = dict(urlparse.parse_qsl(content))
121
    
121

  
122 122
    # Step 3. Lookup the user or create them if they don't exist.
123
    
123

  
124 124
    # When creating the user I just use their screen_name@twitter.com
125 125
    # for their email and the oauth_token_secret for their password.
126
    # These two things will likely never be used. Alternatively, you 
127
    # can prompt them for their email here. Either way, the password 
126
    # These two things will likely never be used. Alternatively, you
127
    # can prompt them for their email here. Either way, the password
128 128
    # should never be used.
129 129
    screen_name = access_token['screen_name']
130 130
    next = request_token.get('next')
131
    
131

  
132 132
    # check first if user with that email is registered
133 133
    # and if not create one
134 134
    user = None
135 135
    email = request.session.pop('email')
136
    
136

  
137 137
    if email: # signup mode
138
        if not reserved_screen_name(screen_name): 
138
        if not reserved_screen_name(screen_name):
139 139
            try:
140 140
                user = AstakosUser.objects.get(email = email)
141 141
            except AstakosUser.DoesNotExist, e:
......
166 166
            return prepare_response(request, user, next)
167 167
        elif user and not user.is_active:
168 168
            messages.add_message(request, messages.ERROR, 'Inactive account: %s' % user.email)
169
    ip = request.META.get('REMOTE_ADDR',
170
            request.META.get('HTTP_X_REAL_IP', None))
169 171
    return render_response(login_template,
170
                   form = LocalUserCreationForm(ip=request.META['REMOTE_ADDR']),
172
                   form = LocalUserCreationForm(ip=ip),
171 173
                   context_instance=get_context(request, extra_context))
172 174

  
173 175
def reserved_screen_name(screen_name):
......
178 180
    except AstakosUser.DoesNotExist, e:
179 181
        return False
180 182

  
181
def create_user(request, form, backend=None, post_data={}, next = None, on_failure='im/signup.html', on_success='im/signup_complete.html', extra_context={}): 
183
def create_user(request, form, backend=None, post_data={}, next = None, on_failure='im/signup.html', on_success='im/signup_complete.html', extra_context={}):
182 184
    """
183 185
    Create a user.
184
    
186

  
185 187
    The user activation will be delegated to the backend specified by the ``backend`` keyword argument
186 188
    if present, otherwise to the ``astakos.im.backends.InvitationBackend``
187 189
    if settings.ASTAKOS_INVITATIONS_ENABLED is True or ``astakos.im.backends.SimpleBackend`` if not
188 190
    (see backends);
189
    
191

  
190 192
    Upon successful user creation if ``next`` url parameter is present the user is redirected there
191 193
    otherwise renders the ``on_success`` template (if exists) or im/signup_complete.html.
192
    
194

  
193 195
    On unsuccessful creation, renders the ``on_failure`` template (if exists) or im/signup.html with an error message.
194
    
196

  
195 197
    **Arguments**
196
    
198

  
197 199
    ``on_failure``
198 200
        A custom template to render in case of failure. This is optional;
199 201
        if not specified, this will default to ``im/signup.html``.
200
    
202

  
201 203
    ``on_success``
202 204
        A custom template to render in case of success. This is optional;
203 205
        if not specified, this will default to ``im/signup_complete.html``.
204
    
206

  
205 207
    ``extra_context``
206 208
        An dictionary of variables to add to the template context.
207
    
209

  
208 210
    **Template:**
209
    
211

  
210 212
    im/signup.html or ``on_failure`` keyword argument.
211 213
    im/signup_complete.html or ``on_success`` keyword argument.
212 214
    """
......
230 232
        messages.add_message(request, messages.ERROR, e)
231 233
    for provider in IM_MODULES:
232 234
        extra_context['%s_form' % provider] = backend.get_signup_form(provider)
235
    ip = request.META.get('REMOTE_ADDR',
236
            request.META.get('HTTP_X_REAL_IP', None))
233 237
    return render_response(on_failure,
234
                           form = LocalUserCreationForm(ip=request.META['REMOTE_ADDR']),
235
                           context_instance=get_context(request, extra_context))
238
                           form = LocalUserCreationForm(ip=ip),
239
                           context_instance=get_context(request, extra_context))

Also available in: Unified diff