--- a/opensourceprojects/controllers.py
+++ b/opensourceprojects/controllers.py
@@ -1,3 +1,175 @@
-class RootController:
- pass
+import allura.tasks.mail_tasks
+from allura.controllers.root import RootController as AlluraRootController
+from allura.controllers.auth import AuthController
+from allura.lib.decorators import require_post
+from allura.lib.widgets import forms
+from allura import model as M
+from allura.lib import plugin
+
+from tg import expose, session, flash, redirect, validate, config
+from tg.decorators import with_trailing_slash, without_trailing_slash
+from pylons import c, g, request, response
+
+import ew as ew_core
+import ew.jinja2_ew as ew
+from allura.lib import validators as V
+from formencode import validators as fev
+import formencode
+from allura.lib import helpers as h
+import string, random, os
+from hashlib import sha256
+import logging
+
+log = logging.getLogger(__name__)
+
+class OSPRegistrationForm(forms.ForgeForm):
+ template = 'jinja:opensourceprojects:templates/widgets/forge_form.html'
+ class fields(ew_core.NameList):
+ display_name = ew.TextField(
+ label='Display Name',
+ validator=fev.UnicodeString(not_empty=True),
+ attrs={'placeholder':'Display Name', 'class':'displayname'},
+ show_label=False
+ )
+ username = ew.TextField(
+ label='Desired Username',
+ validator=fev.Regex(h.re_path_portion, not_empty=True),
+ attrs={'placeholder':'Username', 'class':'username'},
+ show_label=False
+ )
+ username.validator._messages['invalid'] = (
+ 'Usernames can include letters, numbers, and dashes, but must start with a letter' )
+ email = ew.TextField(
+ label = 'Email Address',
+ validator=fev.Email(not_empty=True),
+ attrs={'placeholder':'Email Address', 'class':'email'},
+ show_label=False
+ )
+
+ @ew_core.core.validator
+ def to_python(self, value, state):
+ d = super(OSPRegistrationForm, self).to_python(value, state)
+ value['username'] = username = value['username'].lower()
+ if M.User.by_username(username):
+ raise formencode.Invalid('That username is already taken. Please choose another.',
+ value, state)
+
+ if M.EmailAddress.query.get(_id=value['email'].lower(), confirmed=True):
+ raise formencode.Invalid('That email address is already taken. Please choose another.',
+ value, state)
+
+ return d
+
+form = OSPRegistrationForm(action='/auth2/save_new', submit_text='Sign Up')
+
+class OSPAuthController(AuthController):
+ """
+ This Auth controller modifies account registration
+ """
+
+ @expose('jinja:opensourceprojects:templates/create_account.html')
+ def create_account(self, **kw):
+ c.form = form
+ return dict()
+
+ @expose()
+ @require_post()
+ @validate(form, error_handler=create_account)
+ def save_new(self, display_name=None, username=None, email=None, **kw):
+ pw = OSPAuthController.random_pass(20)
+ user = M.User.register(
+ dict(username=username,
+ display_name=display_name,
+ password=pw,
+ disabled=True))
+
+ user.email_addresses.append(email)
+ em = M.EmailAddress.upsert(str(email))
+ em.claimed_by_user_id=user._id
+ self.send_account_link(em, pw)
+ flash('User "%s" registered, check you email for confirmation' % user.get_pref('display_name'))
+ redirect('/')
+
+ @staticmethod
+ def send_account_link(email, passwd):
+ email.nonce = sha256(os.urandom(10)).hexdigest()
+ log.info('Sending verification link to %s', email._id)
+ text = '''
+You are receiving this email, to confirm the creationg of the account
+%s at opensourceprojects.eu.
+
+To verify the account please visit the following URL:
+
+ %s
+
+Your password for this account is
+
+ %s
+
+If you did not request this account, please ignore this email.
+
+''' % (email.claimed_by_user().username, g.url('/auth2/verify_acct', a=email.nonce), passwd)
+
+ allura.tasks.mail_tasks.sendmail.post(
+ destinations=[email._id],
+ fromaddr=email._id,
+ reply_to='',
+ subject='OpensourceProjects.eu: Account creation',
+ message_id=h.gen_message_id(),
+ text=text)
+
+ @expose('jinja:opensourceprojects:templates/verify_acct.html')
+ def verify_acct(self, a):
+ """
+ Verify an account using an email token
+ """
+ addr = M.EmailAddress.query.get(nonce=a)
+ if not addr:
+ flash('Unknown verification link', 'error')
+ redirect('/')
+
+ addr.confirmed = True
+ user = addr.claimed_by_user()
+ user.disabled = False
+ return dict(username=user.username)
+
+ @staticmethod
+ def random_pass(size=8, chars=string.ascii_letters + string.digits):
+ """
+ Generate a random password
+ """
+ return ''.join(random.choice(chars) for i in range(size))
+
+
+class RootController(AlluraRootController):
+
+ """
+ The root controller for OpenSourceProjects.eu
+
+ Add the following to the .ini config file to enable
+ this root.
+
+ [app:main]
+ override_root = opensourceprojects
+
+ This controller adds:
+ * An about page
+ * A new auth controller
+ * A new front page
+ """
+
+# auth = OSPAuthController()
+ auth2 = OSPAuthController()
+
+ @expose('jinja:opensourceprojects:templates/about.html')
+ def about(self):
+ return dict()
+
+ @expose('jinja:opensourceprojects:templates/frontpage.html')
+ @with_trailing_slash
+ def index(self, **kw):
+ return dict(form=OSPRegistrationForm(submit_text='Sign Up now!', action='/auth2/save_new'))
+
+
+