Merge branch 'master' of ssh://git.fedorahosted.org/git/fedora-infrastructure
This commit is contained in:
commit
4f9ca8cd23
6 changed files with 111 additions and 40 deletions
|
@ -17,16 +17,17 @@ password = admin
|
||||||
; in 'groups'
|
; in 'groups'
|
||||||
|
|
||||||
; groups that should have a shell account on this system.
|
; groups that should have a shell account on this system.
|
||||||
groups = accounts,fedorabugs
|
groups = sysadmin-main
|
||||||
|
|
||||||
; groups that should have a restricted account on this system.
|
; groups that should have a restricted account on this system.
|
||||||
; restricted accounts use the restricted_shell value in [users]
|
; restricted accounts use the restricted_shell value in [users]
|
||||||
restricted_groups = sysadmin
|
restricted_groups =
|
||||||
|
|
||||||
; ssh_restricted_groups: groups that should be restricted by ssh key. You will
|
; ssh_restricted_groups: groups that should be restricted by ssh key. You will
|
||||||
; need to disable password based logins in order for this value to have any
|
; need to disable password based logins in order for this value to have any
|
||||||
; security meaning
|
; security meaning. Group types can be placed here as well, for example
|
||||||
ssh_restricted_groups = sysadmin-web
|
; @hg,@git,@svn
|
||||||
|
ssh_restricted_groups =
|
||||||
|
|
||||||
; aliases_template: Gets prepended to the aliases file when it is generated by
|
; aliases_template: Gets prepended to the aliases file when it is generated by
|
||||||
; fasClient
|
; fasClient
|
||||||
|
|
|
@ -128,6 +128,7 @@ class MakeShellAccounts(BaseClient):
|
||||||
emails = None
|
emails = None
|
||||||
group_mapping = {}
|
group_mapping = {}
|
||||||
valid_groups = {}
|
valid_groups = {}
|
||||||
|
usernames = {}
|
||||||
|
|
||||||
def mk_tempdir(self):
|
def mk_tempdir(self):
|
||||||
self.temp = tempfile.mkdtemp('-tmp', 'fas-', config.get('global', 'temp').strip('"'))
|
self.temp = tempfile.mkdtemp('-tmp', 'fas-', config.get('global', 'temp').strip('"'))
|
||||||
|
@ -165,6 +166,10 @@ class MakeShellAccounts(BaseClient):
|
||||||
|
|
||||||
def valid_user(self, username):
|
def valid_user(self, username):
|
||||||
''' Is the user valid on this system '''
|
''' Is the user valid on this system '''
|
||||||
|
if not self.valid_groups:
|
||||||
|
self.valid_groups()
|
||||||
|
if not self.group_mapping:
|
||||||
|
self.get_group_mapping()
|
||||||
try:
|
try:
|
||||||
for restriction in self.valid_groups:
|
for restriction in self.valid_groups:
|
||||||
for group in self.valid_groups[restriction]:
|
for group in self.valid_groups[restriction]:
|
||||||
|
@ -238,7 +243,7 @@ class MakeShellAccounts(BaseClient):
|
||||||
shadow_file = codecs.open(self.temp + '/shadow.txt', mode='w', encoding='utf-8')
|
shadow_file = codecs.open(self.temp + '/shadow.txt', mode='w', encoding='utf-8')
|
||||||
os.chmod(self.temp + '/shadow.txt', 00400)
|
os.chmod(self.temp + '/shadow.txt', 00400)
|
||||||
if not self.people:
|
if not self.people:
|
||||||
self.people = self.people_list()
|
self.people_list()
|
||||||
for person in self.people:
|
for person in self.people:
|
||||||
username = person['username']
|
username = person['username']
|
||||||
if self.valid_user(username):
|
if self.valid_user(username):
|
||||||
|
@ -267,7 +272,7 @@ class MakeShellAccounts(BaseClient):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def usernames(self):
|
def get_usernames(self):
|
||||||
usernames = {}
|
usernames = {}
|
||||||
if not self.people:
|
if not self.people:
|
||||||
self.people_list()
|
self.people_list()
|
||||||
|
@ -276,35 +281,58 @@ class MakeShellAccounts(BaseClient):
|
||||||
if self.valid_user_group(uid):
|
if self.valid_user_group(uid):
|
||||||
username = person['username']
|
username = person['username']
|
||||||
usernames[uid] = username
|
usernames[uid] = username
|
||||||
return usernames
|
self.usernames = usernames
|
||||||
|
|
||||||
def groups_text(self, groups=None, people=None):
|
def get_group_mapping(self):
|
||||||
i = 0
|
if not self.usernames:
|
||||||
file = open(self.temp + '/group.txt', 'w')
|
self.get_usernames()
|
||||||
if not groups:
|
for group in self.groups:
|
||||||
groups = self.group_list()
|
|
||||||
if not people:
|
|
||||||
people = self.people_list()
|
|
||||||
|
|
||||||
''' First create all of our users/groups combo '''
|
|
||||||
for person in people:
|
|
||||||
uid = person['id']
|
|
||||||
if self.valid_user_group(uid):
|
|
||||||
username = person['username']
|
|
||||||
file.write("=%i %s:x:%i:\n" % (uid, username, uid))
|
|
||||||
file.write("0%i %s:x:%i:\n" % (i, username, uid))
|
|
||||||
file.write(".%s %s:x:%i:\n" % (username, username, uid))
|
|
||||||
i = i + 1
|
|
||||||
|
|
||||||
usernames = self.usernames()
|
|
||||||
for group in groups:
|
|
||||||
gid = group['id']
|
gid = group['id']
|
||||||
name = group['name']
|
name = group['name']
|
||||||
try:
|
try:
|
||||||
''' Shoot me now I know this isn't right '''
|
''' Shoot me now I know this isn't right '''
|
||||||
members = []
|
members = []
|
||||||
for member in self.memberships[name]:
|
for member in self.memberships[name]:
|
||||||
members.append(usernames[member['person_id']])
|
members.append(self.usernames[member['person_id']])
|
||||||
|
memberships = ','.join(members)
|
||||||
|
self.group_mapping[name] = members
|
||||||
|
except KeyError:
|
||||||
|
''' No users exist in the group '''
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def groups_text(self, groups=None, people=None):
|
||||||
|
i = 0
|
||||||
|
file = open(self.temp + '/group.txt', 'w')
|
||||||
|
if not self.groups:
|
||||||
|
self.group_list()
|
||||||
|
if not self.people:
|
||||||
|
self.people_list()
|
||||||
|
if not self.usernames:
|
||||||
|
self.get_usernames()
|
||||||
|
if not self.group_mapping:
|
||||||
|
self.get_group_mapping()
|
||||||
|
''' First create all of our users/groups combo '''
|
||||||
|
for person in self.people:
|
||||||
|
uid = person['id']
|
||||||
|
try:
|
||||||
|
if self.valid_user(self.usernames[uid]):
|
||||||
|
username = person['username']
|
||||||
|
file.write("=%i %s:x:%i:\n" % (uid, username, uid))
|
||||||
|
file.write("0%i %s:x:%i:\n" % (i, username, uid))
|
||||||
|
file.write(".%s %s:x:%i:\n" % (username, username, uid))
|
||||||
|
i = i + 1
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for group in self.groups:
|
||||||
|
gid = group['id']
|
||||||
|
name = group['name']
|
||||||
|
try:
|
||||||
|
''' Shoot me now I know this isn't right '''
|
||||||
|
members = []
|
||||||
|
for member in self.memberships[name]:
|
||||||
|
members.append(self.usernames[member['person_id']])
|
||||||
memberships = ','.join(members)
|
memberships = ','.join(members)
|
||||||
self.group_mapping[name] = members
|
self.group_mapping[name] = members
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -314,21 +342,27 @@ class MakeShellAccounts(BaseClient):
|
||||||
file.write("0%i %s:x:%i:%s\n" % (i, name, gid, memberships))
|
file.write("0%i %s:x:%i:%s\n" % (i, name, gid, memberships))
|
||||||
file.write(".%s %s:x:%i:%s\n" % (name, name, gid, memberships))
|
file.write(".%s %s:x:%i:%s\n" % (name, name, gid, memberships))
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
def group_list(self, search='*'):
|
def group_list(self, search='*'):
|
||||||
params = {'search' : search}
|
params = {'search' : search}
|
||||||
request = self.send_request('group/list', auth=True, input=params)
|
request = self.send_request('group/list', auth=True, input=params)
|
||||||
self.groups = request['groups']
|
self.groups = request['groups']
|
||||||
self.memberships = request['memberships']
|
memberships = {}
|
||||||
|
for group in self.groups:
|
||||||
|
memberships[group['name']] = []
|
||||||
|
try:
|
||||||
|
for member in request['memberships'][u'%s' % group['id']]:
|
||||||
|
memberships[group['name']].append({'person_id': member})
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
self.memberships = memberships
|
||||||
self.valid_groups()
|
self.valid_groups()
|
||||||
return self.groups
|
return self.groups
|
||||||
|
|
||||||
def people_list(self, search='*'):
|
def people_list(self, search='*'):
|
||||||
params = {'search' : search}
|
params = {'search' : search}
|
||||||
self.people = self.send_request('user/list', auth=True, input=params)['people']
|
self.people = self.send_request('user/list', auth=True, input=params)['people']
|
||||||
return self.people
|
|
||||||
|
|
||||||
def email_list(self, search='*'):
|
def email_list(self, search='*'):
|
||||||
params = {'search' : search}
|
params = {'search' : search}
|
||||||
|
|
21
fas/fas.spec
21
fas/fas.spec
|
@ -1,7 +1,7 @@
|
||||||
%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
|
%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
|
||||||
|
|
||||||
Name: fas
|
Name: fas
|
||||||
Version: 0.1
|
Version: 0.2
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Fedora Account System
|
Summary: Fedora Account System
|
||||||
|
|
||||||
|
@ -17,8 +17,12 @@ BuildRequires: python-setuptools-devel
|
||||||
BuildRequires: TurboGears
|
BuildRequires: TurboGears
|
||||||
Requires: TurboGears >= 1.0.4
|
Requires: TurboGears >= 1.0.4
|
||||||
Requires: python-sqlalchemy >= 0.4
|
Requires: python-sqlalchemy >= 0.4
|
||||||
Requires: python-turbomail
|
Requires: python-TurboMail
|
||||||
Requires: python-fedora-infrastructure >= 0.2.99.2
|
Requires: python-fedora-infrastructure >= 0.2.99.2
|
||||||
|
Requires: babel
|
||||||
|
Requires: pygpgme
|
||||||
|
Requires: python-babel
|
||||||
|
Requires: pytz
|
||||||
|
|
||||||
%description
|
%description
|
||||||
The Fedora Account System is a web application that manages the accounts of
|
The Fedora Account System is a web application that manages the accounts of
|
||||||
|
@ -51,11 +55,17 @@ mkdir -p $RPM_BUILD_ROOT%{_sbindir}
|
||||||
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}
|
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}
|
||||||
mv $RPM_BUILD_ROOT%{_bindir}/start-fas $RPM_BUILD_ROOT%{_sbindir}
|
mv $RPM_BUILD_ROOT%{_bindir}/start-fas $RPM_BUILD_ROOT%{_sbindir}
|
||||||
# Unreadable by others because it's going to contain a database password.
|
# Unreadable by others because it's going to contain a database password.
|
||||||
install -m 0600 fas.cfg $RPM_BUILD_ROOT%{_sysconfdir}
|
install fas.cfg $RPM_BUILD_ROOT%{_sysconfdir}
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
%pre
|
||||||
|
/usr/sbin/groupadd -r fas &>/dev/null || :
|
||||||
|
/usr/sbin/useradd -r -s /sbin/nologin -d /usr/share/fas -M \
|
||||||
|
-c 'Fedora Acocunt System user' -g fas fas &>/dev/null || :
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
|
@ -63,11 +73,14 @@ rm -rf $RPM_BUILD_ROOT
|
||||||
%{python_sitelib}/*
|
%{python_sitelib}/*
|
||||||
%{_datadir}/fas/
|
%{_datadir}/fas/
|
||||||
%{_sbindir}/start-fas
|
%{_sbindir}/start-fas
|
||||||
%config(noreplace) %{_sysconfdir}/*
|
%attr(0640,root,apache) %config(noreplace) %{_sysconfdir}/fas.cfg
|
||||||
|
|
||||||
%files clients
|
%files clients
|
||||||
%{_bindir}/*
|
%{_bindir}/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Mar 10 2008 Mike McGrath <mmcgrath@redhat.com> - 0.2-1
|
||||||
|
- Added fas user/group
|
||||||
|
|
||||||
* Mon Mar 10 2008 Toshio Kuratomi <tkuratom@redhat.com> - 0.1-1
|
* Mon Mar 10 2008 Toshio Kuratomi <tkuratom@redhat.com> - 0.1-1
|
||||||
- Initial Build.
|
- Initial Build.
|
||||||
|
|
|
@ -3,6 +3,7 @@ from turbogears import controllers, expose, paginate, identity, redirect, widget
|
||||||
from turbogears.database import session
|
from turbogears.database import session
|
||||||
|
|
||||||
import cherrypy
|
import cherrypy
|
||||||
|
import sqlalchemy
|
||||||
|
|
||||||
import fas
|
import fas
|
||||||
from fas.auth import *
|
from fas.auth import *
|
||||||
|
@ -253,10 +254,17 @@ class Group(controllers.Controller):
|
||||||
groups = []
|
groups = []
|
||||||
re_search = re.sub(r'\*', r'%', search).lower()
|
re_search = re.sub(r'\*', r'%', search).lower()
|
||||||
results = Groups.query.filter(Groups.name.like(re_search)).order_by('name').all()
|
results = Groups.query.filter(Groups.name.like(re_search)).order_by('name').all()
|
||||||
|
if self.jsonRequest():
|
||||||
|
membersql = sqlalchemy.select([PersonRoles.c.person_id, PersonRoles.c.group_id]).order_by(PersonRoles.c.group_id)
|
||||||
|
members = membersql.execute()
|
||||||
|
for member in members:
|
||||||
|
try:
|
||||||
|
memberships[member[1]].append(member[0])
|
||||||
|
except KeyError:
|
||||||
|
memberships[member[1]]=[member[0]]
|
||||||
for group in results:
|
for group in results:
|
||||||
if canViewGroup(person, group):
|
if canViewGroup(person, group):
|
||||||
groups.append(group)
|
groups.append(group)
|
||||||
memberships[group.name] = group.approved_roles
|
|
||||||
if not len(groups):
|
if not len(groups):
|
||||||
turbogears.flash(_("No Groups found matching '%s'") % search)
|
turbogears.flash(_("No Groups found matching '%s'") % search)
|
||||||
return dict(groups=groups, search=search, memberships=memberships)
|
return dict(groups=groups, search=search, memberships=memberships)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#for role in sorted(group.approved_roles)
|
#for role in sorted(group.approved_roles)
|
||||||
${role.member.username},${role.member.emails['primary']},${role.member.human_name},${role.role_type}
|
${role.member.username},${role.member.emails['primary']},${role.member.human_name},${role.role_type},0
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -5,6 +5,8 @@ import cherrypy
|
||||||
|
|
||||||
import turbomail
|
import turbomail
|
||||||
|
|
||||||
|
import sqlalchemy
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import gpgme
|
import gpgme
|
||||||
|
@ -280,7 +282,20 @@ class User(controllers.Controller):
|
||||||
def list(self, search="a*"):
|
def list(self, search="a*"):
|
||||||
'''List users
|
'''List users
|
||||||
'''
|
'''
|
||||||
|
|
||||||
re_search = re.sub(r'\*', r'%', search).lower()
|
re_search = re.sub(r'\*', r'%', search).lower()
|
||||||
|
if self.jsonRequest():
|
||||||
|
people = []
|
||||||
|
peoplesql = sqlalchemy.select([People.c.id, People.c.username, People.c.human_name, People.c.ssh_key, People.c.password])
|
||||||
|
persons = peoplesql.execute()
|
||||||
|
for person in persons:
|
||||||
|
people.append({
|
||||||
|
'id' : person[0],
|
||||||
|
'username' : person[1],
|
||||||
|
'human_name' : person[2],
|
||||||
|
'ssh_key' : person[3],
|
||||||
|
'password' : person[4]})
|
||||||
|
else:
|
||||||
people = People.query.filter(People.username.like(re_search)).order_by('username')
|
people = People.query.filter(People.username.like(re_search)).order_by('username')
|
||||||
if people.count() < 0:
|
if people.count() < 0:
|
||||||
turbogears.flash(_("No users found matching '%s'") % search)
|
turbogears.flash(_("No users found matching '%s'") % search)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue