Merge branch 'master' of ssh://git.fedorahosted.org/git/fedora-infrastructure

This commit is contained in:
Michael McGrath 2008-03-12 15:07:56 -05:00
commit ce35e3ea23
8 changed files with 126 additions and 129 deletions

View file

@ -10,7 +10,7 @@ legal_cla_email = "nobody@fedoraproject.org"
email_host = "fedoraproject.org" # as in, web-members@email_host email_host = "fedoraproject.org" # as in, web-members@email_host
gpgexec = "/usr/bin/gpg" 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_fingerprint = "C199 1E25 D00A D200 2D2E 54D1 BF7F 1647 C54E 8410"
gpg_passphrase = "m00!s@ysth3c0w" gpg_passphrase = "m00!s@ysth3c0w"
gpg_keyserver = "hkp://subkeys.pgp.net" gpg_keyserver = "hkp://subkeys.pgp.net"
@ -83,7 +83,7 @@ tg.strict_parameters = True
server.webpath='/accounts' server.webpath='/accounts'
base_url_filter.on = True base_url_filter.on = True
base_url_filter.use_x_forwarded_host = 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 # Make the session cookie only return to the host over an SSL link
# Disabled for testing. # Disabled for testing.

View file

@ -281,8 +281,8 @@ class Group(controllers.Controller):
group = Groups.by_name(groupname) group = Groups.by_name(groupname)
if not canApplyGroup(person, group, target): if not canApplyGroup(person, group, target):
# turbogears.flash(_('%(user)s could not apply to %(group)s.') % \ turbogears.flash(_('%(user)s can not apply to %(group)s.') % \
# {'user': target.username, 'group': group.name }) {'user': target.username, 'group': group.name })
turbogears.redirect('/group/view/%s' % group.name) turbogears.redirect('/group/view/%s' % group.name)
return dict() return dict()
else: else:

View file

@ -247,17 +247,16 @@ class People(SABase):
# Only admins can see internal_comments # Only admins can see internal_comments
del props['internal_comments'] del props['internal_comments']
del props['emailtoken'] del props['emailtoken']
del props['passwordtoken']
if identity.current.anonymous: if identity.current.anonymous:
# Anonymous users can't see any of these # Anonymous users can't see any of these
del props['email'] del props['email']
del props['emailtoken']
del props['unverified_email'] del props['unverified_email']
del props['ssh_key'] del props['ssh_key']
del props['gpg_keyid'] del props['gpg_keyid']
del props['affiliation'] del props['affiliation']
del props['certificate_serial'] del props['certificate_serial']
del props['password'] del props['password']
del props['passwordtoken']
del props['password_changed'] del props['password_changed']
del props['postal_address'] del props['postal_address']
del props['telephone'] del props['telephone']
@ -267,7 +266,6 @@ class People(SABase):
# Only an admin or the user themselves can see these fields # Only an admin or the user themselves can see these fields
del props['unverified_email'] del props['unverified_email']
del props['password'] del props['password']
del props['passwordtoken']
del props['postal_address'] del props['postal_address']
del props['password_changed'] del props['password_changed']
del props['telephone'] del props['telephone']

View file

@ -8,7 +8,7 @@
</head> </head>
<body> <body>
<h2>${_('Reset Password')}</h2> <h2>${_('Reset Password')}</h2>
<form action="${tg.url('/user/sendpass')}" method="post"> <form action="${tg.url('/user/sendtoken')}" method="post">
<ul> <ul>
<div class="field"><label for="username">${_('Username:')}</label> <input type="text" id="username" name="username" /></div> <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> <div class="field"><label for="email">${_('Email:')}</label> <input type="text" id="email" name="email" /></div>

View file

@ -13,8 +13,8 @@
<p> <p>
Do you really want to change your email to: ${person.unverified_email} ? Do you really want to change your email to: ${person.unverified_email} ?
</p> </p>
<input type="submit" name="confirmation" id="confirmation" value="${_('Confirm')}" /> <input type="submit" value="${_('Confirm')}" />
<input type="submit" value="${_('Cancel')}" /> <a href="${tg.url('/user/verifyemail/%s/%s/cancel') % (person.username, token)}">${_('Cancel')}</a>
</div> </div>
</form> </form>
</body> </body>

View 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>

View file

