# FILE: fcn-priv.pl
# DESCRIPTION: Privilege Manipulation Functions (privs.txt)
#-------------------------------------------------------------------------------
# DISCUS COPYRIGHT NOTICE
#
# Discus is copyright (c) 2002 by DiscusWare, LLC, all rights reserved.
# The use of Discus is governed by the Discus License Agreement which is
# available from the Discus WWW site at:
#    http://www.discusware.com/discus/license
#
# Pursuant to the Discus License Agreement, this copyright notice may not be
# removed or altered in any way.
#-------------------------------------------------------------------------------

use strict;
use vars qw($GLOBAL_OPTIONS $DCONF $PARAMS);

###
### check_topic_authorization
###
### Checks to see if $moderator is authorized to edit $topic
###

sub check_topic_authorization {
	my ($moderator, $topic, $file_in) = @_;
	$moderator = lc($moderator);
	return 1 if $moderator eq $DCONF->{superuser};
	if (! defined $file_in) {
		$file_in = read_privilege_file();
	}
	return $file_in->{by_mod}->{$moderator}->{$topic};
}

###
### read_privilege_file
###
### Low-level reading of the privs.txt file
###

sub read_privilege_file {
	my ($noerr, $nolock) = @_;
	my $file = $nolock ? readfile("$DCONF->{admin_dir}/privs.txt", "read_privilege_file", { no_lock => 1, no_unlock => 1, create => $noerr, zero_ok => 1 }) : readfile("$DCONF->{admin_dir}/privs.txt", "read_privilege_file", { create => $noerr, zero_ok => 1 });
	undef my $result;
	foreach my $line (@{ $file }) {
		chomp $line;
		my ($topic, $mods) = split(/:/, $line);
		next if $topic eq "#";
		next if $topic !~ m|\S|;
		my @mods = split(/,/, $mods);
		push (@{ $result->{topic_list} }, $topic);
		foreach my $mod (@mods) {
			$result->{by_mod}->{$mod}->{$topic} = 1;
			$result->{by_topic}->{$topic}->{$mod} = 1;
		}
	}
	return $result;
}

###
### write_privilege_file
###
### Low-level writing of the privs.txt file based on a list of "actions"
###

sub write_privilege_file {
	my ($actions, $noerr) = @_;
	my @newfile = ();
	undef my $classify;
	foreach my $action (@{ $actions }) {
		my ($gq, $a, $m) = ($action->{topic}, $action->{action}, $action->{moderator});
		foreach my $g (split(/,/, $gq)) {
			if ($a eq "add_topic") {
				push (@newfile, "$g:$m\n");
			} elsif ($a eq "del_topic") {
				$classify->{$g}->{del} = 1;
			} elsif ($a eq "set_equal") {
				$classify->{$g}->{modequals} = $m;
			} else {
				foreach my $md (split(/,/, $m)) {
					if ($a eq "add_mod") {
						$classify->{$g}->{modadd}->{$md} = 1;
					} elsif ($a eq "del_mod") {
						$classify->{$g}->{moddel}->{$md} = 1;
					}
				}
			}
		}
	}
	my $file = readfile("$DCONF->{admin_dir}/privs.txt", "write_privilege_file", { no_unlock => 1, zero_ok => 1, create => $noerr });
	foreach my $line (@{ $file }) {
		my $line_manip = $line; chomp $line_manip;
		my ($topic, $mods) = split(/:/, $line_manip);
		if ($topic eq "#") {
			push (@newfile, $line); next;
		}
		if ($topic !~ m|\S|) {
			next;
		}
		if ($classify->{$topic}->{del}) {
			next;
		}
		if (defined $classify->{$topic}->{modequals}) {
			push (@newfile, "$topic:$classify->{$topic}->{modequals}\n");
			next;
		}
		my @mods = split(/,/, $mods);
		undef my @modsnew;
		undef my $seen;
		foreach my $m (@mods) {
			next if $classify->{$topic}->{moddel}->{$m};
			next if $classify->{$topic}->{modadd}->{$m};
			next if $classify->{"*"}->{moddel}->{$m};
			push (@modsnew, $m);
		}
		foreach my $k (keys(%{ $classify->{$topic}->{modadd} })) {
			push (@modsnew, $k);
		}
		$mods = join(",", sort @modsnew);
		$line_manip = join(":", $topic, $mods);
		$line_manip .= "\n";
		push (@newfile, $line_manip);
	}
	writefile("$DCONF->{admin_dir}/privs.txt", \@newfile, "write_privilege_file", { no_lock => 1, zero_ok => 1 });
}

1;
