Skip to content
This repository has been archived by the owner on Apr 28, 2020. It is now read-only.

Commit

Permalink
Merge pull request #53 from hasgeek/crudapi-mitesh
Browse files Browse the repository at this point in the history
Testing environment bootstrapping
  • Loading branch information
jace committed Aug 20, 2013
2 parents a4ab81d + 82fc2e7 commit 7147a31
Show file tree
Hide file tree
Showing 14 changed files with 279 additions and 99 deletions.
12 changes: 12 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
language: python
python:
- "2.7"
- "pypy"
install:
- pip install -r requirements.txt --use-mirrors
- pip install -r test_requirements.txt --use-mirrors
script:
- nosetests tests --with-coverage
notifications:
email: false
irc: "irc.freenode.net#hasgeek-dev"
101 changes: 101 additions & 0 deletions instance/testing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
from flask import Markup

#: The title of this site
SITE_TITLE = 'Lastuser'

#: Support contact email
SITE_SUPPORT_EMAIL = 'test@example.com'

#: TypeKit code for fonts
TYPEKIT_CODE = ''

#: Google Analytics code UA-XXXXXX-X
GA_CODE = ''

#: Database backend
SQLALCHEMY_BINDS = {
'lastuser': 'postgresql://postgres@localhost/myapp_test',
}

#: Cache type
CACHE_TYPE = 'redis'

#: Secret key
SECRET_KEY = 'random_string_here'

#: Timezone
TIMEZONE = 'Asia/Calcutta'

#: Reserved usernames
#: Add to this list but do not remove any unless you want to break
#: the website
RESERVED_USERNAMES = set([
'app',
'apps',
'auth',
'client',
'confirm',
'login',
'logout',
'new',
'profile',
'reset',
'register',
'token',
'organizations',
])

#: Mail settings
#: MAIL_FAIL_SILENTLY : default True
#: MAIL_SERVER : default 'localhost'
#: MAIL_PORT : default 25
#: MAIL_USE_TLS : default False
#: MAIL_USE_SSL : default False
#: MAIL_USERNAME : default None
#: MAIL_PASSWORD : default None
#: DEFAULT_MAIL_SENDER : default None
MAIL_FAIL_SILENTLY = False
MAIL_SERVER = 'localhost'
DEFAULT_MAIL_SENDER = ('Lastuser', 'test@example.com')
MAIL_DEFAULT_SENDER = DEFAULT_MAIL_SENDER # For new versions of Flask-Mail

#: Logging: recipients of error emails
ADMINS = []

#: Log file
LOGFILE = 'error.log'

#: Use SSL for some URLs
USE_SSL = False

#: Twitter integration
OAUTH_TWITTER_KEY = ''
OAUTH_TWITTER_SECRET = ''

#: GitHub integration
OAUTH_GITHUB_KEY = ''
OAUTH_GITHUB_SECRET = ''

#: Recaptcha for the registration form
RECAPTCHA_USE_SSL = USE_SSL
RECAPTCHA_PUBLIC_KEY = ''
RECAPTCHA_PRIVATE_KEY = ''
RECAPTCHA_OPTIONS = ''

#: SMS gateways
SMS_SMSGUPSHUP_MASK = ''
SMS_SMSGUPSHUP_USER = ''
SMS_SMSGUPSHUP_PASS = ''

#: Messages (text or HTML)
MESSAGE_FOOTER = Markup('Copyright &copy; <a href="http://hasgeek.com/">HasGeek</a>. Powered by <a href="https://github.com/hasgeek/lastuser" title="GitHub project page">Lastuser</a>, open source software from <a href="https://github.com/hasgeek">HasGeek</a>.')
USERNAME_REASON = ''
EMAIL_REASON = 'Please provide an email address to complete your profile'
BIO_REASON = ''
TIMEZONE_REASON = 'Dates and times will be shown in your preferred timezone'
ORG_NAME_REASON = u"Your company’s name as it will appear in the URL. Letters, numbers and dashes only"
ORG_TITLE_REASON = u"Your organization’s given name, preferably without legal suffixes"
ORG_DESCRIPTION_REASON = u"A few words about your organization (optional). Plain text only"
LOGIN_MESSAGE_1 = ""
LOGIN_MESSAGE_2 = ""
30 changes: 16 additions & 14 deletions lastuser_oauth/forms/login.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-