@ -125,6 +125,12 @@ class UserSetPassword(validators.Schema):
passwordcheck = validators.String passwordcheck = validators.String
chained_validators = [validators.FieldsMatch('password', 'passwordcheck')] 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): class UserView(validators.Schema):
username = KnownUser username = KnownUser
@ -271,8 +277,7 @@ login with your Fedora account first):
https://admin.fedoraproject.org/accounts/user/verifyemail/%s https://admin.fedoraproject.org/accounts/user/verifyemail/%s
''') % token ''') % 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) turbomail.enqueue(message)
target.ircnick = ircnick target.ircnick = ircnick
target.gpg_keyid = gpg_keyid target.gpg_keyid = gpg_keyid
@ -326,7 +331,7 @@ https://admin.fedoraproject.org/accounts/user/verifyemail/%s
@identity.require(turbogears.identity.not_anonymous()) @identity.require(turbogears.identity.not_anonymous())
@expose(template='fas.templates.user.verifyemail') @expose(template='fas.templates.user.verifyemail')
def verifyemail(self, token): def verifyemail(self, token, cancel=False):
username = turbogears.identity.current.user_name username = turbogears.identity.current.user_name
person = People.by_username(username) person = People.by_username(username)
if not person.unverified_email: if not person.unverified_email:
@ -334,38 +339,38 @@ https://admin.fedoraproject.org/accounts/user/verifyemail/%s
turbogears.redirect('/user/view/%s' % username) turbogears.redirect('/user/view/%s' % username)
return dict() return dict()
if person.emailtoken and (person.emailtoken != token): if person.emailtoken and (person.emailtoken != token):
person.emailtoken = ''
turbogears.flash(_('Invalid email change token.')) turbogears.flash(_('Invalid email change token.'))
turbogears.redirect('/user/view/%s' % username) turbogears.redirect('/user/view/%s' % username)
return dict() 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) return dict(person=person, token=token)
@identity.require(turbogears.identity.not_anonymous()) @identity.require(turbogears.identity.not_anonymous())
@expose(template='fas.templates.user.verifyemail') @expose()
def setemail(self, token, confirmation=None): def setemail(self, token):
username = turbogears.identity.current.user_name username = turbogears.identity.current.user_name
person = People.by_username(username) 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.flash(_('You do not have any pending email changes.'))
turbogears.redirect('/user/view/%s' % username) turbogears.redirect('/user/view/%s' % username)
return dict() return dict()
if person.emailtoken and (person.emailtoken != token): if person.emailtoken != token:
person.emailtoken = ''
turbogears.flash(_('Invalid email change token.')) turbogears.flash(_('Invalid email change token.'))
turbogears.redirect('/user/view/%s' % username) turbogears.redirect('/user/view/%s' % username)
return dict() return dict()
if confirmation: ''' Log this '''
''' Log this ''' oldEmail = person.email
oldEmail = person.email person.email = person.unverified_email
person.email = person.unverified_email Log(author_id=person.id, description='Email changed from %s to %s' % (oldEmail, person.email))
Log(author_id=person.id, description='Email changed from %s to %s' % (oldEmail, person.email)) person.unverified_email = ''
person.unverified_email = '' session.flush()
session.flush() turbogears.flash(_('You have successfully changed your email to \'%s\'') % person.email)
turbogears.flash(_('You have successfully changed your email to \'%s\'') % person.email) turbogears.redirect('/user/view/%s' % username)
turbogears.redirect('/user/view/%s' % username) return dict()
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)
@expose(template='fas.templates.user.new') @expose(template='fas.templates.user.new')
def new(self): def new(self):
@ -397,7 +402,7 @@ https://admin.fedoraproject.org/accounts/user/verifyemail/%s
You have created a new Fedora account! You have created a new Fedora account!
Your new password is: %s 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 Welcome to the Fedora Project. Now that you've signed up for an
account you're probably desperate to start contributing, and with that account you're probably desperate to start contributing, and with that
@ -481,7 +486,7 @@ forward to working with you!
#TODO: Validate #TODO: Validate
@expose(template="fas.templates.user.resetpass") @expose(template="fas.templates.user.resetpass")
def sendpass(self, username, email, encrypted=False): def sendtoken(self, username, email, encrypted=False):
import turbomail import turbomail
# Logged in # Logged in
if turbogears.identity.current.user_name: if turbogears.identity.current.user_name:
@ -496,14 +501,13 @@ forward to working with you!
if email != person.email: if email != person.email:
turbogears.flash(_("username + email combo unknown.")) turbogears.flash(_("username + email combo unknown."))
return dict() return dict()
newpass = generate_password() token = generate_token()
message = turbomail.Message(config.get('accounts_email'), email, _('Fedora Project Password Reset')) message = turbomail.Message(config.get('accounts_email'), email, _('Fedora Project Password Reset'))
mail = _(''' mail = _('''
You have requested a password reset! Somebody (hopefully you) has requested a password reset for your account!
Your new password is: %s To change your password (or to cancel the request), please visit
https://admin.fedoraproject.org/accounts/user/verifypass/%(user)s/%(token)s
Please go to https://admin.fedoraproject.org/fas/ to change it. ''') % {'user': username, 'token': token}
''') % newpass['pass']
if encrypted: if encrypted:
# TODO: Move this out to a single function (same as # TODO: Move this out to a single function (same as
# CLA one), think of how to make sure this doesn't get # 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() return dict()
else: else:
try: 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() ciphertext = StringIO.StringIO()
ctx = gpgme.Context() ctx = gpgme.Context()
ctx.armor = True ctx.armor = True
@ -533,26 +538,78 @@ Please go to https://admin.fedoraproject.org/fas/ to change it.
ciphertext) ciphertext)
message.plain = ciphertext.getvalue() message.plain = ciphertext.getvalue()
except: 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() return dict()
else: else:
message.plain = mail; message.plain = mail;
turbomail.enqueue(message) turbomail.enqueue(message)
try: person.passwordtoken = token
person.password = newpass['hash'] turbogears.flash(_('A password reset URL has been emailed to you.'))
turbogears.flash(_('Your new password has been emailed to you.'))
except:
turbogears.flash(_('Your password could not be reset.'))
return dict()
turbogears.redirect('/login') turbogears.redirect('/login')
return dict() 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()) @identity.require(turbogears.identity.not_anonymous())
@expose(template="genshi-text:fas.templates.user.cert", format="text", content_type='text/plain; charset=utf-8') @expose(template="genshi-text:fas.templates.user.cert", format="text", content_type='text/plain; charset=utf-8')
def gencert(self): def gencert(self):
username = turbogears.identity.current.user_name username = turbogears.identity.current.user_name
person = People.by_username(username) person = People.by_username(username)
if signedCLAPrivs(person): if signedCLAPrivs(person):
person.certificate_serial = person.certificate_serial + 1 person.certificate_serial = person.certificate_serial + 1

View file

@ -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()