#!/bin/bash

# Workaround for :
# semanage user -l | cat
# UnicodeEncodeError: ascii
export LC_MESSAGES=C

alterator_api_version=1

. alterator-sh-functions
. shell-quote

list_sensitivity()
{
	local sensitivity_ru=
	local seman="$(/usr/bin/seinfo --sensitivity | sed -n '3,${p}' )"
	while read sensitivity
	do
		sensitivity_ru="$(/usr/bin/selinux-seusers-fn -t $sensitivity)"
		write_enum_item "$sensitivity" "$sensitivity_ru"
	done < <(echo "$seman")
}

list_category()
{
	local category_ru=
        local seman="$(echo "$in_categories" | tr ';' '\n')"

	if [ -n "$seman" ]; then
	    while read category
	    do
		category_ru="$(selinux-seusers-fn -t $category)"
		write_enum_item "$category" "$category_ru"
	    done < <(echo "$seman")
	fi
}

list_all_categories()
{
	local category_ru=
	local seman="$(/usr/bin/seinfo --category | sed -n '2,${p}' )"
	while read category
	do
		category_ru="$(/usr/bin/selinux-seusers-fn -t $category)"
		write_enum_item "$category" "$category_ru"
	done < <(echo "$seman")
}

list_seusers()
{
	local seman=$(/usr/sbin/semanage user -l | sed -n '5,${p}' | awk -F\  '{print $1}')
	while read seuser
	do
		write_table_item name "$seuser" label "$seuser"
	done < <(echo "$seman")
}

list_role()
{
	local seman="$(/usr/bin/seinfo -r | sed -n '3,${p}' )"

	while read role
	do
		write_table_item name "$role" label "$role"
	done < <(echo "$seman")
}

new_user()
{
	local role="$(seinfo -r | sed '3!d')"
	semanage user -a -R "$role" -r s0 "$in_new_name"
}

list_to_range()
{
	if [ -z "$1" ]; then
		return
	fi

	local seman="$(echo "$(echo "$1" | grep -o "[0-9]*")")"
	local index=
	local range=
	local prev_cat=
	while read category
	do
		if [ -z "$index" ]; then
			range="c$category"
			prev_cat="$category"
			index="$category"
		elif [ "$(($category-$prev_cat))" != "1" ]; then
			if [ "$index" != "$prev_cat" ]; then
				range="$range"".c$prev_cat"",c$category"
			else
				range="$range"",c$category"
			fi
			index="$category"
			prev_cat="$category"
		elif [ "$(($category-$prev_cat))" == "1" ];then
			prev_cat="$category"
		fi
	done < <(echo "$seman")
	if [ "$(($prev_cat-$index))" != "1" ]; then
		if [ "$(($prev_cat-$index))" != "0" ]; then
			range="$range"".c$prev_cat"
		fi
	else
		range="$range"",c$prev_cat"
	fi
	echo "$range"
}

have_users()
{
	local index=
	local seman=$(/usr/sbin/semanage login -l | sed -n '4,${p}')
	while read username seuser range
	do
		if [ "$seuser" == "$in_users" ]; then
			index="yes"
		fi
	done < <(echo "$seman")
	echo "$index"
}

change_user()
{
	if [ -n "$(have_users)" ];then
		return
	fi

	local minlvl="$in_minlevel"
	local maxlvl="$in_maxlevel"

	local mincat="$(list_to_range $in_category)"
	local maxcat="$(list_to_range $in_categories)"
	local range=

	local role="$(echo "$in_roles" | tr ';' ' ')"

	if [ "$minlvl$mincat" != "$maxlvl$maxcat" ]; then
		if [ -n "$mincat" ]; then
			range="$minlvl:$mincat-"
		else
			range="$minlvl-"
		fi
	fi

	if [ -n "$maxcat" ]; then
		range="$range""$maxlvl"":$maxcat"
	else
		range="$range""$maxlvl"
	fi

	semanage user -m -R "$role" -r "$range" "$in_users"
}

delete_user()
{
	if [ -z "$(have_users)" ]; then
		semanage user -d "$in_users"
	fi
}

on_message()
{
	case "$in_action" in
		read)
		 local maxrange="$(echo "$(selinux-users-fn maxcat "$(selinux-seusers-fn -u $in_users)")" | tr '\n' ';')"
		 local minrange="$(echo "$(selinux-users-fn mincat "$(selinux-seusers-fn -u $in_users)")" | tr '\n' ';')"

		 local maxlvl="$(echo "$(selinux-seusers-fn -u $in_users)" | awk -F\- '{print $2}' | awk -F\: '{print $1}')"
		 local minlvl="$(echo "$(selinux-seusers-fn -u $in_users)" | awk -F\- '{print $1}' | awk -F\: '{print $1}')"

		 if [ -z "$maxlvl" ]; then
			 maxlvl="$minlvl"
		 fi

		 if [ "$maxrange" = ';' ]; then
			 maxrange=$minrange
		 fi

		  write_string_param maxlevel "$maxlvl"
		  write_string_param minlevel "$minlvl"
		  write_string_param category "$minrange"
		  write_string_param categories "$maxrange"
		  write_string_param roles "$(echo "$(selinux-seusers-fn -r $in_users)" | tr '\n' ';')"

		;;
	esac
}

alterator_export_proc list_sensitivity
alterator_export_proc list_category
alterator_export_proc list_all_categories
alterator_export_proc list_seusers
alterator_export_proc list_role

alterator_export_proc new_user
alterator_export_proc change_user
alterator_export_proc delete_user

message_loop
