#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
#
# Univention Management Console
#  Create UMC ACLs for local user
#
# Copyright 2006-2014 Univention GmbH
#
# http://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.

import cPickle
import os
from optparse import OptionParser
import sys

from univention.management.console.acl import Rule

import univention.config_registry as ucr

OPERATIONS = ( 'show', 'reset', 'allow', 'remove' )
_cache_dir = '/var/cache/univention-management-console/acls'

configRegistry = ucr.ConfigRegistry()
configRegistry.load()

parser = OptionParser( usage = '%%prog (%s) [options]' % '|'.join( OPERATIONS ) )
parser.add_option( '-u', '--user', action = 'store',
				   dest = 'user', default = 'root',
				   help = 'define the user who should get access [default: %default]' )
parser.add_option( '-c', '--command', type = 'string', action = 'append',
				   dest = 'commands', default = [],
				   help = 'defines a list of UMC commands (or patterns)' )
parser.add_option( '-f', '--flavor', type = 'string', action = 'store',
				   dest = 'flavor', default = '*',
				   help = 'defines the flavor' )
parser.add_option( '-H', '--host', type = 'string', action = 'store',
				   dest = 'host', default = configRegistry[ 'hostname' ],
				   help = 'on which host the commands are allowed [default: %default]' )

( options, args ) = parser.parse_args()

if len( args ) < 1:
	parser.error( 'operation missing' )
	sys.exit( 1 )
operation = args[ 0 ]
if not operation in OPERATIONS:
	parser.error( 'unknown operation %s' % operation )
	sys.exit( 1 )

filename = os.path.join( _cache_dir, options.user )
if os.path.isfile( filename ) and operation in ( 'show', 'allow', 'remove' ):
	try:
		fd = open( filename )
		acls = cPickle.load( fd )
		print 'loaded pickle file', filename
	except:
		acls = []
	finally:
		fd.close()
else:
	acls = []

# convert old format
new_acls = []
if isinstance( acls, dict ):
	for rule in acls[ 'allow' ]:
		rule = Rule( rule )
		if not rule in new_acls:
			new_acls.append( rule )
else: # check for duplicates
	for rule in acls:
		rule = Rule( rule )
		if not rule in new_acls:
			new_acls.append( rule )
acls = new_acls

if operation == 'show':
	print 'Username: %s' % options.user
	for acl in acls:
		print '     Host: %-10s Command: %-15s Flavor: %-14s Options: %s' % ( acl.host, acl.command, acl.flavor, str( acl.options ) )
	sys.exit( 0 )
elif operation == 'allow':
	for command in options.commands:
		rule = Rule( { 'fromUser': False, 'host': options.host, 'command': command, 'flavor': options.flavor } )
		if not rule in acls:
			acls.append( rule )
			print 'info: rule %s appended' % command
		else:
			print 'warning: rule %s already exists' % command
elif operation == 'remove':
	acls = filter( lambda item: item.command not in options.commands,  acls )
elif operation == 'reset':
	pass # nothing todo as the acls dict is already "reset" and will be written in the next step

fd = open( filename, 'w' )
fd.write( cPickle.dumps( acls ) )
fd.close()
