Switch to unified view

a/opensourceprojects/controllers.py b/opensourceprojects/controllers.py
1
1
2
class RootController:
2
import allura.tasks.mail_tasks
3
from allura.controllers.root import RootController as AlluraRootController
4
from allura.controllers.auth import AuthController
5
from allura.lib.decorators import require_post
6
from allura.lib.widgets import forms
7
from allura import model as M
8
from allura.lib import plugin
9
10
from tg import expose, session, flash, redirect, validate, config
11
from tg.decorators import with_trailing_slash, without_trailing_slash
12
from pylons import c, g, request, response
13
14
import ew as ew_core
15
import ew.jinja2_ew as ew
16
from allura.lib import validators as V
17
from formencode import validators as fev
18
import formencode
19
from allura.lib import helpers as h
20
import string, random, os
21
from hashlib import sha256
22
import logging
23
24
log = logging.getLogger(__name__)
25
26
class OSPRegistrationForm(forms.ForgeForm):
27
    template = 'jinja:opensourceprojects:templates/widgets/forge_form.html'
28
    class fields(ew_core.NameList):
29
        display_name = ew.TextField(
30
            label='Display Name',
31
            validator=fev.UnicodeString(not_empty=True),
32
            attrs={'placeholder':'Display Name', 'class':'displayname'},
33
            show_label=False
34
            )
35
        username = ew.TextField(
36
            label='Desired Username',
37
            validator=fev.Regex(h.re_path_portion, not_empty=True),
38
            attrs={'placeholder':'Username', 'class':'username'},
39
            show_label=False
40
            )
41
        username.validator._messages['invalid'] = (
42
            'Usernames can include letters, numbers, and dashes, but must start with a letter' )
43
        email = ew.TextField(
44
            label = 'Email Address',
45
            validator=fev.Email(not_empty=True),
46
            attrs={'placeholder':'Email Address', 'class':'email'},
47
            show_label=False
48
            )
49
50
    @ew_core.core.validator
51
    def to_python(self, value, state):
52
        d = super(OSPRegistrationForm, self).to_python(value, state)
53
        value['username'] = username = value['username'].lower()
54
        if M.User.by_username(username):
55
            raise formencode.Invalid('That username is already taken. Please choose another.',
56
                                    value, state)
57
58
        if M.EmailAddress.query.get(_id=value['email'].lower(), confirmed=True):
59
            raise formencode.Invalid('That email address is already taken. Please choose another.',
60
                                    value, state)
61
        
62
        return d
63
64
form = OSPRegistrationForm(action='/auth2/save_new', submit_text='Sign Up')
65
66
class OSPAuthController(AuthController):
67
    """
68
    This Auth controller modifies account registration
69
    """
70
71
    @expose('jinja:opensourceprojects:templates/create_account.html')
72
    def create_account(self, **kw):
73
        c.form = form
74
        return dict()
75
76
    @expose()
77
    @require_post()
78
    @validate(form, error_handler=create_account)
79
    def save_new(self, display_name=None, username=None, email=None, **kw):
80
        pw = OSPAuthController.random_pass(20)
81
        user = M.User.register(
82
            dict(username=username,
83
                 display_name=display_name,
84
                 password=pw,
85
                 disabled=True))
86
87
        user.email_addresses.append(email)
88
        em = M.EmailAddress.upsert(str(email))
89
        em.claimed_by_user_id=user._id
90
        self.send_account_link(em, pw)
91
        flash('User "%s" registered, check you email for confirmation' % user.get_pref('display_name'))
92
        redirect('/')
93
94
    @staticmethod
95
    def send_account_link(email, passwd):
96
        email.nonce = sha256(os.urandom(10)).hexdigest()
97
        log.info('Sending verification link to %s', email._id)
98
        text = '''
99
You are receiving this email, to confirm the creationg of the account
100
%s at opensourceprojects.eu.
101
102
To verify the account please visit the following URL:
103
3
    pass
104
    %s
105
106
Your password for this account is
107
   
108
   %s
109
110
If you did not request this account, please ignore this email.
111
112
''' % (email.claimed_by_user().username, g.url('/auth2/verify_acct', a=email.nonce), passwd)
113
114
        allura.tasks.mail_tasks.sendmail.post(
115
            destinations=[email._id],
116
            fromaddr=email._id,
117
            reply_to='',
118
            subject='OpensourceProjects.eu: Account creation',
119
            message_id=h.gen_message_id(),
120
            text=text)
121
122
    @expose('jinja:opensourceprojects:templates/verify_acct.html')
123
    def verify_acct(self, a):
124
        """
125
        Verify an account using an email token
126
        """
127
        addr = M.EmailAddress.query.get(nonce=a)
128
        if not addr:
129
            flash('Unknown verification link', 'error')
130
            redirect('/')
131
132
        addr.confirmed = True
133
        user = addr.claimed_by_user()
134
        user.disabled = False
135
        return dict(username=user.username)
136
        
137
    @staticmethod
138
    def random_pass(size=8, chars=string.ascii_letters + string.digits):
139
        """
140
        Generate a random password
141
        """
142
        return ''.join(random.choice(chars) for i in range(size))
143
        
144
145
class RootController(AlluraRootController):
146
147
    """
148
    The root controller for OpenSourceProjects.eu
149
    
150
    Add the following to the .ini config file to enable
151
    this root.
152
153
    [app:main]
154
    override_root = opensourceprojects
155
156
    This controller adds:
157
    * An about page
158
    * A new auth controller
159
    * A new front page
160
    """
161
162
#    auth = OSPAuthController()
163
    auth2 = OSPAuthController()
164
165
    @expose('jinja:opensourceprojects:templates/about.html')
166
    def about(self):
167
        return dict()
168
169
    @expose('jinja:opensourceprojects:templates/frontpage.html')
170
    @with_trailing_slash
171
    def index(self, **kw):
172
        return dict(form=OSPRegistrationForm(submit_text='Sign Up now!', action='/auth2/save_new'))
173
174
175