Merge branch 'master' of ssh://git.fedorahosted.org/git/fedora-infrastructure
This commit is contained in:
commit
ce35e3ea23
8 changed files with 126 additions and 129 deletions
|
@ -10,7 +10,7 @@ legal_cla_email = "nobody@fedoraproject.org"
|
|||
email_host = "fedoraproject.org" # as in, web-members@email_host
|
||||
|
||||
gpgexec = "/usr/bin/gpg"
|
||||
gpghome = "/srv/fedora-infrastructure/fas/gnupg"
|
||||
gpghome = "/home/ricky/work/fedora/fedora-infrastructure/fas/gnupg"
|
||||
gpg_fingerprint = "C199 1E25 D00A D200 2D2E 54D1 BF7F 1647 C54E 8410"
|
||||
gpg_passphrase = "m00!s@ysth3c0w"
|
||||
gpg_keyserver = "hkp://subkeys.pgp.net"
|
||||
|
@ -83,7 +83,7 @@ tg.strict_parameters = True
|
|||
server.webpath='/accounts'
|
||||
base_url_filter.on = True
|
||||
base_url_filter.use_x_forwarded_host = True
|
||||
base_url_filter.base_url = "https://publictest3.fedoraproject.org/accounts"
|
||||
base_url_filter.base_url = "http://localhost:8088/accounts"
|
||||
|
||||
# Make the session cookie only return to the host over an SSL link
|
||||
# Disabled for testing.
|
||||
|
|
|
@ -281,8 +281,8 @@ class Group(controllers.Controller):
|
|||
group = Groups.by_name(groupname)
|
||||
|
||||
if not canApplyGroup(person, group, target):
|
||||
# turbogears.flash(_('%(user)s could not apply to %(group)s.') % \
|
||||
# {'user': target.username, 'group': group.name })
|
||||
turbogears.flash(_('%(user)s can not apply to %(group)s.') % \
|
||||
{'user': target.username, 'group': group.name })
|
||||
turbogears.redirect('/group/view/%s' % group.name)
|
||||
return dict()
|
||||
else:
|
||||
|
|
|
@ -247,17 +247,16 @@ class People(SABase):
|
|||
# Only admins can see internal_comments
|
||||
del props['internal_comments']
|
||||
del props['emailtoken']
|
||||
del props['passwordtoken']
|
||||
if identity.current.anonymous:
|
||||
# Anonymous users can't see any of these
|
||||
del props['email']
|
||||
del props['emailtoken']
|
||||
del props['unverified_email']
|
||||
del props['ssh_key']
|
||||
del props['gpg_keyid']
|
||||
del props['affiliation']
|
||||
del props['certificate_serial']
|
||||
del props['password']
|
||||
del props['passwordtoken']
|
||||
del props['password_changed']
|
||||
del props['postal_address']
|
||||
del props['telephone']
|
||||
|
@ -267,7 +266,6 @@ class People(SABase):
|
|||
# Only an admin or the user themselves can see these fields
|
||||
del props['unverified_email']
|
||||
del props['password']
|
||||
del props['passwordtoken']
|
||||
del props['postal_address']
|
||||
del props['password_changed']
|
||||
del props['telephone']
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<h2>${_('Reset Password')}</h2>
|
||||
<form action="${tg.url('/user/sendpass')}" method="post">
|
||||
<form action="${tg.url('/user/sendtoken')}" method="post">
|
||||
<ul>
|
||||
<div class="field"><label for="username">${_('Username:')}</label> <input type="text" id="username" name="username" /></div>
|
||||
<div class="field"><label for="email">${_('Email:')}</label> <input type="text" id="email" name="email" /></div>
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
<p>
|
||||
Do you really want to change your email to: ${person.unverified_email} ?
|
||||
</p>
|
||||
<input type="submit" name="confirmation" id="confirmation" value="${_('Confirm')}" />
|
||||
<input type="submit" value="${_('Cancel')}" />
|
||||
<input type="submit" value="${_('Confirm')}" />
|
||||
<a href="${tg.url('/user/verifyemail/%s/%s/cancel') % (person.username, token)}">${_('Cancel')}</a>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
|
|
22
fas/fas/templates/user/verifypass.html
Normal file
22
fas/fas/templates/user/verifypass.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:py="http://genshi.edgewall.org/"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<xi:include href="../master.html" />
|
||||
<head>
|
||||
<title>${_('Reset Password')}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>${_('Reset Password')}</h2>
|
||||
<form action="${tg.url('/user/setnewpass/%s/%s') % (person.username, token)}" method="post">
|
||||
<ul>
|
||||
<div class="field"><label for="password">${_('New Password:')}</label> <input type="password" id="password" name="password" /></div>
|
||||
<div class="field"><label for="passwordcheck">${_('Confirm Password:')}</label> <input type="password" id="passwordcheck" name="passwordcheck" /></div>
|
||||
<div class="field">
|
||||
<input type="submit" value="${_('Change Password')}" />
|
||||
<a href="${tg.url('/user/verifypass/%s/%s/cancel') % (person.username, token)}">${_('Cancel')}</a>
|
||||
</div>
|
||||
</ul>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
135
fas/fas/user.py
135
fas/fas/user.py
|
@ -125,6 +125,12 @@ class UserSetPassword(validators.Schema):
|
|||
passwordcheck = validators.String
|
||||
chained_validators = [validators.FieldsMatch('password', 'passwordcheck')]
|
||||
|
||||
class UserResetPassword(validators.Schema):
|
||||
# TODO (after we're done with most testing): Add complexity requirements?
|
||||
password = validators.String(min=8)
|
||||
passwordcheck = validators.String
|
||||
chained_validators = [validators.FieldsMatch('password', 'passwordcheck')]
|
||||
|
||||
class UserView(validators.Schema):
|
||||
username = KnownUser
|
||||
|
||||
|
@ -271,8 +277,7 @@ login with your Fedora account first):
|
|||
|
||||
https://admin.fedoraproject.org/accounts/user/verifyemail/%s
|
||||
''') % token
|
||||
emailflash = _(' Your email ')
|
||||
|
||||
emailflash = _(' Before your new email takes effect, you must confirm it. You should receive an email with instructions shortly.')
|
||||
turbomail.enqueue(message)
|
||||
target.ircnick = ircnick
|
||||
target.gpg_keyid = gpg_keyid
|
||||
|
@ -326,7 +331,7 @@ https://admin.fedoraproject.org/accounts/user/verifyemail/%s
|
|||
|
||||
@identity.require(turbogears.identity.not_anonymous())
|
||||
@expose(template='fas.templates.user.verifyemail')
|
||||
def verifyemail(self, token):
|
||||
def verifyemail(self, token, cancel=False):
|
||||
username = turbogears.identity.current.user_name
|
||||
person = People.by_username(username)
|
||||
if not person.unverified_email:
|
||||
|
@ -334,38 +339,38 @@ https://admin.fedoraproject.org/accounts/user/verifyemail/%s
|
|||
turbogears.redirect('/user/view/%s' % username)
|
||||
return dict()
|
||||
if person.emailtoken and (person.emailtoken != token):
|
||||
person.emailtoken = ''
|
||||
turbogears.flash(_('Invalid email change token.'))
|
||||
turbogears.redirect('/user/view/%s' % username)
|
||||
return dict()
|
||||
if cancel:
|
||||
person.emailtoken = ''
|
||||
turbogears.flash(_('Your pending email change has been canceled. The email change token has been invalidated.'))
|
||||
turbogears.redirect('/user/view/%s' % username)
|
||||
return dict()
|
||||
return dict(person=person, token=token)
|
||||
|
||||
@identity.require(turbogears.identity.not_anonymous())
|
||||
@expose(template='fas.templates.user.verifyemail')
|
||||
def setemail(self, token, confirmation=None):
|
||||
@expose()
|
||||
def setemail(self, token):
|
||||
username = turbogears.identity.current.user_name
|
||||
person = People.by_username(username)
|
||||
if not person.unverified_email:
|
||||
if not (person.unverified_email and person.emailtoken):
|
||||
turbogears.flash(_('You do not have any pending email changes.'))
|
||||
turbogears.redirect('/user/view/%s' % username)
|
||||
return dict()
|
||||
if person.emailtoken and (person.emailtoken != token):
|
||||
person.emailtoken = ''
|
||||
if person.emailtoken != token:
|
||||
turbogears.flash(_('Invalid email change token.'))
|
||||
turbogears.redirect('/user/view/%s' % username)
|
||||
return dict()
|
||||
if confirmation:
|
||||
''' Log this '''
|
||||
oldEmail = person.email
|
||||
person.email = person.unverified_email
|
||||
Log(author_id=person.id, description='Email changed from %s to %s' % (oldEmail, person.email))
|
||||
person.unverified_email = ''
|
||||
session.flush()
|
||||
turbogears.flash(_('You have successfully changed your email to \'%s\'') % person.email)
|
||||
turbogears.redirect('/user/view/%s' % username)
|
||||
else:
|
||||
turbogears.flash(_('Your pending email change has been canceled. The email change token has been invalidated.') % person.email)
|
||||
turbogears.redirect('/user/view/%s' % username)
|
||||
''' Log this '''
|
||||
oldEmail = person.email
|
||||
person.email = person.unverified_email
|
||||
Log(author_id=person.id, description='Email changed from %s to %s' % (oldEmail, person.email))
|
||||
person.unverified_email = ''
|
||||
session.flush()
|
||||
turbogears.flash(_('You have successfully changed your email to \'%s\'') % person.email)
|
||||
turbogears.redirect('/user/view/%s' % username)
|
||||
return dict()
|
||||
|
||||
@expose(template='fas.templates.user.new')
|
||||
def new(self):
|
||||
|
@ -397,7 +402,7 @@ https://admin.fedoraproject.org/accounts/user/verifyemail/%s
|
|||
You have created a new Fedora account!
|
||||
Your new password is: %s
|
||||
|
||||
Please go to https://admin.fedoraproject.org/fas/ to change it.
|
||||
Please go to https://admin.fedoraproject.org/accounts/ to change it.
|
||||
|
||||
Welcome to the Fedora Project. Now that you've signed up for an
|
||||
account you're probably desperate to start contributing, and with that
|
||||
|
@ -481,7 +486,7 @@ forward to working with you!
|
|||
|
||||
#TODO: Validate
|
||||
@expose(template="fas.templates.user.resetpass")
|
||||
def sendpass(self, username, email, encrypted=False):
|
||||
def sendtoken(self, username, email, encrypted=False):
|
||||
import turbomail
|
||||
# Logged in
|
||||
if turbogears.identity.current.user_name:
|
||||
|
@ -496,14 +501,13 @@ forward to working with you!
|
|||
if email != person.email:
|
||||
turbogears.flash(_("username + email combo unknown."))
|
||||
return dict()
|
||||
newpass = generate_password()
|
||||
token = generate_token()
|
||||
message = turbomail.Message(config.get('accounts_email'), email, _('Fedora Project Password Reset'))
|
||||
mail = _('''
|
||||
You have requested a password reset!
|
||||
Your new password is: %s
|
||||
|
||||
Please go to https://admin.fedoraproject.org/fas/ to change it.
|
||||
''') % newpass['pass']
|
||||
Somebody (hopefully you) has requested a password reset for your account!
|
||||
To change your password (or to cancel the request), please visit
|
||||
https://admin.fedoraproject.org/accounts/user/verifypass/%(user)s/%(token)s
|
||||
''') % {'user': username, 'token': token}
|
||||
if encrypted:
|
||||
# TODO: Move this out to a single function (same as
|
||||
# CLA one), think of how to make sure this doesn't get
|
||||
|
@ -517,7 +521,8 @@ Please go to https://admin.fedoraproject.org/fas/ to change it.
|
|||
return dict()
|
||||
else:
|
||||
try:
|
||||
plaintext = StringIO.StringIO(mail)
|
||||
# This may not be the neatest fix, but gpgme gave an error when mail was unicode.
|
||||
plaintext = StringIO.StringIO(mail.encode('utf-8'))
|
||||
ciphertext = StringIO.StringIO()
|
||||
ctx = gpgme.Context()
|
||||
ctx.armor = True
|
||||
|
@ -533,26 +538,78 @@ Please go to https://admin.fedoraproject.org/fas/ to change it.
|
|||
ciphertext)
|
||||
message.plain = ciphertext.getvalue()
|
||||
except:
|
||||
turbogears.flash(_('Your password reset email could not be encrypted. Your password has not been changed.'))
|
||||
turbogears.flash(_('Your password reset email could not be encrypted.'))
|
||||
return dict()
|
||||
else:
|
||||
message.plain = mail;
|
||||
turbomail.enqueue(message)
|
||||
try:
|
||||
person.password = newpass['hash']
|
||||
turbogears.flash(_('Your new password has been emailed to you.'))
|
||||
except:
|
||||
turbogears.flash(_('Your password could not be reset.'))
|
||||
return dict()
|
||||
person.passwordtoken = token
|
||||
turbogears.flash(_('A password reset URL has been emailed to you.'))
|
||||
turbogears.redirect('/login')
|
||||
return dict()
|
||||
|
||||
@expose(template="fas.templates.user.newpass")
|
||||
# TODO: Validator
|
||||
def newpass(self, username, token, password=None, passwordcheck=None):
|
||||
person = People.by_username(username)
|
||||
if not person.passwordtoken:
|
||||
turbogears.flash(_('You do not have any pending password changes.'))
|
||||
turbogears.redirect('/login')
|
||||
return dict()
|
||||
if person.passwordtoken != token:
|
||||
person.emailtoken = ''
|
||||
turbogears.flash(_('Invalid password change token.'))
|
||||
turbogears.redirect('/login')
|
||||
return dict()
|
||||
return dict(person=person, token=token)
|
||||
|
||||
@expose(template="fas.templates.user.verifypass")
|
||||
# TODO: Validator
|
||||
def verifypass(self, username, token, cancel=False):
|
||||
person = People.by_username(username)
|
||||
if not person.passwordtoken:
|
||||
turbogears.flash(_('You do not have any pending password changes.'))
|
||||
turbogears.redirect('/login')
|
||||
return dict()
|
||||
if person.passwordtoken != token:
|
||||
turbogears.flash(_('Invalid password change token.'))
|
||||
turbogears.redirect('/login')
|
||||
return dict()
|
||||
if cancel:
|
||||
person.passwordtoken = ''
|
||||
turbogears.flash(_('Your password reset has been canceled. The password change token has been invalidated.'))
|
||||
turbogears.redirect('/login')
|
||||
return dict()
|
||||
return dict(person=person, token=token)
|
||||
|
||||
@expose()
|
||||
@validate(validators=UserResetPassword())
|
||||
def setnewpass(self, username, token, password, passwordcheck):
|
||||
person = People.by_username(username)
|
||||
if not person.passwordtoken:
|
||||
turbogears.flash(_('You do not have any pending password changes.'))
|
||||
turbogears.redirect('/login')
|
||||
return dict()
|
||||
if person.passwordtoken != token:
|
||||
person.emailtoken = ''
|
||||
turbogears.flash(_('Invalid password change token.'))
|
||||
turbogears.redirect('/login')
|
||||
return dict()
|
||||
''' Log this '''
|
||||
newpass = generate_password(password)
|
||||
person.password = newpass['hash']
|
||||
person.passwordtoken = ''
|
||||
Log(author_id=person.id, description='Password changed')
|
||||
session.flush()
|
||||
turbogears.flash(_('You have successfully reset your password. You should now be able to login below.'))
|
||||
turbogears.redirect('/login')
|
||||
return dict()
|
||||
|
||||
@identity.require(turbogears.identity.not_anonymous())
|
||||
@expose(template="genshi-text:fas.templates.user.cert", format="text", content_type='text/plain; charset=utf-8')
|
||||
def gencert(self):
|
||||
username = turbogears.identity.current.user_name
|
||||
person = People.by_username(username)
|
||||
|
||||
person = People.by_username(username)
|
||||
if signedCLAPrivs(person):
|
||||
person.certificate_serial = person.certificate_serial + 1
|
||||
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
import pgdb
|
||||
|
||||
from turbogears.view import engines
|
||||
import turbogears.view
|
||||
import turbogears.util as tg_util
|
||||
from turbogears import view, database, errorhandling, config
|
||||
from itertools import izip
|
||||
from inspect import isclass
|
||||
from turbogears import update_config, start_server
|
||||
import cherrypy
|
||||
cherrypy.lowercase_api = True
|
||||
from os.path import *
|
||||
import sys
|
||||
import time
|
||||
import crypt
|
||||
import random
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
update_config(configfile=sys.argv[1],
|
||||
modulename="fas.config")
|
||||
elif exists(join(dirname(__file__), "setup.py")):
|
||||
update_config(configfile="dev.cfg",modulename="fas.config")
|
||||
else:
|
||||
update_config(configfile="prod.cfg",modulename="fas.config")
|
||||
|
||||
from sqlalchemy import *
|
||||
from sqlalchemy.exceptions import *
|
||||
from fas.model import *
|
||||
|
||||
|
||||
db = pgdb.connect(dsn='localhost', user='fedora', password='test', database='fedorausers')
|
||||
|
||||
c = db.cursor()
|
||||
|
||||
c.execute('select id, name, owner_id, group_type, needs_sponsor, user_can_remove, prerequisite_id, joinmsg from project_group;')
|
||||
bool_dict = {0 : False, 1 : True}
|
||||
print "Creating Groups..."
|
||||
admin = People.by_username('admin')
|
||||
admin_id = admin.id
|
||||
for group in c.fetchall():
|
||||
(id, name, owner_id, group_type, needs_sponsor, user_can_remove, prerequisite_id, joinmsg) = group
|
||||
print "%i - %s" % (id, name)
|
||||
try:
|
||||
group = Groups.by_id(id)
|
||||
#if prerequisite_id:
|
||||
# group.prerequisite = Groups.by_id(prerequisite_id)
|
||||
session.flush()
|
||||
except IntegrityError, e:
|
||||
print "\tERROR - The group: '%s' (%i) could not be created - %s" % (name, id, e)
|
||||
except FlushError, e:
|
||||
print "\tERROR - The group: '%s' (%i) could not be created - %s" % (name, id, e)
|
||||
except InvalidRequestError, e:
|
||||
print "\tERROR - The group: '%s' (%i) could not be created - %s" % (name, id, e)
|
||||
|
||||
session.close()
|
||||
|
||||
c.execute('select person_id, project_group_id, role_type, role_domain, role_status, internal_comments, sponsor_id, creation, approval from role order by person_id;')
|
||||
print "Creating Role Maps..."
|
||||
for role in c.fetchall():
|
||||
(person_id, project_group_id, role_type, role_domain, role_status, internal_comments, sponsor_id, creation, approval) = role
|
||||
print "%s - %s" % (person_id, project_group_id)
|
||||
try:
|
||||
role = PersonRoles.query.filter_by(person_id=person_id, group_id=project_group_id)
|
||||
if role_status == 'declined':
|
||||
''' No longer exists '''
|
||||
continue
|
||||
# Do we need to do weird stuff to convert from no time zone to time zone?
|
||||
role.creation = creation
|
||||
session.flush()
|
||||
except ProgrammingError, e:
|
||||
print "\tERROR - The role %s -> %s could not be created - %s" % (person_id, project_group_id, e)
|
||||
session.close()
|
||||
except IntegrityError, e:
|
||||
if e.message.find('dupilcate key'):
|
||||
print "\tERROR - The role %s -> %s already exists! Skipping" % (person_id, project_group_id)
|
||||
session.close()
|
||||
continue
|
||||
print "\tERROR - The role %s -> %s could not be created - %s" % (person_id, project_group_id, e)
|
||||
session.close()
|
Loading…
Add table
Add a link
Reference in a new issue