Merge branch 'master' of git://bzr.fedoraproject.org/hosted/fedora-infrastructure

This commit is contained in:
Toshio Kuratomi 2008-02-14 20:07:15 -08:00
commit c5078b9ce9
47 changed files with 685 additions and 501 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
architecture/Services.odg Normal file

Binary file not shown.

BIN
architecture/buildsys.flw Normal file

Binary file not shown.

BIN
architecture/buildsys.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Before After
Before After

View file

@ -7,8 +7,9 @@
#mail.server = 'bastion.fedora.phx.redhat.com' #mail.server = 'bastion.fedora.phx.redhat.com'
#base_url_filter.base_url = "http://192.168.2.101:8080" #base_url_filter.base_url = "http://192.168.2.101:8080"
mail.on = False mail.on = True
mail.server = 'bastion.fedora.phx.redhat.com' mail.server = 'bastion.fedora.phx.redhat.com'
mail.testmode = True
mail.debug = False mail.debug = False
mail.encoding = 'utf-8' mail.encoding = 'utf-8'
@ -53,7 +54,7 @@ tg.strict_parameters = True
server.webpath='/fas' server.webpath='/fas'
base_url_filter.on=True base_url_filter.on=True
base_url = "http://publictest1.fedoraproject.org" base_url_filter.base_url = "https://publictest1.fedoraproject.org/fas"
# 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

@ -124,7 +124,7 @@ def canApplyGroup(userName, groupName, applyUserName, g=None):
try: try:
g[req].cn g[req].cn
except KeyError: except KeyError:
return False return { 'status': False, 'requires': req }
# A user can apply themselves, and FAS admins can apply other people. # A user can apply themselves, and FAS admins can apply other people.
if (userName == applyUserName) or \ if (userName == applyUserName) or \
isAdmin(userName, g): isAdmin(userName, g):

View file

@ -4,7 +4,7 @@ from turbogears import controllers, expose, paginate, identity, redirect, widget
import ldap import ldap
import cherrypy import cherrypy
import mx.DateTime from datetime import datetime
import re import re
import gpgme import gpgme
import StringIO import StringIO
@ -69,7 +69,7 @@ class CLA(controllers.Controller):
return dict() return dict()
userName = turbogears.identity.current.user_name userName = turbogears.identity.current.user_name
user = Person.byUserName(userName) user = Person.byUserName(userName)
return dict(type=type, user=user, date=str(mx.DateTime.now())) return dict(type=type, user=user, date=datetime.utcnow().ctime())
@identity.require(turbogears.identity.not_anonymous()) @identity.require(turbogears.identity.not_anonymous())
@error_handler(error) @error_handler(error)
@ -78,7 +78,7 @@ class CLA(controllers.Controller):
'''Download CLA''' '''Download CLA'''
userName = turbogears.identity.current.user_name userName = turbogears.identity.current.user_name
user = Person.byUserName(userName) user = Person.byUserName(userName)
return dict(user=user, date=str(mx.DateTime.now())) return dict(user=user, date=datetime.utcnow().ctime())
@identity.require(turbogears.identity.not_anonymous()) @identity.require(turbogears.identity.not_anonymous())
@error_handler(error) @error_handler(error)

View file

@ -24,6 +24,11 @@ import sys
reload(sys) reload(sys)
sys.setdefaultencoding('utf-8') sys.setdefaultencoding('utf-8')
def add_custom_stdvars(vars):
return vars.update({"gettext": _})
turbogears.view.variable_providers.append(add_custom_stdvars)
# from fas import json # from fas import json
# import logging # import logging
# log = logging.getLogger("fas.controllers") # log = logging.getLogger("fas.controllers")
@ -49,9 +54,7 @@ class Root(controllers.RootController):
@expose(template="fas.templates.home") @expose(template="fas.templates.home")
@identity.require(identity.not_anonymous()) @identity.require(identity.not_anonymous())
def home(self): def home(self):
from feeds import Koji return dict()
builds = Koji(turbogears.identity.current.user_name)
return dict(builds=builds)
@expose(template="fas.templates.login") @expose(template="fas.templates.login")
def login(self, forward_url=None, previous_url=None, *args, **kw): def login(self, forward_url=None, previous_url=None, *args, **kw):
@ -60,6 +63,8 @@ class Root(controllers.RootController):
and identity.was_login_attempted() \ and identity.was_login_attempted() \
and not identity.get_identity_errors(): and not identity.get_identity_errors():
turbogears.flash(_('Welcome, %s') % Person.byUserName(turbogears.identity.current.user_name).givenName) turbogears.flash(_('Welcome, %s') % Person.byUserName(turbogears.identity.current.user_name).givenName)
if not forward_url:
forward_url = config.get('base_url_filter.base_url') + '/'
raise redirect(forward_url) raise redirect(forward_url)
forward_url=None forward_url=None
@ -84,50 +89,4 @@ class Root(controllers.RootController):
def logout(self): def logout(self):
identity.current.logout() identity.current.logout()
turbogears.flash(_('You have successfully logged out.')) turbogears.flash(_('You have successfully logged out.'))
raise redirect("/") raise redirect(request.headers.get("Referer", "/"))
## TODO: Invitation cleanup- move out and validate!
@expose(template='fas.templates.inviteMember')
@identity.require(identity.not_anonymous())
def inviteMember(self, name=None, email=None, skills=None):
if name and email:
turbogears.flash(_('Invitation Sent to: "%(name)s" <%(email)s>') % {'name': name, 'email': email})
if name or email:#FIXME
turbogears.flash(_('Please provide both an email address and the persons name.'))
return dict()
@expose(format="json")
def search(self, userName=None, groupName=None):
people = Person.users('%s*' % userName)
return dict(people=
filter(lambda item: userName in item.lower(), people))
@expose(template='fas.templates.invite')
@identity.require(identity.not_anonymous())
def invite(self, target=None):
import turbomail
user = Person.byUserName(turbogears.identity.current.user_name)
if target:
message = turbomail.Message(user.mail, target, _('Come join The Fedora Project!'))
message.plain = _('''%(name)s <%(email)s> has invited you to join the Fedora
Project! We are a community of users and developers who produce a
complete operating system from entirely free and open source software
(FOSS). %(name)s thinks that you have knowledge and skills
that make you a great fit for the Fedora community, and that you might
be interested in contributing.
How could you team up with the Fedora community to use and develop your
skills? Check out http://fedoraproject.org/wiki/Join for some ideas.
Our community is more than just software developers -- we also have a
place for you whether you're an artist, a web site builder, a writer, or
a people person. You'll grow and learn as you work on a team with other
very smart and talented people.
Fedora and FOSS are changing the world -- come be a part of it!''') % {'name': user.givenName, 'email': user.mail}
turbomail.enqueue(message)
turbogears.flash(_('Message sent to: %s') % target)
return dict(target=target, user=user)
def relativeUser(realUser, sudoUser):
''' Takes user and sees if they are allow to sudo for remote group'''
p = Person.byUserName('realUser')

View file

