#!/bin/sh -efu

. girar-sh-functions

[ -n "${GIRAR_USER-}" ] ||
	fatal 'GIRAR_USER undefined'

usage()
{
	echo >&2 "$PROG: $*"
	echo >&2 "usage: $PROG <project name> <binary package repository name>"
	exit 1
}

[ "$#" -ge 2 ] ||
	usage 'Not enough arguments.'
[ "$#" -le 2 ] ||
	usage 'Too many arguments.'

project_name="$1"; shift
repository="$1"; shift

allow()
{
	message "access to $project_name ALLOWED for $GIRAR_USER: $*"
	exit 0
}

deny()
{
	message "access to $project_name DENIED for $GIRAR_USER: $*"
	exit 1
}

cd "$HOME"

# Returns:
# 0 - $GIRAR_USER is allowed to request build of $project_name for binary $repository;
# 1 - otherwise.

# Denied if no non-empty repository list available.
[ -s "$GIRAR_REPOSITORIES" ] ||
	deny 'repository list not available'

# Denied if requested binary repository is not listed.
fgrep -ixqse "$repository" "$GIRAR_REPOSITORIES" ||
	deny "invalid repository \`$repository', valid repositories are: $(tr -s '\n' ' '<"$GIRAR_REPOSITORIES")"

# Normalize binary repository name.
repository="$(printf %s "$repository" |tr '[:upper:]' '[:lower:]')"

# Denied if no acl file available for the given binary repository.
[ -s "$GIRAR_ACL_CONF_DIR/list.packages.$repository" ] ||
	deny "acl file for repository \`$repository' not available"

# Allowed if package is not listed in acl file.
acl_line="$(grep "^$project_name[[:space:]]" "$GIRAR_ACL_CONF_DIR/list.packages.$repository")" ||
	allow "project \`$project_name' is not listed in acl file for repository \`$repository'"

# acl_line format: pkg_name leader [builders]
set -- ${acl_line}
[ $# -ge 2 ] ||
	deny "acl file for repository \`$repository' contains invalid acl entry: $acl_line"
leader="$2"; shift 2
builders="$*"

# Allowed if $GIRAR_USER is superuser.
[ "$GIRAR_USER" != 'root' ] ||
	allow 'superuser'

# Allowed if $GIRAR_USER is leader.
[ "$GIRAR_USER" != "$leader" ] ||
	allow 'project leader'

# Allowed if there are no leader
[ "$leader" != '@nobody' ] ||
	allow 'project is orphaned'

# Wildcard builders are allowed.
[ "$builders" != '*' -a "$builders" != '@everybody' ] ||
	allow 'project leader welcomes random builders'

# Separate people and groups.
groups=
people=
for o in ${leader} ${builders}; do
	[ -z "${o%%@*}" ] &&
		groups="$groups|$o" ||
		people="$people $o"
done
groups="${groups#|}"

# Allowed if $GIRAR_USER is listed in $people.
if printf %s " $people " |fgrep -qs " $GIRAR_USER "; then
	allow 'approved builder'
fi

# Expand groups if any.
if [ -n "$groups" -a -s "$GIRAR_ACL_CONF_DIR/list.groups.$repository" ]; then
	gpeople="$(sed -r -n "s/^($groups)[[:space:]]+//p" "$GIRAR_ACL_CONF_DIR/list.groups.$repository")"
	gpeople="$(printf %s "$gpeople" |tr -s '[:space:]' ' ')"

	# Allowed if $GIRAR_USER is listed in $gpeople.
	if printf %s " $gpeople " |fgrep -qs " $GIRAR_USER "; then
		allow 'member of approved group'
	fi
fi

if [ -s "$GIRAR_ACL_CONF_DIR/list.nmu.$repository" ]; then
	cur_time="$(date +'%s')"
	while read proj builder start_time end_time; do
		[ "$project_name" = "$proj" ] &&
			[ "$builder" = '*' -o "$builder" = "$GIRAR_USER" ] &&
			[ $cur_time -gt "$start_time" ] &&
			[ $end_time -eq 0 -o $cur_time -lt $end_time ] ||
			continue
		allow 'approved NMU builder'
	done < "$GIRAR_ACL_CONF_DIR/list.nmu.$repository"
fi

deny "does not belong to approved builders list: $leader $builders"
