#!/usr/libexec/platform-python
#
# Test script for shadow utils
#
# Copyright (C) 2021 Olaf Kirch <okir@suse.de>

import os
import susetest

# This test will only work if sudoers file contains "Defaults targetpw", as
# is the shipping default with SUSE
@susetest.test
def verify_rootpass(driver):
	'''sudo.rootpass: verify sudo with root password'''
	state = driver.client.managers.sudo

	if not state.targetpwEnabled:
		driver.skipTest()
		return

	node = state.target

	state.sudoResetTimestamp()

	state.logInfo("sudo should ask for root password on first attempt")
	if not state.runSudoWithPassword("true", state.root):
		return

	state.logInfo("OKAY, this seems to work as expected")

@susetest.test
def verify_sudoer(driver):
	'''sudo.sudoer: verify sudo with sudoer entry requiring no password'''
	state = driver.client.managers.sudo
	node = state.target

	state.createSudoerEntry(state.test_user, nopasswd = True)

	node.logInfo("sudo should not ask for password")
	if not state.runSudoWithoutPassword("true"):
		return

	node.logInfo("OKAY, this seems to work as expected")
	state.removeSudoerEntry(state.test_user)

@susetest.test
def verify_listing(driver):
	'''sudo.listing: verify that sudo -l works'''
	state = driver.client.managers.sudo
	node = state.target

	state.createSudoerEntry(state.test_user, nopasswd = True)

	st = node.run("sudo -l", user = state.test_user, tty = True, stdin = None, timeout = 10)
	if not st:
		node.logFailure(f"sudo -l failed: {st.message}")
		state.removeSudoerEntry(state.test_user)
		return

	node.logInfo("OKAY, this seems to work as expected")
	state.removeSudoerEntry(state.test_user)

@susetest.test
def verify_sudoer_password(driver):
	'''sudo.sudoer-pass: verify sudo with sudoer entry requiring password'''
	state = driver.client.managers.sudo
	node = state.target

	state.createSudoerEntry(state.test_user, nopasswd = False)

	node.logInfo("sudo should ask for password")
	if not state.runSudoWithPassword("true"):
		state.removeSudoerEntry(state.test_user)
		return

	node.logInfo("OKAY, this seems to work as expected")
	state.removeSudoerEntry(state.test_user)

@susetest.test
def verify_cachedcreds(driver):
	'''sudo.cachedcreds: verify that sudo caches credentials'''
	state = driver.client.managers.sudo

	state.createSudoerEntry(state.test_user, nopasswd = False)

	state.logInfo("sudo should accept user without password on second attempt")
	if not state.runSudoWithPassword("true && sleep 1 && sudo true"):
		state.target.run("journalctl -e | tail -20")
		state.removeSudoerEntry(state.test_user)
		return

	state.logInfo("OKAY, this seems to work as expected")
	state.removeSudoerEntry(state.test_user)

# FIXME: This test case is broken
@susetest.test
def verify_clearcreds(driver):
	'''sudo.clearcreds: verify that we can clear cached sudo credentials'''

	# broken - skip this for now
	driver.skipTest()
	return

	state = driver.client.managers.sudo

	state.sudoResetTimestamp()

	state.logInfo("after clearing credentials, sudo should ask for password again")
	if not state.runSudoWithPassword("true"):
		return

	if not state.sudoResetTimestamp():
		return

	state.logInfo("OKAY, this seems to work as expected")

# boilerplate tests
susetest.template('selinux-verify-executable', 'sudo')

if __name__ == '__main__':
	susetest.perform()
