#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License. See accompanying LICENSE file.
#

import argparse
import os,sys
import pycurl
import getpass
import logging
from StringIO import StringIO as BytesIO
def log(msg,type):
	if type == 'info':
		logging.info(" %s",msg)
	if type == 'debug':
		logging.debug(" %s",msg)
	if type == 'warning':
		logging.warning(" %s",msg)
	if type == 'exception':
		logging.exception(" %s",msg)
	if type == 'error':
		logging.error(" %s",msg)

def isPairedSwitch(value):
	isSwitch=False
	switch_arr =["-groups", "-users","-admin","-url","-sslCertPath"]
	if value in switch_arr:
		isSwitch=True
	return isSwitch

def printUsage():
	log("[I] Note : This utility can be used to delete users or groups, To delete groups refer below given first command and to delete users refer second command.","info")
	log("[I] Usage(Group delete): deleteUserGroupUtil.py -groups <group file path> -admin <ranger admin user> -url <rangerhosturl> [-force] [-sslCertPath <cert path>] [-debug]","info")
	log("[I] Usage(User delete): deleteUserGroupUtil.py -users <user file path> -admin <ranger admin user> -url <rangerhosturl> [-force] [-sslCertPath <cert path>] [-debug]","info")
	log("[I] -groups: Delete groups specified in the given file","info")
	log("[I] -users: Delete users specified in the given file","info")
	log("[I] -admin: Ranger Admin user ID","info")
	log("[I] -force: Force delete users/groups, even if they are referenced in policies","info")
	log("[I] -url: Ranger Admin URL","info")
	log("[I] -sslCertPath: Filepath to ssl certificate to use when Ranger Admin uses HTTPS","info")
	log("[I] -debug: Enables debugging","info")
	sys.exit(1)

def processRequest(url,usernamepassword,data,method,isHttps,certfile,isDebug):
	buffer = BytesIO()
	header = BytesIO()
	c = pycurl.Curl()
	c.setopt(c.URL, url)
	c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json','Accept: application/json'])
	c.setopt(pycurl.USERPWD, usernamepassword)
	c.setopt(pycurl.VERBOSE, 0)
	if isHttps==True:
		c.setopt(pycurl.SSL_VERIFYPEER,1)
		c.setopt(pycurl.SSL_VERIFYHOST,2)
		c.setopt(pycurl.CAINFO, certfile)

	c.setopt(c.WRITEFUNCTION ,buffer.write)
	c.setopt(c.HEADERFUNCTION,header.write)
	# setting proper method and parameters
	if method == 'get' :
		c.setopt(pycurl.HTTPGET, 1)
	elif method == 'delete' :
		c.setopt(pycurl.CUSTOMREQUEST, "DELETE")
		c.setopt(c.POSTFIELDS, str(data))
	else :
		log("[E] Unknown Http Request method found, only get or delete method are allowed!","error")

	c.perform()
	# getting response
	response = buffer.getvalue()
	headerResponse = header.getvalue()
	response_code=0
	response_code=str(c.getinfo(pycurl.RESPONSE_CODE))
	response_code=int(response_code)
	buffer.close()
	header.close()
	c.close()
	if isDebug ==True or (response_code!=200 and response_code!=204):
		print 'Request URL = ' + str(url)
		print 'Response    = ' + str(headerResponse)
	return response_code
def validateArgs(argv):
	if(len(argv)<7):
		log("[E] insufficient number of arguments. Found " + len(argv) + "; expected at least 7","error")
		printUsage()
	if not "-users" in argv and not "-groups" in argv:
		log("[E] -users or -groups switch was missing!","error")
		printUsage()
	if not "-admin" in argv:
		log("[E] -admin switch was missing!","error")
		printUsage()
	if not "-url" in argv:
		log("[E] -url switch was missing!","error")
		printUsage()
	if "-url" in argv:
		try:
			host=str(argv[argv.index("-url")+1])
			host=host.strip()
			if host =="" or host is None or isPairedSwitch(host):
				log("[E] invalid Ranger Admin host URL","error")
				printUsage()
			if host.lower().startswith("https"):
				if not "-sslCertPath" in argv:
					log("[E] -sslCertPath switch was missing!","error")
					printUsage()
		except IndexError:
			log("[E] missing/invalid Ranger Admin host URL","error")
			printUsage()

