Skip to content

Commit

Permalink
Merge branch '438-readonly-sqlite'
Browse files Browse the repository at this point in the history
  • Loading branch information
plajjan committed Feb 9, 2014
2 parents fd69b8a + dbb2f84 commit 0fda853
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 12 deletions.
28 changes: 26 additions & 2 deletions nipap/nipap-passwd
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ if __name__ == '__main__':
parser.add_option('-f', '--file', dest='db_file', type='string', help="database file [default: read from config]")
# parser.add_option('-m', '--modify', dest='modify_user', type='string')
parser.add_option('-p', '--password', dest='password', type='string', help='set user\'s password to PASSWORD')
parser.add_option('--latest-version', action='store_true',
help='check that the sqlite database is of latest version')
parser.add_option('--create-database', action='store_true',
help='create SqliteAuth database')
parser.add_option('--upgrade-database', action='store_true',
help='upgrade sqlite database to latest version')
parser.add_option('-l', '--list', action='store_true', dest='list', help='list users')
parser.add_option('-t', '--trusted', action='store_true', dest='trusted', default=False, help='mark user as trusted')
parser.add_option('-r', '--readonly', action='store_true', dest='readonly', default=False, help='set user to read only')
parser.add_option('-n', '--name', dest='name', type='string', help='set user\'s name to NAME')
parser.add_option('-c', '--config', dest='config', default='/etc/nipap/nipap.conf', type='string', help=
'read configuration from CONFIG [default:/etc/nipap/nipap.conf]')
parser.add_option('-c', '--config', dest='config', default='/etc/nipap/nipap.conf', type='string',
help='read configuration from CONFIG [default:/etc/nipap/nipap.conf]')
options, args = parser.parse_args()

logger = logging.getLogger()
Expand All @@ -42,6 +48,24 @@ if __name__ == '__main__':

a = nipap.authlib.SqliteAuth('local', 'a', 'b', 'c')

if options.latest_version:
try:
a._latest_db_version()
except nipap.authlib.AuthSqliteError, e:
print >> sys.stderr, "Problem with Sqlite database for local auth: %s" % e
print >> sys.stderr, "Run 'nipap-passwd --upgrade-database' to upgrade your database."
sys.exit(1)
print "Sqlite database for local auth is of the latest version."
sys.exit(0)

if options.create_database:
a._create_database()
sys.exit(0)

if options.upgrade_database:
a._upgrade_database()
sys.exit(0)

if options.list:
# print a nicely formatted list of users
header = "%-20s %-25s %-7s %-7s" % ('username', 'real name', 'trusted', 'read only')
Expand Down
57 changes: 47 additions & 10 deletions nipap/nipap/authlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,28 +377,43 @@ def __init__(self, name, username, password, authoritative_source, auth_options=

self._logger.debug('Creating SqliteAuth instance')

# make sure that user table exists
sql_verify_table = '''SELECT * FROM sqlite_master
WHERE type = 'table' AND name = 'user' '''

# connect to database
try:
self._db_conn = sqlite3.connect(self._cfg.get('auth.backends.' + self.auth_backend, 'db_path'), check_same_thread = False)
self._db_conn.row_factory = sqlite3.Row
self._db_curs = self._db_conn.cursor()
self._db_curs.execute(sql_verify_table)

if len(self._db_curs.fetchall()) < 1:
self._logger.info('user database does not exist')
self._setup_database()

except sqlite3.Error, e:
self._logger.error('Could not open user database: %s' % str(e))
raise AuthError(str(e))



def _setup_database(self):
def _latest_db_version(self):
""" Check if database is of the latest version
Fairly stupid functions that simply checks for existence of columns.
"""
# make sure that user table exists
sql_verify_table = '''SELECT * FROM sqlite_master
WHERE type = 'table' AND name = 'user' '''
self._db_curs.execute(sql_verify_table)
if len(self._db_curs.fetchall()) < 1:
raise AuthSqliteError("No 'user' table.")

for column in ('username', 'pwd_salt', 'pwd_hash', 'full_name',
'trusted', 'readonly'):
sql = "SELECT %s FROM user" % column
try:
self._db_curs.execute(sql)
except:
raise AuthSqliteError("No column '%s' on table 'user'." % column)

return True



def _create_database(self):
""" Set up database
Creates tables required for the authentication module.
Expand All @@ -418,6 +433,23 @@ def _setup_database(self):



def _upgrade_database(self):
""" Upgrade database to latest version
This is a fairly primitive function that won't look at how the
database looks like but just blindly run commands.
"""
self._logger.info('upgrading user database')
# add readonly column
try:
sql = '''ALTER TABLE user ADD COLUMN readonly NOT NULL DEFAULT 0'''
self._db_curs.execute(sql)
except:
pass
self._db_conn.commit()



def authenticate(self):
""" Verify authentication.
Expand Down Expand Up @@ -568,3 +600,8 @@ class AuthorizationFailed(AuthError):
""" Authorization failed.
"""
error_code = 1520


class AuthSqliteError(AuthError):
""" Problem with the Sqlite database
"""
11 changes: 11 additions & 0 deletions nipap/nipapd
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@ if __name__ == '__main__':
print >> sys.stderr, "Could not drop privileges to user '%s' and group '%s'" % (run_user, run_group)
sys.exit(1)

# pre-start checks
from nipap import authlib
a = authlib.SqliteAuth('local', 'a', 'b', 'c')
try:
a._latest_db_version()
except authlib.AuthSqliteError, e:
print >> sys.stderr, "Problem with Sqlite database for local auth: %s" % e
print >> sys.stderr, "Run 'nipap-passwd --upgrade-database' to upgrade your database."
sys.exit(1)


if not cfg.getboolean('nipapd', 'foreground'):
import nipap.daemon
ret = nipap.daemon.createDaemon()
Expand Down

0 comments on commit 0fda853

Please sign in to comment.