@ -26,31 +26,81 @@ python-fedora, python module to interact with Fedora Infrastructure Services
import ldap import ldap
from ldap import modlist from ldap import modlist
import datetime import time
from random import Random from random import Random
import sha import sha
from base64 import b64encode from base64 import b64encode
import sys import sys
import os
dbName = 'fastest'
class AuthError(Exception): class AuthError(Exception):
pass pass
def retrieve_db_info(dbKey):
'''Retrieve information to connect to the db from the filesystem.
Arguments:
:dbKey: The string identifying the database entry in the config file.
Returns: A dictionary containing the values to use in connecting to the
database.
Exceptions:
:IOError: Returned if the config file is not on the system.
:AuthError: Returned if there is no record found for dbKey in the
config file.
'''
# Open a filehandle to the config file
if os.environ.has_key('HOME') and os.path.isfile(
os.path.join(os.environ.get('HOME'), '.fedora-db-access')):
fh = file(os.path.join(
os.environ.get('HOME'), '.fedora-db-access'), 'r')
elif os.path.isfile('/etc/sysconfig/fedora-db-access'):
fh = file('/etc/sysconfig/fedora-db-access', 'r')
else:
raise IOError, 'fedora-db-access file does not exist.'
# Read the file until we get the information for the requested db
dbInfo = None
for line in fh.readlines():
if not line:
break
line = line.strip()
if not line or line[0] == '#':
continue
pieces = line.split(None, 1)
if len(pieces) < 2:
continue
if pieces[0] == dbKey:
dbInfo = eval(pieces[1])
break
if fh:
fh.close()
if not dbInfo:
raise AuthError, 'Authentication source "%s" not configured' % (dbKey,)
return dbInfo
class Server(object): class Server(object):
def __init__(self, server=None, who=None, password=None): def __init__(self, server=None, who=None, password=None):
### FIXME: Before deploy, get the default server, user, and password try:
# from the fedora-db-access file. dbInfo = retrieve_db_info(dbName)
server = server or 'localhost' except IOError:
who = who or 'cn=directory manager' raise AuthError, 'Authentication config file fedora-db-access is' \
password = password or 'test' ' not available'
server = server or dbInfo['host'] or 'localhost'
who = 'cn=%s' % (who or dbInfo['user'])
# Some db connections have no password
password = password or dbInfo.get('password')
self.ldapConn = ldap.open(server) self.ldapConn = ldap.open(server)
self.ldapConn.simple_bind_s(who, password) self.ldapConn.simple_bind_s(who, password)
def add(self, base, attributes): def add(self, base, attributes):
''' Add a new group record to LDAP instance ''' ''' Add a new group record to LDAP instance '''
attributes=[ (k, v) for k,v in attributes.items() ] self.ldapConn.add_s(base, attributes.items())
self.ldapConn.add_s(base, attributes)
def delete(self, base): def delete(self, base):
''' Delete target base ''' ''' Delete target base '''
@ -60,7 +110,7 @@ class Server(object):
''' Modify an attribute, requires write access ''' ''' Modify an attribute, requires write access '''
if new is None: if new is None:
return None return None
new = str(new) new = unicode(new).encode('utf-8')
if new == old: if new == old:
return None return None
@ -130,17 +180,17 @@ class Group(object):
} }
@classmethod @classmethod
def newGroup(self, cn, fedoraGroupDesc, fedoraGroupOwner, fedoraGroupNeedsSponsor, fedoraGroupUserCanRemove, fedoraGroupRequires, fedoraGroupJoinMsg): def newGroup(self, cn, fedoraGroupDesc, fedoraGroupOwner, fedoraGroupType, fedoraGroupNeedsSponsor, fedoraGroupUserCanRemove, fedoraGroupRequires, fedoraGroupJoinMsg):
''' Create a new group ''' ''' Create a new group '''
attributes = { 'cn' : cn, attributes = { 'cn' : cn.encode('utf-8'),
'objectClass' : ('fedoraGroup'), 'objectClass' : ('fedoraGroup'),
'fedoraGroupDesc' : fedoraGroupDesc, 'fedoraGroupDesc' : fedoraGroupDesc.encode('utf-8'),
'fedoraGroupOwner' : fedoraGroupOwner, 'fedoraGroupOwner' : fedoraGroupOwner.encode('utf-8'),
'fedoraGroupType' : '1', 'fedoraGroupType' : fedoraGroupType.encode('utf-8'),
'fedoraGroupNeedsSponsor' : fedoraGroupNeedsSponsor, 'fedoraGroupNeedsSponsor' : fedoraGroupNeedsSponsor.encode('utf-8'),
'fedoraGroupUserCanRemove' : fedoraGroupUserCanRemove, 'fedoraGroupUserCanRemove' : fedoraGroupUserCanRemove.encode('utf-8'),
'fedoraGroupRequires' : fedoraGroupRequires, 'fedoraGroupRequires' : fedoraGroupRequires.encode('utf-8'),
'fedoraGroupJoinMsg' : fedoraGroupJoinMsg, 'fedoraGroupJoinMsg' : fedoraGroupJoinMsg.encode('utf-8'),
} }
self.__server.add('cn=%s,%s' % (cn, self.__base), attributes) self.__server.add('cn=%s,%s' % (cn, self.__base), attributes)
@ -271,17 +321,10 @@ class Groups(object):
except TypeError: except TypeError:
raise TypeError, 'Group "%s" does not exist' % groupName raise TypeError, 'Group "%s" does not exist' % groupName
dt = datetime.datetime.now() now = time.time()
now = '%.2i-%.2i-%.2i %.2i:%.2i:%.2i.%.2i' % (dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond)
attributes = { 'cn' : groupName, attributes = { 'cn' : groupName.encode('utf-8'),
'fedoraRoleApprovaldate' : 'NotApproved', 'fedoraRoleApprovaldate' : 'None',
'fedoraRoleCreationDate' : str(now), 'fedoraRoleCreationDate' : str(now),
'fedoraRoleDomain' : 'None', 'fedoraRoleDomain' : 'None',
'fedoraRoleSponsor' : 'None', 'fedoraRoleSponsor' : 'None',
@ -335,33 +378,27 @@ class Person(object):
@classmethod @classmethod
def newPerson(self, cn, givenName, mail, telephoneNumber, postalAddress): def newPerson(self, cn, givenName, mail, telephoneNumber, postalAddress):
''' Create a new user ''' ''' Create a new user '''
dt = datetime.datetime.now() now = time.time()
now = '%.2i-%.2i-%.2i %.2i:%.2i:%.2i.%.2i' % (dt.year, attributes = { 'cn' : cn.encode('utf-8'),
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond)
attributes = { 'cn' : cn,
'objectClass' : ('fedoraPerson', 'inetOrgPerson', 'organizationalPerson', 'person', 'top'), 'objectClass' : ('fedoraPerson', 'inetOrgPerson', 'organizationalPerson', 'person', 'top'),
'displayName' : cn, 'displayName' : cn.encode('utf-8'),
'sn' : cn, 'sn' : cn.encode('utf-8'),
'cn' : cn, 'cn' : cn.encode('utf-8'),
'fedoraPersonSshKey' : '', 'fedoraPersonSshKey' : '',
'facsimileTelephoneNumber' : '', 'facsimileTelephoneNumber' : '',
'fedoraPersonApprovalStatus' : 'approved', 'fedoraPersonApprovalStatus' : 'approved',
'givenName' : givenName, 'givenName' : givenName.encode('utf-8'),
'mail' : mail, 'mail' : mail.encode('utf-8'),
'fedoraPersonKeyId' : '', 'fedoraPersonKeyId' : '',
'fedoraPersonCertSerial' : -1, 'fedoraPersonCertSerial' : '-1',
'description' : '', 'description' : '',
'fedoraPersonCreationDate' : str(now), 'fedoraPersonCreationDate' : str(now),
'telephoneNumber' : telephoneNumber, 'telephoneNumber' : telephoneNumber.encode('utf-8'),
'fedoraPersonBugzillaMail' : mail, 'fedoraPersonBugzillaMail' : mail.encode('utf-8'),
'postalAddress' : postalAddress, 'postalAddress' : postalAddress.encode('utf-8'),
'fedoraPersonIrcNick' : '', 'fedoraPersonIrcNick' : '',
'userPassword' : 'Disabled' 'userPassword' : 'Disabled',
'fedoraPersonTimeZone' : 'UTC',
} }
self.__server.add('cn=%s,%s' % (cn, self.__base), attributes) self.__server.add('cn=%s,%s' % (cn, self.__base), attributes)
attributes = { attributes = {
@ -475,14 +512,7 @@ class Person(object):
base = 'cn=%s,ou=Roles,cn=%s,ou=People,dc=fedoraproject,dc=org' % (groupName, self.cn) base = 'cn=%s,ou=Roles,cn=%s,ou=People,dc=fedoraproject,dc=org' % (groupName, self.cn)
g = Groups.byGroupName(groupName, includeUnapproved=True)[self.cn] g = Groups.byGroupName(groupName, includeUnapproved=True)[self.cn]
group = Groups.groups(groupName)[groupName] group = Groups.groups(groupName)[groupName]
dt = datetime.datetime.now() now = time.time()
now = '%.2i-%.2i-%.2i %.2i:%.2i:%.2i.%.2i' % (dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond)
self.__server.modify(base, 'fedoraRoleApprovalDate', now) self.__server.modify(base, 'fedoraRoleApprovalDate', now)
if group.fedoraGroupNeedsSponsor.lower() == 'true': if group.fedoraGroupNeedsSponsor.lower() == 'true':
self.__server.modify(base, 'fedoraRoleSponsor', sponsor) self.__server.modify(base, 'fedoraRoleSponsor', sponsor)

View file

@ -64,6 +64,10 @@ class userNameGroupNameExists(validators.Schema):
class groupNameExists(validators.Schema): class groupNameExists(validators.Schema):
groupName = validators.All(knownGroup(not_empty=True, max=10), validators.String(max=32, min=3)) groupName = validators.All(knownGroup(not_empty=True, max=10), validators.String(max=32, min=3))
class groupInvite(validators.Schema):
groupName = validators.All(knownGroup(not_empty=True, max=10), validators.String(max=32, min=3))
target = validators.Email(not_empty=True, strip=True),
#class findUser(widgets.WidgetsList): #class findUser(widgets.WidgetsList):
# userName = widgets.AutoCompleteField(label=_('Username'), search_controller='search', search_param='userName', result_name='people') # userName = widgets.AutoCompleteField(label=_('Username'), search_controller='search', search_param='userName', result_name='people')
# action = widgets.HiddenField(default='apply', validator=validators.String(not_empty=True)) # action = widgets.HiddenField(default='apply', validator=validators.String(not_empty=True))
@ -92,6 +96,22 @@ class Group(controllers.Controller):
turbogears.redirect('/') turbogears.redirect('/')
return dict(tg_errors=tg_errors) return dict(tg_errors=tg_errors)
@expose(format="json")
def exportShellAccounts(self):
''' Replaces old "exportShellAccounts.py" '''
userList = Groups.byGroupName('sysadmin-main')
user = Person.byUserName('mmcgrath').givenName
users = {}
for user in userList.keys():
u = Person.byUserName(user)
users[user] = {
'userName' : u.cn,
'password' : u.userPassword,
'sshKey' : u.fedoraPersonSshKey,
}
groups = Groups.groups('*')
return dict(users=users, groups=groups)
@identity.require(turbogears.identity.not_anonymous()) @identity.require(turbogears.identity.not_anonymous())
@validate(validators=groupNameExists()) @validate(validators=groupNameExists())
@error_handler(error) @error_handler(error)
@ -118,7 +138,8 @@ class Group(controllers.Controller):
me = groups[userName] me = groups[userName]
except: except:
me = UserGroup() me = UserGroup()
return dict(userName=userName, groups=groups, group=group, me=me) u = Person.byUserName(userName)
return dict(userName=userName, u=u, groups=groups, group=group, me=me)
@identity.require(turbogears.identity.not_anonymous()) @identity.require(turbogears.identity.not_anonymous())
@expose(template="fas.templates.group.new") @expose(template="fas.templates.group.new")
@ -134,7 +155,7 @@ class Group(controllers.Controller):
@validate(validators=createGroup()) @validate(validators=createGroup())
@error_handler(error) @error_handler(error)
@expose(template="fas.templates.group.new") @expose(template="fas.templates.group.new")
def create(self, groupName, fedoraGroupDesc, fedoraGroupOwner, fedoraGroupNeedsSponsor='FALSE', fedoraGroupUserCanRemove='FALSE', fedoraGroupRequires='', fedoraGroupJoinMsg=''): def create(self, groupName, fedoraGroupDesc, fedoraGroupOwner, fedoraGroupType, fedoraGroupNeedsSponsor='FALSE', fedoraGroupUserCanRemove='FALSE', fedoraGroupRequires='', fedoraGroupJoinMsg=''):
'''Create a group''' '''Create a group'''
userName = turbogears.identity.current.user_name userName = turbogears.identity.current.user_name
if not canCreateGroup(userName): if not canCreateGroup(userName):
@ -144,6 +165,7 @@ class Group(controllers.Controller):
fas.fasLDAP.Group.newGroup(groupName, fas.fasLDAP.Group.newGroup(groupName,
fedoraGroupDesc, fedoraGroupDesc,
fedoraGroupOwner, fedoraGroupOwner,
fedoraGroupType,
fedoraGroupNeedsSponsor, fedoraGroupNeedsSponsor,
fedoraGroupUserCanRemove, fedoraGroupUserCanRemove,
fedoraGroupRequires, fedoraGroupRequires,
@ -182,7 +204,7 @@ class Group(controllers.Controller):
@validate(validators=editGroup()) @validate(validators=editGroup())
@error_handler(error) @error_handler(error)
@expose() @expose()
def save(self, groupName, fedoraGroupDesc, fedoraGroupOwner, fedoraGroupType=1, fedoraGroupNeedsSponsor="FALSE", fedoraGroupUserCanRemove="FALSE", fedoraGroupRequires="", fedoraGroupJoinMsg=""): def save(self, groupName, fedoraGroupDesc, fedoraGroupOwner, fedoraGroupType, fedoraGroupNeedsSponsor="FALSE", fedoraGroupUserCanRemove="FALSE", fedoraGroupRequires="", fedoraGroupJoinMsg=""):
'''Edit a group''' '''Edit a group'''
userName = turbogears.identity.current.user_name userName = turbogears.identity.current.user_name
if fedoraGroupRequires is None: if fedoraGroupRequires is None:
@ -233,9 +255,9 @@ class Group(controllers.Controller):
applicant = turbogears.identity.current.user_name applicant = turbogears.identity.current.user_name
if not userName: if not userName:
userName = applicant userName = applicant
if not canApplyGroup(applicant, groupName, userName): if not canApplyGroup(applicant, groupName, userName)['status']:
turbogears.flash(_('%(user)s could not apply to %(group)s!') % \ turbogears.flash(_('%(user)s could not apply to %(group)s! This group requires membership in %(requires)s') % \
{'user': userName, 'group': groupName}) {'user': userName, 'group': groupName, 'requires': canApplyGroup(applicant, groupName, userName)['requires']})
turbogears.redirect('/group/view/%s' % groupName) turbogears.redirect('/group/view/%s' % groupName)
return dict() return dict()
else: else:
@ -287,16 +309,13 @@ class Group(controllers.Controller):
group = Groups.groups(groupName)[groupName] group = Groups.groups(groupName)[groupName]
import turbomail import turbomail
message = turbomail.Message(config.get('accounts_mail'), p.mail, "Your Fedora '%s' membership has been sponsored" % groupName) message = turbomail.Message(config.get('accounts_mail'), p.mail, "Your Fedora '%s' membership has been sponsored" % groupName)
user = Person.byUserName(userName)
name = user.givenName
email = user.mail
message.plain = dedent(''' message.plain = dedent('''
%(name)s <%(email)s> has sponsored you for membership in the %(group)s %(name)s <%(email)s> has sponsored you for membership in the %(group)s
group of the Fedora account system. If applicable, this change should group of the Fedora account system. If applicable, this change should
propagate into the e-mail aliases and CVS repository within an hour. propagate into the e-mail aliases and CVS repository within an hour.
%(joinmsg)s %(joinmsg)s
''') % {'group': groupName, 'name': name, 'email': email, 'joinmsg': group.fedoraGroupJoinMsg} ''') % {'group': groupName, 'name': user.givenName, 'email': user.mail, 'joinmsg': group.fedoraGroupJoinMsg}
turbomail.enqueue(message) turbomail.enqueue(message)
turbogears.flash(_("'%s' has been sponsored!") % p.cn) turbogears.flash(_("'%s' has been sponsored!") % p.cn)
turbogears.redirect('/group/view/%s' % groupName) turbogears.redirect('/group/view/%s' % groupName)
@ -322,18 +341,16 @@ class Group(controllers.Controller):
{'name': userName, 'group': groupName}) {'name': userName, 'group': groupName})
turbogears.redirect('/group/view/%s' % groupName) turbogears.redirect('/group/view/%s' % groupName)
else: else:
user = Person.byUserName(sponsor)
import turbomail import turbomail
message = turbomail.Message(config.get('accounts_mail'), p.mail, "Your Fedora '%s' membership has been removed" % groupName) sponsor = Person.byUserName(sponsor)
user = Person.byUserName(userName) user = Person.byUserName(userName)
name = user.givenName message = turbomail.Message(config.get('accounts_mail'), user.mail, "Your Fedora '%s' membership has been removed" % groupName)
email = user.mail
message.plain = dedent(''' message.plain = dedent('''
%(name)s <%(email)s> has removed you from the '%(group)s' %(name)s <%(email)s> has removed you from the '%(group)s'
group of the Fedora Accounts System This change is effective group of the Fedora Accounts System This change is effective
immediately for new operations, and should propagate into the e-mail immediately for new operations, and should propagate into the e-mail
aliases within an hour. aliases within an hour.
''') % {'group': groupName, 'name': name, 'email': email} ''') % {'group': groupName, 'name': sponsor.name, 'email': sponsor.mail}
turbomail.enqueue(message) turbomail.enqueue(message)
turbogears.flash(_('%(name)s has been removed from %(group)s!') % \ turbogears.flash(_('%(name)s has been removed from %(group)s!') % \
{'name': userName, 'group': groupName}) {'name': userName, 'group': groupName})
@ -367,8 +384,6 @@ class Group(controllers.Controller):
import turbomail import turbomail
message = turbomail.Message(config.get('accounts_mail'), p.mail, "Your Fedora '%s' membership has been upgraded" % groupName) message = turbomail.Message(config.get('accounts_mail'), p.mail, "Your Fedora '%s' membership has been upgraded" % groupName)
user = Person.byUserName(userName) user = Person.byUserName(userName)
name = user.givenName
email = user.mail
g = Groups.byUserName(userName) g = Groups.byUserName(userName)
status = g[groupName].fedoraRoleType.lower() status = g[groupName].fedoraRoleType.lower()
message.plain = dedent(''' message.plain = dedent('''
@ -376,7 +391,7 @@ class Group(controllers.Controller):
'%(group)s' group of the Fedora Accounts System This change is '%(group)s' group of the Fedora Accounts System This change is
effective immediately for new operations, and should propagate effective immediately for new operations, and should propagate
into the e-mail aliases within an hour. into the e-mail aliases within an hour.
''') % {'group': groupName, 'name': name, 'email': email, 'status': status} ''') % {'group': groupName, 'name': user.givenName, 'email': user.mail, 'status': status}
turbomail.enqueue(message) turbomail.enqueue(message)
turbogears.flash(_('%s has been upgraded!') % userName) turbogears.flash(_('%s has been upgraded!') % userName)
turbogears.redirect('/group/view/%s' % groupName) turbogears.redirect('/group/view/%s' % groupName)
@ -438,3 +453,45 @@ class Group(controllers.Controller):
groups = Groups.byGroupName(groupName) groups = Groups.byGroupName(groupName)
return dict(groups=groups, Person=Person) return dict(groups=groups, Person=Person)
@identity.require(identity.not_anonymous())
@validate(validators=groupNameExists())
@error_handler(error)
@expose(template='fas.templates.group.invite')
def invite(self, groupName):
userName = turbogears.identity.current.user_name
user = Person.byUserName(userName)
return dict(user=user, group=groupName)
@identity.require(identity.not_anonymous())
@validate(validators=groupNameExists())
@error_handler(error)
@expose(template='fas.templates.group.invite')
def sendinvite(self, groupName, target=None):
import turbomail
userName = turbogears.identity.current.user_name
user = Person.byUserName(userName)
if isApproved(userName, groupName):
message = turbomail.Message(user.mail, target, _('Come join The Fedora Project!'))
message.plain = _(dedent('''
%(name)s <%(email)s> has invited you to join the Fedora
Project! We are a community of users and developers who produce a
complete operating system from entirely free and open source software
(FOSS). %(name)s thinks that you have knowledge and skills
that make you a great fit for the Fedora community, and that you might
be interested in contributing.
How could you team up with the Fedora community to use and develop your
skills? Check out http://fedoraproject.org/join-fedora for some ideas.
Our community is more than just software developers -- we also have a
place for you whether you're an artist, a web site builder, a writer, or
a people person. You'll grow and learn as you work on a team with other
very smart and talented people.
Fedora and FOSS are changing the world -- come be a part of it!''')) % {'name': user.givenName, 'email': user.mail}
turbomail.enqueue(message)
turbogears.flash(_('Message sent to: %s') % target)
turbogears.redirect('/group/view/%s' % groupName)
else:
turbogears.flash(_("You are not in the '%s' group.") % groupName)
return dict(target=target, user=user)

View file

@ -225,7 +225,7 @@ a
.userbox dd .userbox dd
{ {
margin-left: 22ex; margin-left: 24ex;
} }
.account .account
@ -324,6 +324,11 @@ a
background: url(/fas/static/images/queue.png) 0 50% no-repeat; background: url(/fas/static/images/queue.png) 0 50% no-repeat;
} }
#rolespanel .queue strong
{
color: #222222;
}
#footer #footer
{ {
font-size: 1.6ex; font-size: 1.6ex;

View file

@ -4,19 +4,19 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Fedora Accounts System</title> <title>${_('Fedora Accounts System')}</title>
</head> </head>
<body> <body>
<!-- Click-through CLA --> <!-- Click-through CLA -->
<h2>Contributor License Agreement</h2> <h2>${_('Contributor License Agreement')}</h2>
<xi:include href="cla.html" /> <xi:include href="cla.html" />
<form action="${tg.url('/cla/click/%s' % userName)}" method="post"> <form action="${tg.url('/cla/click/%s' % userName)}" method="post">
<div> <div>
If you agree to these terms and conditions, type "I agree" here: <input type="text" id="agree" name="agree" /><br /> ${_('If you agree to these terms and conditions, type "I agree" here:')} <input type="text" id="agree" name="agree" /><br />
Full Name: ${user.givenName}<br /> ${_('Full Name:')} ${user.givenName}<br />
E-mail: ${user.mail}<br /> ${_('E-mail:')} ${user.mail}<br />
Date: ${date}<br /> ${_('Date:')} ${date}<br />
<input type="submit" value="Submit CLA" /> <input type="submit" value="${_('Submit CLA')}" />
</div> </div>
</form> </form>
</body> </body>

View file

@ -4,19 +4,19 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Fedora Accounts System</title> <title>${_('Fedora Accounts System')}</title>
</head> </head>
<body> <body>
<h2>Fedora Contributor License Agreement</h2> <h2>${_('Fedora Contributor License Agreement')}</h2>
<p> <p>
There are two ways to sign the CLA... <a href="http://fedoraproject.org/wiki/Legal/CLAAcceptanceHierarchies">CLA Acceptance Hierarchies</a> ${Markup(_('There are two ways to sign the CLA. Most users will want to do a signed CLA as it will promote them to a full contributor in Fedora. The click-through CLA only grants partial access but may be preferred for those with special legal considerations. See: &lt;a href="http://fedoraproject.org/wiki/Legal/CLAAcceptanceHierarchies"&gt;CLA Acceptance Hierarchies&lt;/a&gt; for more information.'))}
</p> </p>
<ul py:if="not signedCLA"> <ul py:if="not signedCLA">
<li><a href="${tg.url('/cla/view/sign')}">Signed CLA</a></li> <li><a href="${tg.url('/cla/view/sign')}">${_('Signed CLA')}</a></li>
<li py:if="not clickedCLA"><a href="${tg.url('/cla/view/click')}">Click-through CLA</a></li> <li py:if="not clickedCLA"><a href="${tg.url('/cla/view/click')}">${_('Click-through CLA')}</a></li>
</ul> </ul>
<p py:if="signedCLA"> <p py:if="signedCLA">
Congratulations, you have already sucessfully signed the <a href="${tg.url('/cla/view')}">CLA</a>. ${Markup(_('You have already sucessfully signed the &lt;a href="%s"&gt;CLA&lt;/a&gt;.') % tg.url('/cla/view'))}
</p> </p>
</body> </body>
</html> </html>

View file

@ -4,20 +4,20 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Fedora Accounts System</title> <title>${_('Fedora Accounts System')}</title>
</head> </head>
<body> <body>
<!-- Signed CLA --> <!-- Signed CLA -->
<h2>Contributor License Agreement</h2> <h2>${_('Contributor License Agreement')}</h2>
<p> <p>
Use the below link to download/save the CLA as fedora-icla-${tg.identity.user.user_name}.txt, run gpg -as fedora-icla-${tg.identity.user.user_name}.txt, and upload fedora-icla-${tg.identity.user.user_name}.txt.asc in the form below. ${_('Use the below link to download/save the CLA as fedora-icla-%(user)s.txt, run gpg -as fedora-icla-${tg.identity.user.user_name}.txt, and upload fedora-icla-%(user)s.txt.asc in the form below.') % {'user': tg.identity.user.user_name}}
</p> </p>
<a href="${tg.url('/cla/download')}">Download the CLA text file here!</a> <a href="${tg.url('/cla/download')}">${_('Download the CLA text file here!')}</a>
<form action="${tg.url('/cla/sign')}" method="post" enctype="multipart/form-data"> <form action="${tg.url('/cla/sign')}" method="post" enctype="multipart/form-data">
<div> <div>
<label for="signature">Signed CLA:</label> <input type="file" id="signature" name="signature" /><br /> <label for="signature">${_('Signed CLA:')}</label> <input type="file" id="signature" name="signature" /><br />
<input type="submit" value="Submit CLA" /> <input type="submit" value="${_('Submit CLA')}" />
</div> </div>
</form> </form>
</body> </body>

View file

@ -4,11 +4,11 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Fedora Accounts System</title> <title>${_('Fedora Accounts System')}</title>
</head> </head>
<body> <body>
<!-- Click-through CLA --> <!-- Click-through CLA -->
<h2>Contributor License Agreement</h2> <h2>${_('Contributor License Agreement')}</h2>
<div py:if="type is None" py:strip=''> <div py:if="type is None" py:strip=''>
<xi:include href="cla.html" /> <xi:include href="cla.html" />
</div> </div>
@ -17,28 +17,28 @@
<xi:include href="cla.html" /> <xi:include href="cla.html" />
<form action="${tg.url('/cla/click')}" method="post"> <form action="${tg.url('/cla/click')}" method="post">
<div> <div>
If you agree to these terms and conditions, type "I agree" here: <input type="text" id="agree" name="agree" /><br /> ${_('If you agree to these terms and conditions, type "I agree" here:')} <input type="text" id="agree" name="agree" /><br />
Full Name: ${user.givenName}<br /> ${_('Full Name:')} ${user.givenName}<br />
E-mail: ${user.mail}<br /> ${_('E-mail:')} ${user.mail}<br />
Date: ${date}<br /> ${_('Date:')} ${date}<br />
<input type="submit" value="Submit CLA" /> <input type="submit" value="${_('Submit CLA')}" />
</div> </div>
</form> </form>
</div> </div>
<div py:if="type == 'sign'" py:strip=''> <div py:if="type == 'sign'" py:strip=''>
<p> <p>
Use the below link to download/save the CLA as fedora-icla-${user.cn}.txt, and run: ${_('Use the below link to download/save the CLA as fedora-icla-${user.cn}.txt, and run:
<pre>gpg -as fedora-icla-${user.cn}.txt</pre> &lt;pre&gt;gpg -as fedora-icla-${user.cn}.txt&lt;/pre&gt;
After, upload fedora-icla-${user.cn}.txt.asc in the form below. After, upload fedora-icla-${user.cn}.txt.asc in the form below.')}
</p> </p>
<p> <p>
<a href="${tg.url('/cla/download')}">Download the CLA text file here!</a> <a href="${tg.url('/cla/download')}">${_('Download the CLA text file here!')}</a>
</p> </p>
<form action="${tg.url('/cla/sign')}" method="post" enctype="multipart/form-data"> <form action="${tg.url('/cla/sign')}" method="post" enctype="multipart/form-data">
<div> <div>
<label for="signature">Signed CLA:</label> <input type="file" id="signature" name="signature" /><br /> <label for="signature">${_('Signed CLA:')}</label> <input type="file" id="signature" name="signature" /><br />
<input type="submit" value="Submit CLA" /> <input type="submit" value="${_('Submit CLA')}" />
</div> </div>
</form> </form>
</div> </div>

View file

@ -4,7 +4,7 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="master.html" /> <xi:include href="master.html" />
<head> <head>
<title>Fedora Accounts System</title> <title>${_('Fedora Accounts System')}</title>
<style type="text/css"> <style type="text/css">
#content ul #content ul
{ {
@ -14,8 +14,8 @@
</style> </style>
</head> </head>
<body> <body>
<h2>Error!</h2> <h2>${_('Error!')}</h2>
<p>The following error(s) have occured with your request:</p> <p>${_('The following error(s) have occured with your request:')}</p>
<ul> <ul>
<li py:for="field, error in tg_errors.items()"> <li py:for="field, error in tg_errors.items()">
${field}: ${str(error)} ${field}: ${str(error)}

View file

@ -4,39 +4,39 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Edit Group</title> <title>${_('Edit Group')}</title>
</head> </head>
<body> <body>
<h2>Edit Group: ${group.cn}</h2> <h2>${_('Edit Group: %s') % group.cn}</h2>
<form action="${tg.url('/group/save/%s' % group.cn)}" method="post"> <form action="${tg.url('/group/save/%s' % group.cn)}" method="post">
<div class="field"> <div class="field">
<label for="fedoraGroupDesc">Description:</label> <label for="fedoraGroupDesc"${_('Description:')}/label>
<input type="text" id="fedoraGroupDesc" name="fedoraGroupDesc" value="${group.fedoraGroupDesc}" /> <input type="text" id="fedoraGroupDesc" name="fedoraGroupDesc" value="${group.fedoraGroupDesc}" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupOwner">Group Owner:</label> <label for="fedoraGroupOwner"${_('Group Owner:')}/label>
<input type="text" id="fedoraGroupOwner" name="fedoraGroupOwner" value="${group.fedoraGroupOwner}" /> <input type="text" id="fedoraGroupOwner" name="fedoraGroupOwner" value="${group.fedoraGroupOwner}" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupNeedsSponsor">Needs Sponsor:</label> <label for="fedoraGroupNeedsSponsor"${_('Needs Sponsor:')}/label>
<input py:if="group.fedoraGroupNeedsSponsor" type="checkbox" id="fedoraGroupNeedsSponsor" name="fedoraGroupNeedsSponsor" value="TRUE" checked="checked" /> <input py:if="group.fedoraGroupNeedsSponsor" type="checkbox" id="fedoraGroupNeedsSponsor" name="fedoraGroupNeedsSponsor" value="TRUE" checked="checked" />
<input py:if="not group.fedoraGroupNeedsSponsor" type="checkbox" id="fedoraGroupNeedsSponsor" name="fedoraGroupNeedsSponsor" value="TRUE" /> <input py:if="not group.fedoraGroupNeedsSponsor" type="checkbox" id="fedoraGroupNeedsSponsor" name="fedoraGroupNeedsSponsor" value="TRUE" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupUserCanRemove">Self Removal:</label> <label for="fedoraGroupUserCanRemove"${_('Self Removal:')}/label>
<input py:if="group.fedoraGroupUserCanRemove" type="checkbox" id="fedoraGroupUserCanRemove" name="fedoraGroupUserCanRemove" value="TRUE" checked="checked" /> <input py:if="group.fedoraGroupUserCanRemove" type="checkbox" id="fedoraGroupUserCanRemove" name="fedoraGroupUserCanRemove" value="TRUE" checked="checked" />
<input py:if="not group.fedoraGroupUserCanRemove" type="checkbox" id="fedoraGroupUserCanRemove" name="fedoraGroupUserCanRemove" value="TRUE" /> <input py:if="not group.fedoraGroupUserCanRemove" type="checkbox" id="fedoraGroupUserCanRemove" name="fedoraGroupUserCanRemove" value="TRUE" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupRequires">Must Belong To:</label> <label for="fedoraGroupRequires"${_('Must Belong To:')}/label>
<input type="text" id="fedoraGroupRequires" name="fedoraGroupRequires" value="${group.fedoraGroupRequires}" /> <input type="text" id="fedoraGroupRequires" name="fedoraGroupRequires" value="${group.fedoraGroupRequires}" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupJoinMsg">Group Join Message:</label> <label for="fedoraGroupJoinMsg"${_('Group Join Message:')}/label>
<input type="text" id="fedoraGroupJoinMsg" name="fedoraGroupJoinMsg" value="${group.fedoraGroupJoinMsg}" /> <textarea id="fedoraGroupJoinMsg" name="fedoraGroupJoinMsg">${group.fedoraGroupJoinMsg}</textarea>
</div> </div>
<div class="field"> <div class="field">
<input type="submit" value="Save!" /> <input type="submit" value="${_('Save!')}" />
</div> </div>
</form> </form>
</body> </body>

View file

@ -2,18 +2,19 @@
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/" xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Invite a new community member!</title> <title>${_('Invite a new community member!')}</title>
</head> </head>
<body> <body>
<h2>Invite a new community member!</h2> <h2>${_('Invite a new community member!')}</h2>
<form method="post"> <form method="post" action="${tg.url('/group/sendinvite/%s') % group}">
<div> <div>
To email: <input type="text" value="" name="target" /><br /> <!--TODO: Make the email translatable -->
From: ${user.mail}<br /> ${_('To email:')} <input type="text" value="" name="target" /><br />
Subject: Invitation to join the Fedora Team!<br /> ${_('From:)} ${user.mail}<br />
Message: ${_('Subject:')} Invitation to join the Fedora Team!<br />
${_('Message:')}
<div class="message"> <div class="message">
<p> <p>
${user.givenName} &lt;<a href="mailto: ${user.mail}">${user.mail}</a>&gt; has invited you to join the Fedora ${user.givenName} &lt;<a href="mailto: ${user.mail}">${user.mail}</a>&gt; has invited you to join the Fedora
@ -25,7 +26,7 @@
</p> </p>
<p> <p>
How could you team up with the Fedora community to use and develop your How could you team up with the Fedora community to use and develop your
skills? Check out http://fedoraproject.org/wiki/Join for some ideas. skills? Check out http://fedoraproject.org/join-fedora for some ideas.
Our community is more than just software developers -- we also have a Our community is more than just software developers -- we also have a
place for you whether you're an artist, a web site builder, a writer, or place for you whether you're an artist, a web site builder, a writer, or
a people person. You'll grow and learn as you work on a team with other a people person. You'll grow and learn as you work on a team with other
@ -35,7 +36,7 @@
Fedora and FOSS are changing the world -- come be a part of it! Fedora and FOSS are changing the world -- come be a part of it!
</p> </p>
</div> </div>
<input type="submit" value="Send" /> <input type="submit" value="${_('Send!')}" />
</div> </div>
</form> </form>
</body> </body>

View file

@ -4,28 +4,28 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Groups List</title> <title>${_('Groups List')}</title>
</head> </head>
<body> <body>
<?python from fas import auth ?> <?python from fas import auth ?>
<h2>List (${search})</h2> <h2>${_('List (%s)') % search}</h2>
<h3>Search Groups</h3> <h3>${_('Search Groups')}</h3>
<form method="get" action="${tg.url('/group/list')}"> <form method="get" action="${tg.url('/group/list')}">
<p>"*" is a wildcard (Ex: "cvs*")</p> <p>${_('"*" is a wildcard (Ex: "cvs*")')}</p>
<div> <div>
<input type="text" value="${search}" name="search" size="15 "/> <input type="text" value="${search}" name="search" size="15 "/>
<input type="submit" value="Search" /> <input type="submit" value="${_('Search')}" />
</div> </div>
</form> </form>
<h3>Results</h3> <h3>${_('Results')}</h3>
<ul class="letters"> <ul class="letters">
<li py:for="letter in 'abcdefghijklmnopqrstuvwxyz'.upper()"><a href="${tg.url('/group/list/%s*' % letter)}">${letter}</a></li> <li py:for="letter in 'abcdefghijklmnopqrstuvwxyz'.upper()"><a href="${tg.url('/group/list/%s*' % letter)}">${letter}</a></li>
<li><a href="${tg.url('/group/list/*')}">All</a></li> <li><a href="${tg.url('/group/list/*')}">${_('All')}</a></li>
</ul> </ul>
<table py:if="groups"> <table py:if="groups">
<thead> <thead>
<tr><th>Group</th><th>Description</th><th>Status</th></tr> <tr><th>${_('Group')}</th><th>${_('Description')}</th><th>${_('Status')}</th></tr>
</thead> </thead>
<tbody> <tbody>
<tr py:for="group in sorted(groups.keys())"> <tr py:for="group in sorted(groups.keys())">
@ -34,10 +34,10 @@
<td>${groups[group].fedoraGroupDesc}</td> <td>${groups[group].fedoraGroupDesc}</td>
<td> <td>
<a py:if="group in myGroups" href="${tg.url('/group/view/%s' % group)}"> <a py:if="group in myGroups" href="${tg.url('/group/view/%s' % group)}">
<span class="approved" py:if="myGroups[group].fedoraRoleStatus.lower() == 'approved'">Approved</span> <span class="approved" py:if="myGroups[group].fedoraRoleStatus.lower() == 'approved'">${_('Approved')}</span>
<span class="unapproved" py:if="myGroups[group].fedoraRoleStatus.lower() == 'unapproved'">Unapproved</span> <span class="unapproved" py:if="myGroups[group].fedoraRoleStatus.lower() == 'unapproved'">${_('Unapproved')}</span>
</a> </a>
<a py:if="group not in myGroups" href="${tg.url('/group/apply/%s/%s' % (group, tg.identity.user.user_name))}"><span>Apply</span></a> <a py:if="group not in myGroups" href="${tg.url('/group/apply/%s/%s' % (group, tg.identity.user.user_name))}"><span>${_('Apply')}</span></a>
</td> </td>
</div> </div>
</tr> </tr>

View file

@ -4,41 +4,45 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Create a new FAS Group</title> <title>${_('Create a new FAS Group')}</title>
</head> </head>
<body> <body>
<h2>Create a new FAS Group</h2> <h2>${_('Create a new FAS Group')}</h2>
<form action="${tg.url('/group/create')}" method="post"> <form action="${tg.url('/group/create')}" method="post">
<div class="field"> <div class="field">
<label for="groupName">Group Name:</label> <label for="groupName"${_('Group Name:')}/label>
<input type="text" id="groupName" name="groupName" /> <input type="text" id="groupName" name="groupName" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupDesc">Description:</label> <label for="fedoraGroupDesc"${_('Description:')}/label>
<input type="text" id="fedoraGroupDesc" name="fedoraGroupDesc" /> <input type="text" id="fedoraGroupDesc" name="fedoraGroupDesc" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupOwner">Group Owner:</label> <label for="fedoraGroupOwner"${_('Group Owner:')}/label>
<input type="text" id="fedoraGroupOwner" name="fedoraGroupOwner" /> <input type="text" id="fedoraGroupOwner" name="fedoraGroupOwner" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupNeedsSponsor">Needs Sponsor:</label> <label for="fedoraGroupType"${_('Group Type:')}/label>
<input type="text" id="fedoraGroupType" name="fedoraGroupType" value="tracking" />
</div>
<div class="field">
<label for="fedoraGroupNeedsSponsor"${_('Needs Sponsor:')}/label>
<input type="checkbox" id="fedoraGroupNeedsSponsor" name="fedoraGroupNeedsSponsor" value="TRUE" checked="checked" /> <input type="checkbox" id="fedoraGroupNeedsSponsor" name="fedoraGroupNeedsSponsor" value="TRUE" checked="checked" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupUserCanRemove">Self Removal:</label> <label for="fedoraGroupUserCanRemove"${_('Self Removal:')}/label>
<input type="checkbox" id="fedoraGroupUserCanRemove" name="fedoraGroupUserCanRemove" value="TRUE" checked="checked" /> <input type="checkbox" id="fedoraGroupUserCanRemove" name="fedoraGroupUserCanRemove" value="TRUE" checked="checked" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupRequires">Must Belong To:</label> <label for="fedoraGroupRequires"${_('Must Belong To:')}/label>
<input type="text" id="fedoraGroupRequires" name="fedoraGroupRequires" value="cla_done" /> <input type="text" id="fedoraGroupRequires" name="fedoraGroupRequires" value="cla_done" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraGroupJoinMsg">Join Message:</label> <label for="fedoraGroupJoinMsg"${_('Join Message:')}/label>
<input type="text" id="fedoraGroupJoinMsg" name="fedoraGroupJoinMsg" /> <textarea id="fedoraGroupJoinMsg" name="fedoraGroupJoinMsg"></textarea>
</div> </div>
<div class="field"> <div class="field">
<input type="submit" value="Create!" /> <input type="submit" value="${_('Create!')}" />
</div> </div>
</form> </form>
</body> </body>

View file

@ -4,66 +4,71 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Edit Group</title> <title>${_('Edit Group')}</title>
</head> </head>
<body> <body>
<?python from fas import auth ?> <?python from fas import auth ?>
<h2>${group.fedoraGroupDesc} (${group.cn})</h2> <h2>${group.fedoraGroupDesc} (${group.cn})</h2>
<h3> <h3>
My Status: ${_('My Status:')}
<span py:if="auth.isApproved(userName, group.cn)" class="approved">Approved</span> <span py:if="auth.isApproved(userName, group.cn)" class="approved">${_('Approved')}</span>
<span py:if="not auth.isApproved(userName, group.cn)" class="unapproved">Unapproved</span> <span py:if="not auth.isApproved(userName, group.cn)" class="unapproved">${_('Unapprove')}d</span>
<span py:if="'Not a Member' in me.fedoraRoleStatus">Not a Member</span> <span py:if="'Not a Member' in me.fedoraRoleStatus">${_('Not a Member')}</span>
</h3> </h3>
<form py:if="'Not a Member' in me.fedoraRoleStatus" action="${tg.url('/group/apply/%s/%s' % (group.cn, userName))}"> <form py:if="'Not a Member' in me.fedoraRoleStatus" action="${tg.url('/group/apply/%s/%s' % (group.cn, userName))}">
<div> <div>
<!--<input type="text" name="requestField" value="Please let me join..." />--> <!--<input type="text" name="requestField" value="${_('Please let me join...')}" />-->
<input type="submit" value="Join!" /> <input type="submit" value="${('Apply!')}" />
</div> </div>
</form> </form>
<a py:if="'Not a Member' not in me.fedoraRoleStatus" href="${tg.url('/group/remove/%s/%s' % (group.cn, userName))}">Remove me</a> <a py:if="'Not a Member' not in me.fedoraRoleStatus" href="${tg.url('/group/remove/%s/%s' % (group.cn, userName))}">${_('Remove me')}</a>
<h3>Group Details <a href="${tg.url('/group/edit/%s' % group.cn)}">(edit)</a></h3> <h3>Group Details <a href="${tg.url('/group/edit/%s' % group.cn)}">${_('(edit)')}</a></h3>
<div class="userbox"> <div class="userbox">
<dl> <dl>
<dt>Name:</dt><dd>${group.cn}</dd> <dt>${_('Name:')}</dt><dd>${group.cn}</dd>
<dt>Description:</dt><dd>${group.fedoraGroupDesc}</dd> <dt>${_('Description:')}</dt><dd>${group.fedoraGroupDesc}</dd>
<dt>Owner:</dt><dd>${group.fedoraGroupOwner}</dd> <dt>${_('Owner:')}</dt><dd>${group.fedoraGroupOwner}</dd>
<dt>Type:</dt><dd>${group.fedoraGroupType}</dd> <dt>${_('Type:')}</dt><dd>${group.fedoraGroupType}</dd>
<dt>Needs Sponsor:</dt><dd> <dt>${_('Needs Sponsor:')}</dt><dd>
<span py:if="group.fedoraGroupNeedsSponsor == 'TRUE'" py:strip="">Yes</span> <span py:if="group.fedoraGroupNeedsSponsor == 'TRUE'" py:strip="">${_('Yes')}</span>
<span py:if="group.fedoraGroupNeedsSponsor == 'FALSE'" py:strip="">No</span> <span py:if="group.fedoraGroupNeedsSponsor == 'FALSE'" py:strip="">${_('No')}</span>
</dd> </dd>
<dt>Self Removal</dt><dd> <dt>${_('Self Removal:')}</dt><dd>
<span py:if="group.fedoraGroupUserCanRemove == 'TRUE'" py:strip="">Yes</span> <span py:if="group.fedoraGroupUserCanRemove == 'TRUE'" py:strip="">${_('Yes')}</span>
<span py:if="group.fedoraGroupUserCanRemove == 'FALSE'" py:strip="">No</span> <span py:if="group.fedoraGroupUserCanRemove == 'FALSE'" py:strip="">${_('No')}</span>
</dd> </dd>
<dt>Join Message:</dt><dd>${group.fedoraGroupJoinMsg}</dd> <dt>${_('Join Message:')}</dt><dd>${group.fedoraGroupJoinMsg}</dd>
</dl> </dl>
</div> </div>
<!-- <!--
TODO: Implement this :) TODO: Implement this :)
<h3 py:if='me.fedoraRoleStatus == "approved"'>Invite</h3> <h3 py:if='me.fedoraRoleStatus == "approved"'>${_('Invite')}</h3>
<span py:if='me.fedoraRoleStatus == "approved"'>${form(action='modifyGroup', value=value, method='get')}</span> <span py:if='me.fedoraRoleStatus == "approved"'>${form(action='modifyGroup', value=value, method='get')}</span>
--> -->
<h3>Members</h3> <h3>${_('Members')}</h3>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>Username</th> <th>${_('Username')}</th>
<th>Sponsor</th> <th>${_('Sponsor')}</th>
<th>Date Added</th> <th>${_('Date Added')}</th>
<th>Date Approved</th> <th>${_('Date Approved')}</th>
<th>Approval</th> <th>${_('Approval')}</th>
<th>Role Type</th> <th>${_('Role Type')}</th>
<th py:if="auth.canSponsorGroup(userName, group.cn)">Action</th> <th py:if="auth.canSponsorGroup(userName, group.cn)">${_('Action')}</th>
</tr> </tr>
</thead> </thead>
<tr py:for="user in sorted(groups.keys())"> <tr py:for="user in sorted(groups.keys())">
<td><a href="${tg.url('/user/view/%s' % user)}">${user}</a></td> <td><a href="${tg.url('/user/view/%s' % user)}">${user}</a></td>
<td py:if='not(groups[user].fedoraRoleSponsor == "None")'><a href="${tg.url('/user/view/%s' % groups[user].fedoraRoleSponsor)}">${groups[user].fedoraRoleSponsor}</a></td> <td py:if='not(groups[user].fedoraRoleSponsor == "None")'><a href="${tg.url('/user/view/%s' % groups[user].fedoraRoleSponsor)}">${groups[user].fedoraRoleSponsor}</a></td>
<td py:if='groups[user].fedoraRoleSponsor == "None"'>None</td> <td py:if='groups[user].fedoraRoleSponsor == "None"'>${_('None')}</td>
<td>${groups[user].fedoraRoleCreationDate}</td> <?python
<td>${groups[user].fedoraRoleApprovalDate}</td> from datetime import datetime
from pytz import timezone
?>
<td>${datetime.fromtimestamp(float(groups[user].fedoraRoleCreationDate), timezone(u.fedoraPersonTimeZone)).strftime('%F %R %Z')}</td>
<td py:if="groups[user].fedoraRoleApprovalDate.lower() == 'none'">${groups[user].fedoraRoleApprovalDate}</td>
<td py:if="groups[user].fedoraRoleApprovalDate.lower() != 'none'">${datetime.fromtimestamp(float(groups[user].fedoraRoleApprovalDate), timezone(u.fedoraPersonTimeZone)).strftime('%F %R %Z')}</td>
<td>${groups[user].fedoraRoleStatus}</td> <td>${groups[user].fedoraRoleStatus}</td>
<td>${groups[user].fedoraRoleType}</td> <td>${groups[user].fedoraRoleType}</td>
<!--<td>${groups[user].fedoraRoleDomain}</td>--> <!--<td>${groups[user].fedoraRoleDomain}</td>-->
@ -72,18 +77,18 @@
<ul> <ul>
<li py:if="groups[user].fedoraRoleStatus.lower() != 'approved'"> <li py:if="groups[user].fedoraRoleStatus.lower() != 'approved'">
<a py:if="group.fedoraGroupNeedsSponsor.upper() == 'TRUE'" <a py:if="group.fedoraGroupNeedsSponsor.upper() == 'TRUE'"
href="${tg.url('/group/sponsor/%s/%s' % (groups[user].cn, user))}">Sponsor</a> href="${tg.url('/group/sponsor/%s/%s' % (groups[user].cn, user))}">${_('Sponsor')}</a>
<a py:if="not group.fedoraGroupNeedsSponsor.upper() == 'TRUE'" <a py:if="not group.fedoraGroupNeedsSponsor.upper() == 'TRUE'"
href="${tg.url('/group/sponsor/%s/%s' % (groups[user].cn, user))}">Approve</a> href="${tg.url('/group/sponsor/%s/%s' % (groups[user].cn, user))}">${_('Approve')}</a>
</li> </li>
<li py:if="auth.canRemoveUser(tg.identity.user.user_name, group.cn, userName)"> <li py:if="auth.canRemoveUser(tg.identity.user.user_name, group.cn, userName)">
<a href="${tg.url('/group/remove/%s/%s' % (groups[user].cn, user))}">Remove</a> <a href="${tg.url('/group/remove/%s/%s' % (groups[user].cn, user))}">${_('Remove')}</a>
</li> </li>
<li py:if="auth.canUpgradeUser(tg.identity.user.user_name, group.cn, userName)"> <li py:if="auth.canUpgradeUser(tg.identity.user.user_name, group.cn, userName)">
<a href="${tg.url('/group/upgrade/%s/%s' % (groups[user].cn, user))}">Upgrade</a> <a href="${tg.url('/group/upgrade/%s/%s' % (groups[user].cn, user))}">${_('Upgrade')}</a>
</li> </li>
<li py:if="auth.canDowngradeUser(tg.identity.user.user_name, group.cn, userName)"> <li py:if="auth.canDowngradeUser(tg.identity.user.user_name, group.cn, userName)">
<a href="${tg.url('/group/downgrade/%s/%s' % (groups[user].cn, user))}">Downgrade</a> <a href="${tg.url('/group/downgrade/%s/%s' % (groups[user].cn, user))}">${_('Downgrade')}</a>
</li> </li>
</ul> </ul>
</td> </td>

View file

@ -4,22 +4,8 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="master.html" /> <xi:include href="master.html" />
<head> <head>
<title>Fedora Accounts System</title> <title>${_('Fedora Accounts System')}</title>
</head> </head>
<body> <body>
<h2 py:if="'userID' in builds.userLink" class="accounts">Recent Builds <a href="${builds.userLink}">(Koji)</a></h2>
<table py:if="'userID' in builds.userLink">
<thead>
<tr><th>Build</th><th>Build Date</th></tr>
</thead>
<!--<tr><td>Koji</td><td><a href="${builds.userLink}">Build Info</a></td></tr>-->
<tr py:for="build in builds.builds">
<td>
<span py:if="'complete' in builds.builds[build]['title']" class="approved"><a href="${build}">${builds.builds[build]['title']}</a></span>
<span py:if="'failed' in builds.builds[build]['title']" class="unapproved"><a href="${build}">${builds.builds[build]['title']}</a></span>
</td>
<td>${builds.builds[build]['pubDate']}</td>
</tr>
</table>
</body> </body>
</html> </html>

View file

@ -4,7 +4,7 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="master.html" /> <xi:include href="master.html" />
<head> <head>
<title>Login to the Fedora Accounts System</title> <title>${_('Login to the Fedora Accounts System')}</title>
<style type="text/css"> <style type="text/css">
#content ul #content ul
{ {
@ -14,20 +14,20 @@
</style> </style>
</head> </head>
<body> <body>
<h2>Login</h2> <h2>${_('Login')}</h2>
<p>${message}</p> <p>${message}</p>
<form action="${previous_url}" method="post"> <form action="${previous_url}" method="post">
<div class="field"><label for="user_name">User Name:</label> <input type="text" id="user_name" name="user_name" /></div> <div class="field"><label for="user_name">${_('User Name:')}</label> <input type="text" id="user_name" name="user_name" /></div>
<div class="field"><label for="password">Password:</label> <input type="password" id="password" name="password" /></div> <div class="field"><label for="password">${_('Password:')}</label> <input type="password" id="password" name="password" /></div>
<div class="field"> <div class="field">
<input type="submit" name="login" value="Login" /> <input type="submit" name="login" value="${_('Login')}" />
<input py:if="forward_url" type="hidden" name="forward_url" value="${tg.url(forward_url)}" /> <input py:if="forward_url" type="hidden" name="forward_url" value="${tg.url(forward_url)}" />
<input py:for="name,value in original_parameters.items()" type="hidden" name="${name}" value="${value}" /> <input py:for="name,value in original_parameters.items()" type="hidden" name="${name}" value="${value}" />
</div> </div>
</form> </form>
<ul> <ul>
<li><a href="${tg.url('/user/resetpass')}">Forgot Password?</a></li> <li><a href="${tg.url('/user/resetpass')}">${_('Forgot Password?')}</a></li>
<li><a href="${tg.url('/user/new')}">Sign Up</a></li> <li><a href="${tg.url('/user/new')}">${_('Sign Up')}</a></li>
</ul> </ul>
</body> </body>
</html> </html>

View file

@ -3,57 +3,60 @@
xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:py="http://genshi.edgewall.org/" xmlns:py="http://genshi.edgewall.org/"
py:strip=""> py:strip="">
<?python
_ = lambda text: tg.gettext(text)
?>
<head py:match="head" py:attrs="select('@*')"> <head py:match="head" py:attrs="select('@*')">
<!--<link href="${tg.url('/static/css/style.css')}" rel="stylesheet" type="text/css" />--> <link href="${tg.url('/static/css/style.css')}" rel="stylesheet" type="text/css" />
<meta py:replace="select('*|text()')" /> <meta py:replace="select('*|text()')" />
</head> </head>
<body py:match="body" py:attrs="select('@*')"> <body py:match="body" py:attrs="select('@*')">
<div id="wrapper"> <div id="wrapper">
<div id="head"> <div id="head">
<h1><a href="http://fedoraproject.org/">Fedora</a></h1> <h1><a href="http://fedoraproject.org/">${_('Fedora')}</a></h1>
<div id="searchbox"> <div id="searchbox">
<form action="" method="get"> <form action="" method="get">
<label for="q">Search:</label> <label for="q">${_('Search:')}</label>
<input type="text" name="q" id="q" /> <input type="text" name="q" id="q" />
<input type="submit" value="Search" /> <input type="submit" value="${_('Search')}" />
</form> </form>
</div> </div>
</div> </div>
<div id="topnav"> <div id="topnav">
<ul> <ul>
<li class="first"><a href="http://fedoraproject.org/">Learn about Fedora</a></li> <li class="first"><a href="http://fedoraproject.org/">${_('Learn about Fedora')}</a></li>
<li><a href="http://fedoraproject.org/get-fedora.html">Download Fedora</a></li> <li><a href="http://fedoraproject.org/get-fedora.html">${_('Download Fedora')}</a></li>
<li><a href="http://fedoraproject.org/wiki/">Projects</a></li> <li><a href="http://fedoraproject.org/wiki/">${_('Projects')}</a></li>
<li><a href="http://fedoraproject.org/join-fedora.html">Join Fedora</a></li> <li><a href="http://fedoraproject.org/join-fedora.html">${_('Join Fedora')}</a></li>
<li><a href="http://fedoraproject.org/wiki/Communicate">Communicate</a></li> <li><a href="http://fedoraproject.org/wiki/Communicate">${_('Communicate')}</a></li>
<li><a href="http://docs.fedoraproject.org/">Help/Documentation</a></li> <li><a href="http://docs.fedoraproject.org/">${_('Help/Documentation')}</a></li>
</ul> </ul>
</div> </div>
<div id="infobar"> <div id="infobar">
<div id="authstatus"> <div id="authstatus">
<span py:if="not tg.identity.anonymous"> <span py:if="not tg.identity.anonymous">
<strong>Logged in:</strong> ${tg.identity.user.user_name} <strong>${_('Logged in:')}</strong> ${tg.identity.user.user_name}
</span> </span>
</div> </div>
<div id="control"> <div id="control">
<ul> <ul>
<li py:if="not tg.identity.anonymous"><a href="${tg.url('/user/view/%s' % tg.identity.user.user_name)}">My Account</a></li> <li py:if="not tg.identity.anonymous"><a href="${tg.url('/user/view/%s' % tg.identity.user.user_name)}">${_('My Account')}</a></li>
<li py:if="not tg.identity.anonymous"><a href="${tg.url('/logout')}">Log Out</a></li> <li py:if="not tg.identity.anonymous"><a href="${tg.url('/logout')}">${_('Log Out')}</a></li>
<li py:if="tg.identity.anonymous"><a href="${tg.url('/login')}">Log In</a></li> <li py:if="tg.identity.anonymous"><a href="${tg.url('/login')}">${_('Log In')}</a></li>
</ul> </ul>
</div> </div>
</div> </div>
<div id="main"> <div id="main">
<div id="sidebar"> <div id="sidebar">
<ul> <ul>
<li class="first"><a href="${tg.url('/group/list')}">Group List</a></li> <li class="first"><a href="${tg.url('/group/list')}">${_('Group List')}</a></li>
<div py:if="'accounts' in tg.identity.groups" py:strip=''> <div py:if="'accounts' in tg.identity.groups" py:strip=''>
<!-- TODO: Make these use auth.py --> <!-- TODO: Make these use auth.py -->
<li><a href="${tg.url('/user/list')}">User List</a></li> <li><a href="${tg.url('/user/list')}">${_('User List')}</a></li>
<li><a href="${tg.url('/group/new')}">New Group</a></li> <li><a href="${tg.url('/group/new')}">${_('New Group')}</a></li>
</div> </div>
<li><a href="${tg.url('/group/list/A*')}">Apply For a new Group</a></li> <li><a href="${tg.url('/group/list/A*')}">${_('Apply For a new Group')}</a></li>
<li><a href="http://fedoraproject.org/wiki/FWN/LatestIssue">News</a></li> <li><a href="http://fedoraproject.org/wiki/FWN/LatestIssue">${_('News')}</a></li>
</ul> </ul>
</div> </div>
<div id="content"> <div id="content">
@ -64,18 +67,17 @@
</div> </div>
<div id="footer"> <div id="footer">
<ul id="footlinks"> <ul id="footlinks">
<li class="first"><a href="/">About</a></li> <li class="first"><a href="/">${_('About')}</a></li>
<li><a href="http://fedoraproject.org/wiki/Communicate">Contact Us</a></li> <li><a href="http://fedoraproject.org/wiki/Communicate">${_('Contact Us')}</a></li>
<li><a href="http://fedoraproject.org/wiki/Legal">Legal &amp; Privacy</a></li> <li><a href="http://fedoraproject.org/wiki/Legal">${_('Legal &amp; Privacy')}</a></li>
<!--<li><a href="/">Site Map</a></li>--> <!--<li><a href="/">Site Map</a></li>-->
<li><a href="${tg.url('/logout')}">Log Out</a></li> <li><a href="${tg.url('/logout')}">${_('Log Out')}</a></li>
</ul> </ul>
<p class="copy"> <p class="copy">
Copyright &copy; 2007 Red Hat, Inc. and others. All Rights Reserved. ${Markup(_('Copyright &copy; 2007 Red Hat, Inc. and others. All Rights Reserved. Please send any comments or corrections to the &lt;a href="mailto:webmaster@fedoraproject.org"&gt;websites team&lt;/a&gt;.'))}
Please send any comments or corrections to the <a href="mailto:webmaster@fedoraproject.org">websites team</a>.
</p> </p>
<p class="disclaimer"> <p class="disclaimer">
The Fedora Project is maintained and driven by the community and sponsored by Red Hat. This is a community maintained site. Red Hat is not responsible for content. ${_('The Fedora Project is maintained and driven by the community and sponsored by Red Hat. This is a community maintained site. Red Hat is not responsible for content.')}
</p> </p>
</div> </div>
</div> </div>

View file

@ -4,12 +4,12 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Fedora Accounts System</title> <title>${_('Fedora Accounts System')}</title>
</head> </head>
<body> <body>
<h2>Fedora Project OpenID Provider</h2> <h2>${_{'Fedora Project OpenID Provider')}</h2>
<p> <p>
Description goes here, <a href="http://username.fedorapeople.org/">username.fedorapeople.org</a> ${Markup_('Description goes here, &lt;a href="http://username.fedorapeople.org/"&gt;username.fedorapeople.org&lt;/a&gt;'))}
</p> </p>
</body> </body>
</html> </html>

View file

@ -4,16 +4,16 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Fedora Accounts System</title> <title>${_('Fedora Accounts System')}</title>
<link rel="openid.server" href="${server}" /> <link rel="openid.server" href="${server}" />
</head> </head>
<body> <body>
<h2>User ${user.cn}</h2> <h2>${_('User %s') % user.cn}</h2>
<div class="userbox"> <div class="userbox">
<dl> <dl>
<dt>Username:</dt> <dt>${_('Username:')}</dt>
<dd> ${user.cn}</dd> <dd>${user.cn}</dd>
<dt>Name:</dt> <dt>${_('Name:')}</dt>
<dd>${user.givenName}</dd> <dd>${user.givenName}</dd>
</dl> </dl>
</div> </div>

View file

@ -4,15 +4,16 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Fedora Accounts System</title> <title>${_('Fedora Accounts System')}</title>
</head> </head>
<body> <body>
<h2>Fedora Project OpenID Provider</h2> <h2>${_('Fedora Project OpenID Provider')}</h2>
<form action="${tg.url('/openid/server')}"> <form action="${tg.url('/openid/server')}">
<div> <div>
<input type="hidden" id="url" name="url" value="${url}" /> <input type="hidden" id="url" name="url" value="${url}" />
<input type="checkbox" id="trusted" name="trusted" value="allow" /> <label for="trusted">Allow <strong>${url}</strong> to authenticate to your OpenID identity?</label><br /> <input type="checkbox" id="trusted" name="trusted" value="allow" />
<input type="submit" value="Submit" /> <label for="trusted">${Markup(_('Allow &lt;strong&gt;%s&lt;/strong&gt; to authenticate to your OpenID identity?') % url)}</label><br />
<input type="submit" value="${_('Submit'}" />
</div> </div>
</form> </form>
</body> </body>

View file

@ -4,16 +4,16 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Change Password</title> <title>${_('Change Password')}</title>
</head> </head>
<body> <body>
<h2>Change Password</h2> <h2>${_('Change Password')}</h2>
<form action="${tg.url('/user/setpass')}" method="post"> <form action="${tg.url('/user/setpass')}" method="post">
<ul> <ul>
<div class="field"><label for="currentPassword">Current Password:</label> <input type="password" id="currentPassword" name="currentPassword" /></div> <div class="field"><label for="currentPassword">${_('Current Password:')}</label> <input type="password" id="currentPassword" name="currentPassword" /></div>
<div class="field"><label for="password">New Password:</label> <input type="password" id="password" name="password" /></div> <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"><label for="passwordCheck">${_('Confirm Password:')}</label> <input type="password" id="passwordCheck" name="passwordCheck" /></div>
<div class="field"><input type="submit" value="Change Password" /></div> <div class="field"><input type="submit" value="${_('Change Password')}" /></div>
</ul> </ul>
</form> </form>
</body> </body>

View file

@ -4,47 +4,55 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Edit Account</title> <title>${_('Edit Account')}</title>
</head> </head>
<body> <body>
<h2>Edit Account</h2> <h2>${_('Edit Account (%s)') % userName}</h2>
<form action="${tg.url('/user/save/%s' % userName)}" method="post"> <form action="${tg.url('/user/save/%s' % userName)}" method="post">
<div class="field"> <div class="field">
<label for="givenName">Full Name:</label> <label for="givenName">${_('Full Name'):}</label>
<input type="text" id="givenName" name="givenName" value="${user.givenName}" /> <input type="text" id="givenName" name="givenName" value="${user.givenName}" />
</div> </div>
<div class="field"> <div class="field">
<label for="mail">Email:</label> <label for="mail">${_('Email'):}</label>
<input type="text" id="mail" name="mail" value="${user.mail}" /> <input type="text" id="mail" name="mail" value="${user.mail}" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraPersonBugzillaMail">Bugzilla Email:</label> <label for="fedoraPersonBugzillaMail">${_('Bugzilla Email'):}</label>
<input type="text" id="fedoraPersonBugzillaMail" name="fedoraPersonBugzillaMail" value="${user.fedoraPersonBugzillaMail}" /> <input type="text" id="fedoraPersonBugzillaMail" name="fedoraPersonBugzillaMail" value="${user.fedoraPersonBugzillaMail}" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraPersonIrcNick">IRC Nick:</label> <label for="fedoraPersonIrcNick">${_('IRC Nick'):}</label>
<input type="text" id="fedoraPersonIrcNick" name="fedoraPersonIrcNick" value="${user.fedoraPersonIrcNick}" /> <input type="text" id="fedoraPersonIrcNick" name="fedoraPersonIrcNick" value="${user.fedoraPersonIrcNick}" />
</div> </div>
<div class="field"> <div class="field">
<label for="fedoraPersonKeyId">PGP Key:</label> <label for="fedoraPersonKeyId">${_('PGP Key'):}</label>
<input type="text" id="fedoraPersonKeyId" name="fedoraPersonKeyId" value="${user.fedoraPersonKeyId}" /> <input type="text" id="fedoraPersonKeyId" name="fedoraPersonKeyId" value="${user.fedoraPersonKeyId}" />
</div> </div>
<div class="field"> <div class="field">
<label for="telephoneNumber">Telephone Number:</label> <label for="telephoneNumber">${_('Telephone Number'):}</label>
<input type="text" id="telephoneNumber" name="telephoneNumber" value="${user.telephoneNumber}" /> <input type="text" id="telephoneNumber" name="telephoneNumber" value="${user.telephoneNumber}" />
</div> </div>
<div class="field"> <div class="field">
<label for="postalAddress">Postal Address:</label> <label for="postalAddress">${_('Postal Address'):}</label>
<input type="text" id="postalAddress" name="postalAddress" value="${user.postalAddress}" /> <textarea id="postalAddress" name="postalAddress">${user.postalAddress}</textarea>
</div> </div>
<div class="field"> <div class="field">
<label for="description ">Description:</label> <label for="fedoraPersonTimeZone">${_('Time Zone'):}</label>
<textarea id="description" name="description"> <select id="fedoraPersonTimeZone" name="fedoraPersonTimeZone">
${user.description} <?python
</textarea> from pytz import common_timezones
?>
<option py:for="tz in common_timezones" value="${tz}" py:attrs="{'selected': user.fedoraPersonTimeZone == tz and 'selected' or None}">${tz}</option>
</select>
</div> </div>
<div class="field"> <div class="field">
<input type="submit" value="Save!" /> <label for="description ">${_('Description'):}</label>
<textarea id="description" name="description">${user.description}</textarea>
</div>
<div class="field">
<input type="submit" value="${_('Save!')}" />
<a href="${tg.url('/user/view/%s' % userName)}">${_('Cancel')}</a>
</div> </div>
</form> </form>
</body> </body>

View file

@ -4,35 +4,35 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Users List</title> <title>${_('Users List')}</title>
</head> </head>
<body> <body>
<h2>List (${search})</h2> <h2>${_('List (%s)') % search}</h2>
<form method="get" action="${tg.url('/user/list')}"> <form method="get" action="${tg.url('/user/list')}">
<p>"*" is a wildcard (Ex: "cvs*")</p> <p>${_('"*" is a wildcard (Ex: "ric*")')}</p>
<div> <div>
<input type="text" value="${search}" name="search" size="15 "/> <input type="text" value="${search}" name="search" size="15 "/>
<input type="submit" value="Search" /> <input type="submit" value="Search" />
</div> </div>
</form> </form>
<h3>Results</h3> <h3>${_('Results')}</h3>
<ul class="letters"> <ul class="letters">
<li py:for="letter in 'abcdefghijklmnopqrstuvwxyz'.upper()"><a href="${tg.url('/user/list/%s*' % letter)}">${letter}</a></li> <li py:for="letter in 'abcdefghijklmnopqrstuvwxyz'.upper()"><a href="${tg.url('/user/list/%s*' % letter)}">${letter}</a></li>
<li><a href="${tg.url('/user/list/*')}">All</a></li> <li><a href="${tg.url('/user/list/*')}">${_('All')}</a></li>
</ul> </ul>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>Username</th> <th>${_('Username')}</th>
<th>Account Status</th> <th>${_('Account Status')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr py:for="user in sorted(users)"> <tr py:for="user in sorted(users)">
<td><a href="${tg.url('/user/view/%s' % user)}">${user}</a></td> <td><a href="${tg.url('/user/view/%s' % user)}">${user}</a></td>
<td> <td>
<span py:if="claDone[user]" class="approved"> CLA Done</span> <span py:if="claDone[user]" class="approved">${_('CLA Done')}</span>
<span py:if="not claDone[user]" class="unapproved"> CLA Not Done</span> <span py:if="not claDone[user]" class="unapproved">${_('CLA Not Done')}</span>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View file

@ -4,37 +4,37 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Sign up for a Fedora account</title> <title>${_('Sign up for a Fedora account')}</title>
</head> </head>
<body> <body>
<h2>Sign up for a Fedora account</h2> <h2>${_('Sign up for a Fedora account')}</h2>
<form action="${tg.url('/user/create')}" method="post"> <form action="${tg.url('/user/create')}" method="post">
<div class="field"> <div class="field">
<label for="cn">Username:</label> <label for="cn">${_('Username:')}</label>
<input type="text" id="cn" name="cn" /> <input type="text" id="cn" name="cn" />
</div> </div>
<div class="field"> <div class="field">
<label for="givenName">Full Name:</label> <label for="givenName">${_('Full Name:')}</label>
<input type="text" id="givenName" name="givenName" /> <input type="text" id="givenName" name="givenName" />
</div> </div>
<div class="field"> <div class="field">
<label for="mail">Email</label> <label for="mail">${_('Email:')}</label>
<input type="text" id="mail" name="mail" /> <input type="text" id="mail" name="mail" />
</div> </div>
<!-- <div class="field"> <!-- <div class="field">
<label for="fedoraPersonBugzillaMail">Bugzilla Email</label> <label for="fedoraPersonBugzillaMail">${_('Bugzilla Email:')}</label>
<input type="text" id="mail" name="fedoraPersonBugzillaMail" /> <input type="text" id="mail" name="fedoraPersonBugzillaMail" />
</div>--> </div>-->
<div class="field"> <div class="field">
<label for="telephoneNumber">Telephone Number</label> <label for="telephoneNumber">${_('Telephone Number:')}</label>
<input type="text" id="telephoneNumber" name="telephoneNumber" /> <input type="text" id="telephoneNumber" name="telephoneNumber" />
</div> </div>
<div class="field"> <div class="field">
<label for="postalAddress">Postal Address</label> <label for="postalAddress">${_('Postal Address:')}</label>
<textarea id="postalAddress" name="postalAddress"></textarea> <textarea id="postalAddress" name="postalAddress"></textarea>
</div> </div>
<div class="field"> <div class="field">
<input type="submit" value="Sign up!" /> <input type="submit" value="${_('Sign up!')}" />
</div> </div>
</form> </form>
</body> </body>

View file

@ -4,16 +4,16 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>Reset Password</title> <title>${_('Reset Password')}</title>
</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/sendpass')}" 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="mail">Primary Email:</label> <input type="text" id="mail" name="mail" /></div> <div class="field"><label for="mail">${_('Primary Email:')}</label> <input type="text" id="mail" name="mail" /></div>
<div class="field"><input type="checkbox" id="encrypted" name="encrypted" /> <label style="width: auto; float: none; margin-left: 1ex;" for="encrypted">Encrypt/Sign password reset email</label></div> <div class="field"><input type="checkbox" id="encrypted" name="encrypted" /> <label style="width: auto; float: none; margin-left: 1ex;" for="encrypted">${_('Encrypt/Sign password reset email')}</label></div>
<div class="field"><input type="submit" value="Reset Password" /></div> <div class="field"><input type="submit" value="${_('Reset Password')}" /></div>
</ul> </ul>
</form> </form>
</body> </body>

View file

@ -4,73 +4,72 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="../master.html" /> <xi:include href="../master.html" />
<head> <head>
<title>View Account</title> <title>${_('View Account')}</title>
</head> </head>
<body> <body>
<?python from fas import auth ?> <?python from fas import auth ?>
<h2 class="account" py:if="personal">Your Fedora Account</h2> <h2 class="account" py:if="personal">${_('Your Fedora Account')}</h2>
<h2 class="account" py:if="not personal">${user.givenName}'s Fedora Account</h2> <h2 class="account" py:if="not personal">${_('%s\'s Fedora Account') % user.givenName}</h2>
<h3>Account Details <a href="${tg.url('/user/edit/%s' % user.cn)}" py:if="personal or admin">(edit)</a></h3> <h3>${_('Account Details')} <a href="${tg.url('/user/edit/%s' % user.cn)}" py:if="personal or admin">${_('(edit)')}</a></h3>
<div class="userbox"> <div class="userbox">
<dl> <dl>
<dt>Account Name</dt><dd>${user.cn}&nbsp;</dd> <dt>${_('Account Name:')}</dt><dd>${user.cn}</dd>
<dt>Real Name</dt><dd>${user.givenName}&nbsp;</dd> <dt>${_('Real Name:')}</dt><dd>${user.givenName}</dd>
<dt>Email</dt><dd>${user.mail}&nbsp;</dd> <dt>${_('Email:')}</dt><dd>${user.mail}</dd>
<dt>Bugzilla Email</dt><dd>${user.fedoraPersonBugzillaMail}&nbsp;</dd> <dt>${_('Bugzilla Email:')}</dt><dd>${user.fedoraPersonBugzillaMail}</dd>
<dt>IRC Nick</dt><dd>${user.fedoraPersonIrcNick}&nbsp;</dd> <dt>${_('IRC Nick:')}</dt><dd>${user.fedoraPersonIrcNick}&nbsp;</dd>
<dt>PGP Key</dt><dd>${user.fedoraPersonKeyId}&nbsp;</dd> <dt>${_('PGP Key:')}</dt><dd>${user.fedoraPersonKeyId}&nbsp;</dd>
<dt>Telephone Number</dt><dd>${user.telephoneNumber}&nbsp;</dd> <dt>${_('Telephone Number:')}</dt><dd>${user.telephoneNumber}</dd>
<dt>Postal Address</dt><dd>${user.postalAddress}&nbsp;</dd> <dt>${_('Postal Address:')}</dt><dd>${user.postalAddress}</dd>
<dt>Description</dt><dd>${user.description}&nbsp;</dd> <dt>${_('Description:')}</dt><dd>${user.description}&nbsp;</dd>
<dt>Password</dt><dd><span class="approved">Valid</span> <a href="${tg.url('/user/changepass')}" py:if="personal">(change)</a></dd> <dt>${_('Password:')}</dt><dd><span class="approved">${_('Valid')}</span> <a href="${tg.url('/user/changepass')}" py:if="personal">(change)</a></dd>
<dt>Account Status</dt><dd><span class="approved">Approved</span>, Active</dd> <dt>${_('Account Status:')}</dt><dd><span class="approved">${_('Approved')}</span></dd>
<dt>CLA</dt><dd><span py:if="claDone" class="approved">Done</span><span py:if="not claDone" class="unapproved"> Not Done</span></dd> <dt>${_('CLA:')}</dt><dd><span py:if="claDone" class="approved">${_('Done')}</span><span py:if="not claDone" class="unapproved">${_('Not Done (&lt;a href="%s"&gt;Sign it&lt;/a&gt;!)') % tg.url('/cla')}</span></dd>
</dl> </dl>
</div> </div>
<h3 py:if="personal">Your Roles</h3> <h3 py:if="personal">${_('Your Roles')}</h3>
<h3 py:if="not personal">${user.givenName}'s Roles</h3> <h3 py:if="not personal">${_('%s\'s Roles') % user.givenName}</h3>
<ul class="roleslist"> <ul class="roleslist">
<li py:for="group in sorted(groups.keys())"><span class="team approved">${groupdata[group].fedoraGroupDesc} (${group})</span></li> <li py:for="group in sorted(groups.keys())"><span class="team approved">${groupdata[group].fedoraGroupDesc} (${group})</span></li>
<li py:for="group in sorted(groupsPending.keys())"><span class="team unapproved">${groupdata[group].fedoraGroupDesc} (${group})</span></li> <li py:for="group in sorted(groupsPending.keys())"><span class="team unapproved">${groupdata[group].fedoraGroupDesc} (${group})</span></li>
</ul> </ul>
<!--
<ul class="actions" py:if="personal"> <ul class="actions" py:if="personal">
<li><a href="${tg.url('/group/list/A*')}">(Join another project)</a></li> <li><a href="${tg.url('/group/list/A*')}">${_('(Join another project)')}</a></li>
<li><a href="/">(Create a new project)</a></li> <li><a href="/">${_('(Create a new project)')}</a></li>
</ul> </ul>
-->
<ul id="rolespanel" py:if="personal"> <ul id="rolespanel" py:if="personal">
<li py:for="group in sorted(groups.keys())" class="role"> <div py:for="group in sorted(groups.keys())" py:strip="">
<div py:if="auth.canViewGroup(user.cn, group)" py:strip=""> <li py:if="auth.canViewGroup(user.cn, group)" class="role">
<h4>${groupdata[group].fedoraGroupDesc}</h4>, ${groups[group].fedoraRoleType} <h4>${groupdata[group].fedoraGroupDesc}</h4> (${groups[group].fedoraRoleType})
<dl> <dl>
<dt>Status:</dt> <dt>${_('Status:')}</dt>
<dd> <dd>
<span class="approved">Approved</span>, Active <span class="approved">${_('Approved')}</span>
</dd> </dd>
<dt>Tools:</dt> <dt>${_('Tools:')}</dt>
<dd> <dd>
<ul class="tools"> <ul class="tools">
<li><a href="/">Invite a New Member...</a></li> <li><a href="${tg.url('/group/view/%s' % group)}">${_('View Group')}</a></li>
<li py:if="auth.canSponsorGroup(user.cn, group)"><a href="${tg.url('/group/view/%s' % group)}">View All Pending Group Membership Requests...</a></li> <li><a href="${tg.url('/group/invite/%s' % group)}">${_('Invite a New Member...')}</a></li>
<li><a href="${tg.url('/group/view/%s' % group)}">Manage Group Membership...</a></li> <li py:if="auth.canSponsorGroup(user.cn, group)"><a href="${tg.url('/group/view/%s' % group)}">${_('Manage Group Membership...')}</a></li>
<li py:if="auth.canEditGroup(user.cn, group)"><a href="${tg.url('/group/edit/%s' % group)}">Manage Group Details...</a></li> <li py:if="auth.canEditGroup(user.cn, group)"><a href="${tg.url('/group/edit/%s' % group)}">${_('Manage Group Details...')}</a></li>
</ul> </ul>
</dd> </dd>
<div py:if="auth.canSponsorGroup(user.cn, group) and groupUnapproved[group] != []" py:strip=""> <div py:if="auth.canSponsorGroup(user.cn, group) and groupUnapproved[group] != []" py:strip="">
<dt>Queue (last five):</dt> <dt>${_('Queue:')}</dt>
<dd> <dd>
<ul class="queue"> <ul class="queue">
<li py:for="user in groupUnapproved[group][:5]">${user[0]} requests approval to join ${group}</li> <li py:for="user in groupUnapproved[group][:5]">
<!-- ${Markup(_('&lt;strong&gt;%(user)s&lt;/strong&gt; requests approval to join &lt;strong&gt;%(group)s&lt;/strong&gt;.') % {'user': user[0], 'group': group})}
<li><a href="/">Chewbacca D. Wookiee requests approval to join project as a <strong>user</strong></a></li> </li>
<li><a href="/">Gaius Baltar requests approval to upgrade from <strong>user</strong> to <strong>sponsor</strong></a></li>
<li><a href="/">Leia Organa requests approval to upgrade from <strong>user</strong> to <strong>administrator</strong></a></li>
-->
</ul> </ul>
</dd> </dd>
</div> </div>
</dl> </dl>
</div>
</li> </li>
</div>
</ul> </ul>
</body> </body>
</html> </html>

View file

@ -4,7 +4,7 @@
xmlns:xi="http://www.w3.org/2001/XInclude"> xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="master.html" /> <xi:include href="master.html" />
<head> <head>
<title>Welcome to FAS2</title> <title>${_('Welcome to FAS2')}</title>
<style type="text/css"> <style type="text/css">
#content ul #content ul
{ {
@ -15,12 +15,12 @@
</head> </head>
<body> <body>
<p> <p>
Welcome to the Fedora Accounts System 2. This system is not yet live so feel free to play around. Just don't expect it to work. ${_('Welcome to the Fedora Accounts System 2. This system is not yet live so feel free to play around. Just don\'t expect it to work.')}
</p> </p>
<ul> <ul>
<li><a href="${tg.url('/login')}">Log In</a></li> <li><a href="${tg.url('/login')}">${_('Log In')}</a></li>
<li><a href="${tg.url('/user/new')}">New Account</a></li> <li><a href="${tg.url('/user/new')}">${_('New Account')}</a></li>
<li><a href="http://fedoraproject.org/wiki/Join">Why Join?</a></li> <li><a href="http://fedoraproject.org/wiki/Join">${_('Why Join?')}</a></li>
</ul> </ul>
</body> </body>
</html> </html>

View file

@ -143,7 +143,7 @@ class User(controllers.Controller):
unapproved = [(v,k) for k,v in unapproved.items()] unapproved = [(v,k) for k,v in unapproved.items()]
unapproved.sort(date_compare) unapproved.sort(date_compare)
unapproved.reverse() unapproved.reverse()
groupUnapproved[g] = [(k,v) for v,k in unapproved] groupUnapproved[g] = [(Person.byUserName(k).givenName,v) for v,k in unapproved]
for g in groupsPending: for g in groupsPending:
groupdata[g] = Groups.groups(g)[g] groupdata[g] = Groups.groups(g)[g]
try: try:
@ -172,12 +172,13 @@ class User(controllers.Controller):
@validate(validators=editUser()) @validate(validators=editUser())
@error_handler(error) @error_handler(error)
@expose(template='fas.templates.user.edit') @expose(template='fas.templates.user.edit')
def save(self, userName, givenName, mail, fedoraPersonBugzillaMail, telephoneNumber, postalAddress, fedoraPersonIrcNick='', fedoraPersonKeyId='', description=''): def save(self, userName, givenName, mail, fedoraPersonBugzillaMail, telephoneNumber, postalAddress, fedoraPersonIrcNick='', fedoraPersonKeyId='', description='', fedoraPersonTimeZone='UTC'):
if not canEditUser(turbogears.identity.current.user_name, userName): if not canEditUser(turbogears.identity.current.user_name, userName):
turbogears.flash(_("You do not have permission to edit '%s'" % userName)) turbogears.flash(_("You do not have permission to edit '%s'" % userName))
turbogears.redirect('/user/edit/%s', turbogears.identity.current.user_name) turbogears.redirect('/user/edit/%s', turbogears.identity.current.user_name)
try: return dict()
user = Person.byUserName(userName) user = Person.byUserName(userName)
try:
user.givenName = givenName user.givenName = givenName
user.mail = mail user.mail = mail
user.fedoraPersonBugzillaMail = fedoraPersonBugzillaMail user.fedoraPersonBugzillaMail = fedoraPersonBugzillaMail
@ -186,21 +187,13 @@ class User(controllers.Controller):
user.telephoneNumber = telephoneNumber user.telephoneNumber = telephoneNumber
user.postalAddress = postalAddress user.postalAddress = postalAddress
user.description = description user.description = description
user.fedoraPersonTimeZone = fedoraPersonTimeZone
except: except:
turbogears.flash(_('Your account details could not be saved.')) turbogears.flash(_('Your account details could not be saved.'))
else: else:
turbogears.flash(_('Your account details have been saved.')) turbogears.flash(_('Your account details have been saved.'))
turbogears.redirect("/user/view/%s" % userName) turbogears.redirect("/user/view/%s" % userName)
value = {'userName': userName, return dict(userName=userName, user=user)
'givenName': givenName,
'mail': mail,
'fedoraPersonBugzillaMail': fedoraPersonBugzillaMail,
'fedoraPersonIrcNick': fedoraPersonIrcNick,
'fedoraPersonKeyId': fedoraPersonKeyId,
'telephoneNumber': telephoneNumber,
'postalAddress': postalAddress,
'description': description, }
return dict(value=value)
@identity.require(turbogears.identity.in_group("accounts")) #TODO: Use auth.py @identity.require(turbogears.identity.in_group("accounts")) #TODO: Use auth.py
@expose(template="fas.templates.user.list") @expose(template="fas.templates.user.list")
@ -379,6 +372,12 @@ class User(controllers.Controller):
keydump = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey) keydump = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
return dict(cert=certdump, key=keydump) return dict(cert=certdump, key=keydump)
@expose(format="json")
def search(self, userName=None, groupName=None):
people = Person.users('%s*' % userName)
return dict(people=
filter(lambda item: userName in item.lower(), people))
def date_compare(x, y): def date_compare(x, y):
if x[0].fedoraRoleCreationDate > y[0].fedoraRoleCreationDate: if x[0].fedoraRoleCreationDate > y[0].fedoraRoleCreationDate:
return 1 return 1

View file

@ -11,8 +11,12 @@ attributetypes: ( 2.5.444.17 NAME 'fedoraPersonCreationDate' DESC 'date entry wa
attributeTypes: ( 2.5.444.18 NAME 'fedoraPersonApprovalStatus' DESC 'users approval status' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{50} ) attributeTypes: ( 2.5.444.18 NAME 'fedoraPersonApprovalStatus' DESC 'users approval status' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{50} )
attributeTypes: ( 2.5.444.19 NAME 'fedoraPersonKeyId' DESC 'users GPG key ID' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{50} ) attributeTypes: ( 2.5.444.19 NAME 'fedoraPersonKeyId' DESC 'users GPG key ID' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{50} )
attributeTypes: ( 2.5.444.22 NAME 'fedoraPersonCertSerial' DESC 'users SSL cert serial' EQUALITY IntegerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributeTypes: ( 2.5.444.22 NAME 'fedoraPersonCertSerial' DESC 'users SSL cert serial' EQUALITY IntegerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributeTypes: ( 2.5.444.23 NAME 'fedoraPersonTimeZone' DESC 'time zone of the user' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{50} )
attributeTypes: ( 2.5.444.24 NAME 'fedoraPersonEmailConfirm' DESC 'user email confirmation' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{50} )
attributeTypes: ( 2.5.444.25 NAME 'fedoraPersonEmailCode' DESC 'user email code' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{50} )
# fedoraPerson # fedoraPerson
# The fedoraPerson represents people who are a member of the fedora project # The fedoraPerson represents people who are a member of the fedora project
# in some way. It is a structural class and inherits # in some way. It is a structural class and inherits
# from the inetOrgPerson class # from the inetOrgPerson class
objectClasses: ( 2.5.555.1 NAME 'fedoraPerson' DESC 'A member of the fedoraproject group' SUP inetOrgPerson STRUCTURAL MUST ( fedoraPersonSshKey $ mail $ fedoraPersonCreationDate ) MAY (fedoraPersonIrcNick $ fedoraPersonApprovalStatus $ fedoraPersonBugzillaMail $ fedoraPersonKeyId $ fedoraPersonCertSerial ) ) objectClasses: ( 2.5.555.1 NAME 'fedoraPerson' DESC 'A member of the fedoraproject group' SUP inetOrgPerson STRUCTURAL MUST ( fedoraPersonSshKey $ mail $ fedoraPersonCreationDate $ fedoraPersonTimeZone ) MAY (fedoraPersonIrcNick $ fedoraPersonApprovalStatus $ fedoraPersonBugzillaMail $ fedoraPersonKeyId $ fedoraPersonCertSerial ) )

View file

@ -224,6 +224,10 @@ def main():
user = userCursor.fetchone() user = userCursor.fetchone()
if user == None: if user == None:
break break
date = str(user[12]).split('.')[0]
timestamp = time.strftime('%s', time.strptime(date, "%Y-%m-%d %H:%M:%S"))
# TODO: Create method createLdapUserEntry(user) # TODO: Create method createLdapUserEntry(user)
#(dn, entry) = createLdapUserEntry(user) #(dn, entry) = createLdapUserEntry(user)
if options.outType == "ldif": if options.outType == "ldif":
@ -241,16 +245,17 @@ def main():
userLdif.append(["cn",[str(user[1])]]) userLdif.append(["cn",[str(user[1])]])
userLdif.append(["givenName",[str(user[3])]]) userLdif.append(["givenName",[str(user[3])]])
userLdif.append(["fedoraPersonKeyId",[str(user[4])]]) userLdif.append(["fedoraPersonKeyId",[str(user[4])]])
userLdif.append(["fedoraPersonCertSerial",'-1']) userLdif.append(["fedoraPersonCertSerial",['-1']])
userLdif.append(["fedoraPersonSshKey",[str(user[5])]]) userLdif.append(["fedoraPersonSshKey",[str(user[5])]])
userLdif.append(["userPassword",[encode_SSHA_password(str(user[6]))]]) userLdif.append(["userPassword",[encode_SSHA_password(str(user[6]))]])
userLdif.append(["postalAddress",[str(user[8])]]) userLdif.append(["postalAddress",[str(user[8])]])
userLdif.append(["telephoneNumber",[str(user[9])]]) userLdif.append(["telephoneNumber",[str(user[9])]])
userLdif.append(["fax",[str(user[10]) or "None"]]) userLdif.append(["fax",[str(user[10]) or "None"]])
userLdif.append(["o",[str(user[11]) or "None" ]]) # affiliation is set to the o -- another stretch ?? userLdif.append(["o",[str(user[11]) or "None" ]]) # affiliation is set to the o -- another stretch ??
userLdif.append(["fedoraPersonCreationDate",[str(user[12])]]) userLdif.append(["fedoraPersonCreationDate",[str(timestamp)]])
userLdif.append(["fedoraPersonApprovalStatus",[str(user[13])]]) userLdif.append(["fedoraPersonApprovalStatus",[str(user[13])]])
userLdif.append(["description",[str(user[14])]]) #this one may be a streach -- original field was internal comments userLdif.append(["description",[str(user[14])]]) #this one may be a streach -- original field was internal comments
userLdif.append(["fedoraPersonTimeZone",["UTC"]])
userLdif.append(["fedoraPersonIrcNick",[str(user[16])]]) userLdif.append(["fedoraPersonIrcNick",[str(user[16])]])
#userLdif.append(["ou",["Roles"]]) Adding an OU instead #userLdif.append(["ou",["Roles"]]) Adding an OU instead
@ -316,8 +321,8 @@ def main():
print prereq print prereq
else: else:
prereq=["None"] prereq=["None"]
print owner
print owner
#id0, name1, owner_id2, group_type3, needs_sponsor4, user_can_remove5, prerequisite_id6, joinmsg7 #id0, name1, owner_id2, group_type3, needs_sponsor4, user_can_remove5, prerequisite_id6, joinmsg7
userLdif = [["objectClass",["fedoraGroup"]] ] userLdif = [["objectClass",["fedoraGroup"]] ]
@ -369,6 +374,16 @@ def main():
role = roleCursor.fetchone() role = roleCursor.fetchone()
if role == None: if role == None:
break break
date1 = str(role[7]).split('.')[0]
date2 = str(role[8]).split('.')[0]
try:
timestamp1 = time.strftime('%s', time.strptime(date1, "%Y-%m-%d %H:%M:%S"))
except:
timestamp1 = "None"
try:
timestamp2 = time.strftime('%s', time.strptime(date2, "%Y-%m-%d %H:%M:%S"))
except:
timestamp2 = "None"
# TODO: Create method createLdapRoleEntry(group) # TODO: Create method createLdapRoleEntry(group)
#(dn, entry) = createLdapGroupRole(group) #(dn, entry) = createLdapGroupRole(group)
if options.outType == "ldif": if options.outType == "ldif":
@ -407,8 +422,8 @@ def main():
roleLdif.append(["fedoraRoleDomain",[str(role[3]) or "None" ]]) roleLdif.append(["fedoraRoleDomain",[str(role[3]) or "None" ]])
roleLdif.append(["fedoraRoleStatus",[str(role[4])]]) roleLdif.append(["fedoraRoleStatus",[str(role[4])]])
roleLdif.append(["fedoraRoleSponsor",sponsor]) roleLdif.append(["fedoraRoleSponsor",sponsor])
roleLdif.append(["fedoraRoleCreationDate",[str(role[7]) or "None" ]]) roleLdif.append(["fedoraRoleCreationDate",[str(timestamp1)]])
roleLdif.append(["fedoraRoleApprovalDate",[str(role[8])]]) roleLdif.append(["fedoraRoleApprovalDate",[str(timestamp2)]])
ldifWriter.unparse("cn=" + group[0] + ",ou=Roles,cn=" + username[0] + ",ou=People,dc=fedoraproject,dc=org" , roleLdif ) ldifWriter.unparse("cn=" + group[0] + ",ou=Roles,cn=" + username[0] + ",ou=People,dc=fedoraproject,dc=org" , roleLdif )

View file

@ -0,0 +1,27 @@
#!/usr/bin/python
import os
import commands
dirs = ['/git/',
'/hg/',
'/svn/',
'/bzr/',
'/mtn/',]
for dir in dirs:
projects = os.listdir(dir)
for project in projects:
# strip off the .git
firstLetter = project[0]
secondLetter = project[1]
path = "%s%s" % (dir, project)
releaseName = project.replace('.git', '')
release = "/srv/web/releases/%s/%s/%s" % (firstLetter, secondLetter, releaseName)
if not os.path.islink(path):
stat = os.lstat(path)
if not os.path.isdir(release):
os.makedirs(release)
if os.lstat(release).st_gid != stat.st_gid:
os.chown(release, -1, stat.st_gid)
os.chmod(release, 02775)

View file

@ -1 +1,2 @@
check_ipmi - Checks fan and temperature on a box with ipmi support check_ipmi - Checks fan and temperature on a box with ipmi support
check_koji - Check for failed koji builds and warn when in a critical range

5
scripts/run-scm/run-bzr Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh
umask 0002
exec /usr/bin/bzr "$@"

61
scripts/run-scm/run-git Executable file
View file

@ -0,0 +1,61 @@
#!/usr/bin/python -tt
import sys, os
commands = {
"git-receive-pack": "/usr/bin/git-receive-pack",
"git-upload-pack": "/usr/bin/git-upload-pack",
"bzr": "/usr/bin/run-bzr",
"hg": "/usr/bin/run-hg",
"mtn": "/usr/bin/run-mtn",
"svnserve": "/usr/bin/run-svnserve",
"scp": "/usr/bin/scp",
}
if __name__ == '__main__':
orig_cmd = os.environ.get('SSH_ORIGINAL_COMMAND')
if not orig_cmd:
print "Need a command"
sys.exit(1)
allargs = orig_cmd.split()
try:
basecmd = os.path.basename(allargs[0])
cmd = commands[basecmd]
except:
sys.stderr.write("Invalid command %s\n" % orig_cmd)
sys.exit(2)
if basecmd in ('git-receive-pack', 'git-upload-pack'):
# git repositories need to be parsed specially
thearg = ' '.join(allargs[1:])
if thearg[0] == "'" and thearg[-1] == "'":
thearg = thearg.replace("'","")
thearg = thearg.replace("\\'", "")
if thearg[:len('/git/')] != '/git/' or not os.path.isdir(thearg):
print "Invalid repository %s" % thearg
sys.exit(3)
allargs = [thearg]
elif basecmd in ('scp'):
thearg = ' '.join(allargs[1:])
firstLetter = allargs[2][0]
secondLetter = allargs[2][1]
uploadTarget = "/srv/web/releases/%s/%s/%s/" % (firstLetter, secondLetter, allargs[2])
if thearg.find('/') != -1:
print "scp yourfile-1.2.tar.gz scm.fedorahosted.org:$YOURPROJECT # No trailing /"
sys.exit(4)
elif not os.path.isdir(uploadTarget):
print "http://fedorahosted.org/releases/%s/%s/%s does not exist!" % (firstLetter, secondLetter, allargs[2])
sys.exit(5)
else:
newargs = []
newargs.append(allargs[0])
newargs.append(allargs[1])
newargs.append(uploadTarget)
os.execv(cmd, [cmd] + newargs[1:])
sys.exit(1)
else:
allargs = allargs[1:]
os.execv(cmd, [cmd] + allargs)
sys.exit(1)

5
scripts/run-scm/run-hg Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh
umask 0002
exec /usr/bin/hg "$@"

5
scripts/run-scm/run-mtn Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh
umask 0002
exec /usr/bin/mtn "$@"

4
scripts/run-scm/run-svnserve Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
umask 0002
exec /usr/bin/svnserve -t