def main(argv):
	FORMAT = '%(asctime)-15s %(message)s'
	logging.basicConfig(format=FORMAT, level=logging.DEBUG)
	inputPath=""
	certfile=""
	tail=""
	password=""
	isHttps=False
	isUser=False
	isGroup=False
	isDebug=False
	if "-usage" in argv or "-help" in argv:
		printUsage()
	validateArgs(argv)
	for i in range(1, len(argv)) :
		if str(argv[i])== "-groups" :
			restpath= "/groups/groupName/"
			try:
				inputPath=str(argv[i+1])
				inputPath=inputPath.strip()
				if inputPath =="" or not os.path.exists(inputPath) or not os.path.isfile(inputPath) or not os.access(inputPath, os.R_OK) or isPairedSwitch(inputPath):
					log("[E] File '"+inputPath+"' does not exist or could not be read","error")
					sys.exit(1)
				else:
					isGroup=True
				if os.stat(inputPath).st_size == 0:
					log("[E] File '"+inputPath+"' is empty!","error")
					sys.exit(1)
			except IndexError:
				log("[E] missing filename after '-groups' argument","error")
				sys.exit(1)
			continue
		elif str(argv[i])== "-users" :
			restpath= "/users/userName/"
			try:
				inputPath=str(argv[i+1])
				inputPath=inputPath.strip()
				if inputPath =="" or not os.path.exists(inputPath) or not os.path.isfile(inputPath) or not os.access(inputPath, os.R_OK) or isPairedSwitch(inputPath):
					log("[E] File '"+inputPath+"' does not exist or could not be read","error")
					sys.exit(1)
				else:
					isUser=True
				if os.stat(inputPath).st_size == 0:
					log("[E] File '"+inputPath+"' is empty!","error")
					sys.exit(1)
			except IndexError:
				log("[E] missing filename after '-users' argument","error")
				sys.exit(1)
			continue

		if str(argv[i])=="-admin" :
			try:
				user=str(argv[i+1])
				if user =="" or user is None or isPairedSwitch(user):
					log("[E] missing/invalid Ranger Admin login ID for argument '-admin'","error")
					sys.exit(1)
				continue
			except IndexError:
				log("[E] missing/invalid Ranger Admin login ID for argument '-admin'","error")
				sys.exit(1)
		if str(argv[i])=="-url" :
			try:
				host=str(argv[i+1])
				host=host.strip()
				if host =="" or host is None or isPairedSwitch(host):
					log("[E] invalid Ranger Admin host URL","error")
					sys.exit(1)
				if host.lower().startswith("https"):
					isHttps=True
				continue
			except IndexError:
				log("[E] missing/invalid Ranger Admin host URL","error")
				sys.exit(1)
		if str(argv[i])=="-force" :
			tail="?forceDelete=true"
			continue
		if str(argv[i])=="-debug" :
			isDebug=True
			continue
		if isHttps == True and str(argv[i])== "-sslCertPath" :
			try:
				certfile=str(argv[i+1])
				certfile=certfile.strip()
				if certfile =="" or not os.path.exists(certfile) or not os.path.isfile(certfile) or not os.access(certfile, os.R_OK) or isPairedSwitch(certfile):
					log("[E] Certificate File '"+certfile+"' does not exist or could not be read","error")
					sys.exit(1)
			except IndexError:
				log("[E] missing/invalid SSL certificate path for argument '-sslCertPath'","error")
				sys.exit(1)
			continue
	if isUser==True and isGroup==True:
		log("[E] -users and -groups both option were provided, only one is allowed.","error")
		printUsage()
	if password =="" :
		password=getpass.getpass("Enter Ranger Admin password : ")

	usernamepassword=user+":"+password
	url=host+'/service/xusers/secure/users/roles/userName/'+user
	response_code=0
	try:
		response_code=processRequest(url,usernamepassword,None,'get',isHttps,certfile,False)
	except pycurl.error, e:
		print e
		sys.exit(1)
	if response_code == 302 or response_code==401 or response_code==403:
		log("[E] Authentication Error:Please try with valid credentials!","error")
		sys.exit(1)
	if response_code != 200:
		log("[E] Failed to contact Ranger Admin with given parameters. Please review the parameters","error")
		printUsage()
		sys.exit(1)
	f=open(inputPath,'r')
	processedRows=0
	for line in f:
		line=line.strip()
		if line == "" or line is None:
			continue
		if isUser==True and line==user:
			log("[I] Skipping deletion of user : "+line+", Self account deletion is restricted!","info")
			continue
		url=host+'/service/xusers'+restpath+line+tail
		method='delete'
		data=None
		response_code=processRequest(url,usernamepassword,data,method,isHttps,certfile,isDebug)
		if response_code==302 or response_code==401:
			if isUser==True:
				log("[E] failed while deleting user '" + line + "'. Please verify the parameters","error")
			elif isGroup==True:
				log("[E] failed while deleting group '" + line + "'. Please verify the parameters","error")
			buffer.close()
			header.close()
			break
		elif response_code==204:
			if isUser==True:
				log("[I] Deleted user : "+line,"info")
			elif isGroup==True:
				log("[I] Deleted group : "+line,"info")
			processedRows=processedRows+1
		elif response_code==404:
			if isUser==True:
				log("[E] failed while deleting user '" + line + "'. Please verify the parameters","error")
			elif isGroup==True:
				log("[E] failed while deleting group '" + line + "'. Please verify the parameters","error")
		elif response_code==400:
			if isUser==True:
				log("[I] User not found : "+line,"info")
			elif isGroup==True:
				log("[I] Group not found : "+line,"info")

	f.close()
	if processedRows==0:
		if isUser==True:
			log("[I] No valid user found to delete!","info")
		elif isGroup==True:
			log("[I] No valid group found to delete!","info")
	else:
		if isUser==True:
			log("[I] Number of user deleted : "+str(processedRows),"info")
		elif isGroup==True:
			log("[I] Number of group deleted : "+str(processedRows),"info")
main(sys.argv)