from flask import Markup, url_for, current_app
import wtforms
import wtforms.fields.html5
import flask.ext.wtf as wtf
from coaster import valid_username
from baseframe.forms import Form
Expand All @@ -9,46 +11,46 @@


class LoginForm(Form):
username = wtf.TextField('Username or Email', validators=[wtf.Required()])
password = wtf.PasswordField('Password', validators=[wtf.Required()])
username = wtforms.TextField('Username or Email', validators=[wtforms.validators.Required()])
password = wtforms.PasswordField('Password', validators=[wtforms.validators.Required()])

def validate_username(self, field):
existing = getuser(field.data)
if existing is None:
raise wtf.ValidationError("User does not exist")
raise wtforms.ValidationError("User does not exist")

def validate_password(self, field):
user = getuser(self.username.data)
if user is None or not user.password_is(field.data):
raise wtf.ValidationError("Incorrect password")
raise wtforms.ValidationError("Incorrect password")
self.user = user


class RegisterForm(Form):
fullname = wtf.TextField('Full name', validators=[wtf.Required()])
email = wtf.html5.EmailField('Email address', validators=[wtf.Required(), wtf.Email()])
username = wtf.TextField('Username', validators=[wtf.Required()],
fullname = wtforms.TextField('Full name', validators=[wtforms.validators.Required()])
email = wtforms.fields.html5.EmailField('Email address', validators=[wtforms.validators.Required(), wtforms.validators.Email()])
username = wtforms.TextField('Username', validators=[wtforms.validators.Required()],
description="Single word that can contain letters, numbers and dashes")
password = wtf.PasswordField('Password', validators=[wtf.Required()])
confirm_password = wtf.PasswordField('Confirm password',
validators=[wtf.Required(), wtf.EqualTo('password')])
password = wtforms.PasswordField('Password', validators=[wtforms.validators.Required()])
confirm_password = wtforms.PasswordField('Confirm password',
validators=[wtforms.validators.Required(), wtforms.validators.EqualTo('password')])
recaptcha = wtf.RecaptchaField('Are you human?',
description="Type both words into the text box to prove that you are a human and not a computer program")

def validate_username(self, field):
if field.data in current_app.config['RESERVED_USERNAMES']:
raise wtf.ValidationError, "That name is reserved"
raise wtforms.ValidationError, "That name is reserved"
if not valid_username(field.data):
raise wtf.ValidationError(u"Invalid characters in name. Names must be made of ‘a-z’, ‘0-9’ and ‘-’, without trailing dashes")
raise wtforms.ValidationError(u"Invalid characters in name. Names must be made of ‘a-z’, ‘0-9’ and ‘-’, without trailing dashes")
existing = User.query.filter_by(username=field.data).first()
if existing is not None:
raise wtf.ValidationError("That username is taken")
raise wtforms.ValidationError("That username is taken")

def validate_email(self, field):
field.data = field.data.lower() # Convert to lowercase
existing = UserEmail.query.filter_by(email=field.data).first()
if existing is not None:
raise wtf.ValidationError(Markup(
raise wtforms.ValidationError(Markup(
'This email address is already registered. Do you want to <a href="%s">login</a> instead?'
% url_for('.login')
))
49 changes: 25 additions & 24 deletions lastuser_oauth/forms/profile.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-

from flask import g, current_app
import flask.ext.wtf as wtf
import wtforms
import wtforms.fields.html5
from coaster import valid_username, sorted_timezones
from baseframe.forms import Form, ValidEmailDomain

Expand All @@ -11,48 +12,48 @@


class PasswordResetRequestForm(Form):
username = wtf.TextField('Username or Email', validators=[wtf.Required()])
username = wtforms.TextField('Username or Email', validators=[wtforms.validators.Required()])

def validate_username(self, field):
user = getuser(field.data)
if user is None:
raise wtf.ValidationError("Could not find a user with that id")
raise wtforms.ValidationError("Could not find a user with that id")
self.user = user


class PasswordResetForm(Form):
username = wtf.TextField('Username or Email', validators=[wtf.Required()],
username = wtforms.TextField('Username or Email', validators=[wtforms.validators.Required()],
description="Please reconfirm your username or email address")
password = wtf.PasswordField('New password', validators=[wtf.Required()])
confirm_password = wtf.PasswordField('Confirm password',
validators=[wtf.Required(), wtf.EqualTo('password')])
password = wtforms.PasswordField('New password', validators=[wtforms.validators.Required()])
confirm_password = wtforms.PasswordField('Confirm password',
validators=[wtforms.validators.Required(), wtforms.validators.EqualTo('password')])

def validate_username(self, field):
user = getuser(field.data)
if user is None or user != self.user:
raise wtf.ValidationError(
raise wtforms.ValidationError(
"This username or email does not match the user the reset code is for")


class PasswordChangeForm(Form):
old_password = wtf.PasswordField('Current password', validators=[wtf.Required()])
password = wtf.PasswordField('New password', validators=[wtf.Required()])
confirm_password = wtf.PasswordField('Confirm password',
validators=[wtf.Required(), wtf.EqualTo('password')])
old_password = wtforms.PasswordField('Current password', validators=[wtforms.validators.Required()])
password = wtforms.PasswordField('New password', validators=[wtforms.validators.Required()])
confirm_password = wtforms.PasswordField('Confirm password',
validators=[wtforms.validators.Required(), wtforms.validators.EqualTo('password')])

def validate_old_password(self, field):
if g.user is None:
raise wtf.ValidationError, "Not logged in"
raise wtforms.ValidationError, "Not logged in"
if not g.user.password_is(field.data):
raise wtf.ValidationError, "Incorrect password"
raise wtforms.ValidationError, "Incorrect password"


class ProfileForm(Form):
fullname = wtf.TextField('Full name', validators=[wtf.Required()])
email = wtf.html5.EmailField('Email address', validators=[wtf.Required(), wtf.Email(), ValidEmailDomain()])
username = wtf.TextField('Username', validators=[wtf.Required()])
description = wtf.TextAreaField('Bio')
timezone = wtf.SelectField('Timezone', validators=[wtf.Required()], choices=timezones)
fullname = wtforms.TextField('Full name', validators=[wtforms.validators.Required()])
email = wtforms.fields.html5.EmailField('Email address', validators=[wtforms.validators.Required(), wtforms.validators.Email(), ValidEmailDomain()])
username = wtforms.TextField('Username', validators=[wtforms.validators.Required()])
description = wtforms.TextAreaField('Bio')
timezone = wtforms.SelectField('Timezone', validators=[wtforms.validators.Required()], choices=timezones)

def __init__(self, *args, **kwargs):
super(ProfileForm, self).__init__(*args, **kwargs)
Expand All @@ -65,22 +66,22 @@ def validate_username(self, field):
# return
field.data = field.data.lower() # Usernames can only be lowercase
if not valid_username(field.data):
raise wtf.ValidationError("Usernames can only have alphabets, numbers and dashes (except at the ends)")
raise wtforms.ValidationError("Usernames can only have alphabets, numbers and dashes (except at the ends)")
if field.data in current_app.config['RESERVED_USERNAMES']:
raise wtf.ValidationError("This name is reserved")
raise wtforms.ValidationError("This name is reserved")
existing = User.query.filter_by(username=field.data).first()
if existing is not None and existing.id != self.edit_id:
raise wtf.ValidationError("This username is taken")
raise wtforms.ValidationError("This username is taken")
existing = Organization.query.filter_by(name=field.data).first()
if existing is not None:
raise wtf.ValidationError("This username is taken")
raise wtforms.ValidationError("This username is taken")

# TODO: Move to function and place before ValidEmailDomain()
def validate_email(self, field):
field.data = field.data.lower() # Convert to lowercase
existing = UserEmail.query.filter_by(email=field.data).first()
if existing is not None and existing.user != self.edit_obj:
raise wtf.ValidationError("This email address has been claimed by another user.")
raise wtforms.ValidationError("This email address has been claimed by another user.")


class ProfileMergeForm(Form):
Expand Down
5 changes: 3 additions & 2 deletions lastuser_oauth/providers/openid.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from __future__ import absolute_import

from flask import Markup, session
import flask.ext.wtf as wtf
import wtforms
import wtforms.fields.html5
from baseframe.forms import Form
from lastuser_core.registry import LoginProvider
from ..views.login import oid
Expand All @@ -13,7 +14,7 @@


class OpenIdForm(Form):
openid = wtf.html5.URLField('Login with OpenID', validators=[wtf.Required()], default='http://',
openid = wtforms.fields.html5.URLField('Login with OpenID', validators=[wtforms.validators.Required()], default='http://',
description=Markup("Don't forget the <code>http://</code> or <code>https://</code> prefix"))


Expand Down
Loading

0 comments on commit 7147a31

Please sign in to comment.