#!/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
repo="$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

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

repository="$(girar-normalize-repo-name "$repo")" ||
	deny "invalid repository \`$repository'"

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

# Allowed if $GIRAR_USER is superuser.
if girar-check-superuser "$repository"; then
	allow 'superuser'
fi

# Source per-repository config file.
conf="$GIRAR_REPO_CONF_DIR/$repository"
if [ -s "$conf" ]; then
	. "$conf"
fi

# Allowed if package is not listed in acl file.
if ! acl_line="$(grep "^$project_name[[:space:]]" "$GIRAR_ACL_CONF_DIR/list.packages.$repository")"; then
	if [ -z "${GIRAR_ACL_DENY_UNLISTED-}" ]; then
		exit=allow
	else
		exit=deny
	fi
	$exit "project \`$project_name' is not listed in acl file for repository \`$repository'"
fi

# 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 leader.
[ "$GIRAR_USER" != "$leader" ] ||
	allow 'project leader'

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

# Wildcard builders are allowed.
case " $builders " in
	*' * '*|*' @everybody '*)
		allow 'project leader welcomes random builders' ;;
esac

# 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

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