📄 useradmin.py
字号:
# -*- coding: ISO8859-1 -*-## Copyright 2003, 2004 Norwegian University of Science and Technology## This file is part of Network Administration Visualized (NAV)## NAV is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## NAV is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with NAV; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA### $Id: useradmin.py 3388 2006-03-14 12:32:56Z mortenv $# Authors: Morten Vold <morten.vold@itea.ntnu.no>#"""This module represents the useradmin pages of the NAV web interface.It follows the mod_python.publisher paradigm."""#from mod_python import apacheimport os, nav, psycopg, forgetSQLfrom nav import web, dbfrom nav.db import navprofiles, managefrom nav.web.templates.useradmin import *def _profileCursor(): _profileConn = db.getConnection('navprofile', 'navprofile') return _profileConn.cursor()def _manageCursor(): _manageConn = db.getConnection('webfront', 'manage') return _manageConn.cursor()def _accountsToTemplate(accounts): """Convert a list of Account objects into a list of dictionaries containing the Account properties.""" accountList = [{'id': item.id, 'login': item.login, 'name': item.name, 'ext_sync': item.ext_sync, 'groupcount': len(item.getGroups()) } for item in accounts ] return accountListdef _groupsToTemplate(groups): """Convert a list of Account objects into a list of dictionaries containing the Account properties.""" groupList = [{'id': item.id, 'name': item.name, 'description': item.descr, 'membercount': len(item.getMembers()) } for item in groups ] return groupListdef _getAccounts(includeIds=[], excludeIds=[]): """Return a list of rows from the Account table""" criteria = [] if len(includeIds) > 0: criteria.append("id IN (%s)" % ','.join([str(x) for x in includeIds])) if len(excludeIds) > 0: criteria.append("id NOT IN (%s)" % ','.join([str(x) for x in excludeIds])) if len(criteria) > 0: accounts = navprofiles.Account.getAll(where=criteria, orderBy="login") else: accounts = navprofiles.Account.getAll(orderBy="login") return _accountsToTemplate(accounts)def _getGroups(includeIds=[], excludeIds=[]): """Return a list of rows from the AccountGroup table""" criteria = [] if len(includeIds) > 0: criteria.append("id IN (%s)" % ','.join([str(x) for x in includeIds])) if len(excludeIds) > 0: criteria.append("id NOT IN (%s)" % ','.join([str(x) for x in excludeIds])) if len(criteria) > 0: groups = navprofiles.Accountgroup.getAll(where=criteria, orderBy="name") else: groups = navprofiles.Accountgroup.getAll(orderBy="name") return _groupsToTemplate(groups)def _accountExists(id): cursor = _profileCursor() sql = \ """SELECT COUNT(id) FROM Account WHERE id=%d""" % id cursor.execute(sql) return cursor.fetchone()[0] > 0def _groupExists(id): cursor = _profileCursor() sql = \ """SELECT COUNT(id) FROM AccountGroup WHERE id=%d""" % id cursor.execute(sql) return cursor.fetchone()[0] > 0def _link(uid, gid): """Links an account and a group in the AccountInGroup table""" cursor = _profileCursor() sql = \ """INSERT INTO AccountInGroup (accountid, groupid) VALUES (%d, %d)""" % (uid, gid) try: cursor.execute(sql) return True except psycopg.IntegrityError: # They were already linked, or at least one of the id's are # non-existant. return Falsedef _unlink(uid, gid): """Unlinks an account and a group in the AccountInGroup table""" cursor = _profileCursor() sql = \ """DELETE FROM AccountInGroup WHERE accountid=%d AND groupid=%d""" % (uid, gid) cursor.execute(sql) return Truedef _linkOp(req, uid, gid, source, linkFunc, success, failure): """Contains the common code for performing a link or unlink operation. The linkFunc parameter should refer to either the _link() or _unlink() function. """ # Sanitary work on arguments try: uid = int(uid) gid = int(gid) except TypeError: return "Invalid arguments" if source is not None and source not in ('group', 'account'): return "Invalid arguments" if not _accountExists(uid): return "no such account %d" % uid elif not _groupExists(gid): return "no such group %d" % gid if linkFunc(uid, gid): if source: if source == 'group': web.redirect(req, "group?id=%d" % gid) elif source == 'account': web.redirect(req, "account?id=%d" % uid) else: return success else: return failuredef _getPrivileges(): """Return a dictionary of valid privilege names, using their id numbers as key.""" cursor = _profileCursor() sql = \ """SELECT * FROM Privilege""" cursor.execute(sql) rows = cursor.dictfetchall() structure = {} for row in rows: structure[ row['privilegeid'] ] = row['privilegename'] return structuredef _getGroupPrivileges(gid): """Return a list of dictionaries containing the privilege specs for a given group id. This will probably only work as long as we store the privileges specs in our own SQL database.""" cursor = _profileCursor() sql = \ """SELECT * FROM AccountGroupPrivilege INNER JOIN Privilege USING (privilegeid) WHERE accountgroupid=%d ORDER BY privilegename, target""" % gid cursor.execute(sql) return cursor.dictfetchall()def _getPrivileges(): """Return a list of dictionaries containing valid privilege names and their id numbers""" privileges = navprofiles.Privilege.getAll(orderBy="privilegename") return privilegesdef _getNextSequence(sequence): cursor = _profileCursor() sql = \ """SELECT nextval('%s'::text)""" % sequence cursor.execute(sql) row = cursor.fetchone() return row[0]def _storeGroup(groupStruct): """Takes a group structure and attempts to store in in the database. If the supplied group structure contains an id number, this is considered an update of an existing record, else it is considered a new group.""" cursor = _profileCursor() newRecord = not groupStruct.has_key('id') \ or groupStruct['id'] is None \ or groupStruct['id'].strip() == "" if newRecord: id = _getNextSequence('accountgroupids') values = [str(id), groupStruct['name'], groupStruct['description']] escapedValues = [ nav.db.escape(v) for v in values ] valueStr = ",".join(escapedValues) sql = \ """INSERT INTO AccountGroup (id, name, descr) VALUES (%s)""" % valueStr cursor.execute(sql) return True else: id = groupStruct['id'] values = [groupStruct['name'], groupStruct['description']] sql = \ """UPDATE AccountGroup SET name=%s, descr=%s WHERE id=%s""" % ( nav.db.escape(groupStruct['name']), nav.db.escape(groupStruct['description']), int(id)) cursor.execute(sql) return Truedef _storeAccount(accountStruct): """Takes an account structure and attempts to store in in the database. If the supplied account structure contains an id number, this is considered an update of an existing record, else it is considered a new account.""" cursor = _profileCursor() newRecord = not accountStruct.has_key('id') \ or accountStruct['id'] is None \ or accountStruct['id'].strip() == "" if newRecord: id = _getNextSequence('accountids') values = [str(id), accountStruct['login'], accountStruct['name'], accountStruct['password']] escapedValues = [ nav.db.escape(v) for v in values ] valueStr = ",".join(escapedValues) sql = \ """INSERT INTO Account (id, login, name, password) VALUES (%s)""" % valueStr cursor.execute(sql) return True else: id = accountStruct['id'] values = [accountStruct['login'], accountStruct['name'], accountStruct['password']] sql = \ """UPDATE Account SET login=%s, name=%s, password=%s WHERE id=%s""" % ( nav.db.escape(accountStruct['login']), nav.db.escape(accountStruct['name']), nav.db.escape(accountStruct['password']), int(id)) cursor.execute(sql) return True### ###### Public web functions begin here ###### ###def accountlist(req): """Display a list of the accounts registered within NAV.""" page = AccountList() page.accounts = _getAccounts() page.path[-1] = ("Account list", False) page.title = "Account list" if req.session.has_key('statusMessage'): page.statusMessage = req.session['statusMessage'] del req.session['statusMessage'] return pagedef grouplist(req): """Display a list of the groups registered within NAV.""" page = GroupList() page.groups = _getGroups() page.path[-1] = ("Group list", False) page.title = "Group list" if req.session.has_key('statusMessage'): page.statusMessage = req.session['statusMessage'] del req.session['statusMessage'] return pagedef account(req, id=None): """Display all relevant data about an Account in an editable form.""" page = AccountPage() page.path[-1] = ("Edit account", False) if id is not None: # Sanitary work on arguments try: id = int(id) except TypeError: return "%s is not a valid account id" % repr(id) account = navprofiles.Account(id) try: account.load() except forgetSQL.NotFound: return "no such account %s" % id page.newAccount = False page.information = "Editing account \"%s\" (#%s)" % (account.name, account.id) page.account = _accountsToTemplate([account])[0] page.editable = account.ext_sync is None or account.ext_sync == '' page.account['groups'] = _groupsToTemplate(account.getGroups()) page.account['organizations'] = account.getOrgIds() page.account['organizations'].sort() else: page.newAccount = True page.information = "Creating new account" page.account = {'id': None, 'login': '', 'name': 'New user', 'ext_sync': None, 'groups': []} page.editable = True page.title = page.information # We've filled out most of the details of the account and its # group memberships, now we need to fill out the list of groups it # has no membership to so that we may add the account to any of # these groupIds = [ group['id'] for group in page.account['groups'] ] page.account['nongroups'] = _getGroups(excludeIds=groupIds) page.orgTree = manage.getOrgTree() if req.session.has_key('statusMessage'): page.statusMessage = req.session['statusMessage']
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -