## OpenCA - Command
## (c) 1998-2001 by Massimiliano Pala and OpenCA Group
## (c) Copyright 2002-2004 The OpenCA Project
##
##   File Name: lists
##       Brief: lists objects
## Description: lists requests and certificates
##  Parameters: action (type of list)

use strict;

sub cmdLists {

my $action = $query->param('action');
my $dataType;

if ( "$action" eq "" ) {
        configError(gettext("Command Error (Command Missing)"));
}


## Variables Definition
my $getID_url = 'pki?cmd=viewCert;';

my $from    = ( $query->param( 'viewFrom' ) or 0 );
my $matched = $query->param( 'rows' );

## Set the column titles
my ( $dbItem, $listType, @list, @cols, $newCMD );

my ($item_list, $cmd_panel) = (undef, undef);
$item_list->{BODY} = [];

## Differentiate the list parameters
if( $action =~ /^certsList/i) {
	$dataType  = 'VALID_CERTIFICATE';
	$listType  = gettext("Valid Certificates");

	$newCMD    = $getID_url;

	$item_list->{HEAD}->[0] = gettext("Serial");
	$item_list->{HEAD}->[1] = gettext("Common Name");
	$item_list->{HEAD}->[2] = gettext("Issued on");
	$item_list->{HEAD}->[3] = gettext("E-Mail");
	$item_list->{HEAD}->[4] = gettext("Role");

} elsif( $action =~ /^certsExpiredList/i) {
	$dataType  = 'EXPIRED_CERTIFICATE';
	$listType  = gettext("Expired Certificates");

	$newCMD    = $getID_url;

	$item_list->{HEAD}->[0] = gettext("Serial");
	$item_list->{HEAD}->[1] = gettext("Common Name");
	$item_list->{HEAD}->[2] = gettext("Issued on");
	$item_list->{HEAD}->[3] = gettext("E-Mail");
	$item_list->{HEAD}->[4] = gettext("Role");

} elsif( $action =~ /^newReqs/i) {
	$dataType  = 'NEW_REQUEST';
	$listType  = gettext("New Requests");

	$item_list->{HEAD}->[0] = gettext("Serial");
	$item_list->{HEAD}->[1] = gettext("Requested By");
	$item_list->{HEAD}->[2] = gettext("Requested on");
	$item_list->{HEAD}->[3] = gettext("Requested Role");

} elsif ( $action =~ /^revokedList/i ) {
	$dataType  = 'REVOKED_CERTIFICATE';
	$listType  = gettext("Revoked Certificates");

	$newCMD    = $getID_url;

	$item_list->{HEAD}->[0] = gettext("Serial");
	$item_list->{HEAD}->[1] = gettext("Common Name");
	$item_list->{HEAD}->[2] = gettext("Revoked On");
	$item_list->{HEAD}->[3] = gettext("E-Mail");
	$item_list->{HEAD}->[4] = gettext("Role");

} elsif ( $action =~ /^suspendedList/i ) {
	$dataType  = 'SUSPENDED_CERTIFICATE';
	$listType  = gettext("Suspended Certificates");

	$newCMD    = $getID_url;

	$item_list->{HEAD}->[0] = gettext("Serial");
	$item_list->{HEAD}->[1] = gettext("Common Name");
	$item_list->{HEAD}->[2] = gettext("Suspended On");
	$item_list->{HEAD}->[3] = gettext("E-Mail");
	$item_list->{HEAD}->[4] = gettext("Role");

} elsif( $action =~ /^newCRRs/i) {
	$dataType  = 'NEW_CRR';
	$listType  = gettext("New Requests");

	$item_list->{HEAD}->[0] = gettext("Serial");
	$item_list->{HEAD}->[1] = gettext("Requested By");
	$item_list->{HEAD}->[2] = gettext("Requested on");
	$item_list->{HEAD}->[3] = gettext("Affected Role");

} else {
	configError(gettext("Requested List NOT available"));
}

## Get required parameters ( return only the value string )
my $maxItems 	= getRequired( "maxReturnedItems" );

if ( not $matched ) {
	$matched  = $db->elements( DATATYPE=>$dataType );
};

@list = $db->listItems( DATATYPE=>$dataType, FROM=>$from, ITEMS=>$maxItems );

if (not @list) {
	$cmd_panel->[0] = $query->buildRefs(
			ELEMENTS  => $matched,
			MAXITEMS  => $maxItems,
			FACTOR    => 5,
			MODE      => "EXP",
			NOW_FIRST => 0,
			NOW_LAST  => 0,
			FIRST     => 0,
			LAST      => 0);
} else {
	$cmd_panel->[0] = $query->buildRefs(
			ELEMENTS  => $matched,
			MAXITEMS  => $maxItems,
			FACTOR    => 5,
			MODE      => "EXP",
			NOW_FIRST => $list[0]->getSerial($dataType),
			NOW_LAST  => $list[scalar (@list) -1]->getSerial($dataType),
			FIRST     => libDBGetFirstItem ($dataType)->getSerial($dataType),
			LAST      => libDBGetLastItem ($dataType)->getSerial($dataType));
}

## Process all Files
foreach $dbItem ( @list ) {

	## Common Variables
	my ( $format, $key, $ser_col, $op_col, $email, $email_col, $role_col );
	my ( $lnk, $parsed, $head );
	my ( $hex, $notBefore, $submit );

        my $pos = scalar @{$item_list->{BODY}};
        my $index = 0;

	$parsed = $dbItem->getParsed();
	$head	= $parsed->{HEADER};

        $key    = $dbItem->getSerial();
	$hex	= " (0x".sprintf("%X",$key).")";
	$submit = $parsed->{DN_HASH}->{CN}[0];

        $notBefore = ( $parsed->{NOTBEFORE} or $head->{NOTBEFORE}
			or $parsed->{SUBMIT_DATE} );

	if( $dataType =~ /CRR/ ) {
		if ($parsed->{SIGNATURE}) {
			## signature-based revocation
			if (my $sig = libGetSignatureObject ( OBJECT => $dbItem )) {
				if (my $cert = libGetSignerCertificateDB( SIGNATURE=> $sig )) {
					$submit = $cert->getParsed()->{DN};
				} else {
					$submit = gettext("Cannot determine certificate from signature!");
					print STDERR i18nGettext ("Cannot determine certificate from signature (CRR: __SERIAL__).",
                                                                  "__SERIAL__", $key)."\n";
				}
			} else {
				$submit = gettext("Cannot build object from signature!");
				print STDERR i18nGettext ("Cannot build object from signature (CRR: __SERIAL__).",
                                                          "__SERIAL__", $key)."\n";
			}

		} elsif ($parsed->{REVOKE_CERTIFICATE_DN}) {
			## pin-based revocation
			$submit = $parsed->{REVOKE_CERTIFICATE_DN};
		} else {
			## last chance by strong ssl-authentication
			$submit = $parsed->{HEADER}->{SSL_CERT_DN};
			print STDERR i18nGettext ("submitter of CRR not determinable (CRR: __SERIAL__).",
                                                  "__SERIAL__", $key)."\n";
		}
	}

	if( $dataType =~ /CERTIFICATE/i ) {
        	$ser_col = "<a class=\"list\" href=\"$newCMD&dataType=$dataType" .
                		"&key=$key\">". $key.$hex ."</a>";
	} else {
		$ser_col = $key.$hex;
	}

        if( (not $head->{OPERATOR}) or ($head->{OPERATOR} eq gettext("n/a")) ) {
                $op_col = gettext("n/a");
        } else {
                my $tmpOp = $head->{OPERATOR};
                $op_col = "<a class=\"list\" href=\"$self?cmd=searchCert&dataType=" .
                          "CERTIFICATE&key=$tmpOp\">" .
                           $tmpOp ."</a>";
        }

	if ($dataType =~ /CRR/) {
		my $cert = $db->getItem (
					DATATYPE => "CERTIFICATE",
					KEY => $parsed->{REVOKE_CERTIFICATE_SERIAL} );
		if ($cert) {
			$role_col = $cert->getParsed()->{HEADER}->{ROLE};
		} else {
			$role_col = "<font color=#ff0000>".
				gettext ("Cannot load the affected certificate!")."</font>";
		}
	} else {
		$role_col = $head->{ROLE};
	}

        $item_list->{BODY}->[$pos]->[$index++] = $ser_col;
        $item_list->{BODY}->[$pos]->[$index++] = ( $submit or gettext("n/a") );
        $item_list->{BODY}->[$pos]->[$index++] = ( $notBefore or gettext("n/a") );

	if( $dataType =~ /CERTIFICATE/ ) {
	    if( $parsed->{EMAILADDRESSES} ) {
	        $email_col = "";
	        foreach my $address (@{$parsed->{EMAILADDRESSES}})
	        {
                    $email_col .= ", " if ($email_col);
                    $lnk = new CGI({
                                subject=>i18nGettext ("Certificate Serial __CERT_SERIAL__",
                                                      "__CERT_SERIAL__", $key)});
                    $email_col .= $lnk->a({-class=>"list", -href=>"mailto:$address"},
                                          $address );
                }
            } else {
                $email_col = gettext ("n/a");
            };
            $item_list->{BODY}->[$pos]->[$index++] = $email_col;
	}
	$item_list->{BODY}->[$pos]->[$index++] = $role_col;
}

return libSendReply (
                     "NAME"      => gettext ($listType),
                     "ITEM_LIST" => $item_list,
                     "CMD_PANEL" => $cmd_panel,
                     "TIMESTAMP" => 1
                    );
}

1;

