Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1597 lines (1146 sloc)
35.6 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
###################################################################### | |
# | |
# EPrints::DataObj::User | |
# | |
###################################################################### | |
# | |
# | |
###################################################################### | |
=pod | |
=for Pod2Wiki | |
=head1 NAME | |
B<EPrints::DataObj::User> - Class representing a single user. | |
=head1 DESCRIPTION | |
This class represents a single eprint user record and the metadata | |
associated with it. | |
EPrints::DataObj::User is a subclass of EPrints::DataObj with the following | |
metadata fields (plus those defined in ArchiveMetadataFieldsConfig: | |
=head1 SYSTEM METADATA | |
=over 4 | |
=item userid (int) | |
The unique ID number of this user record. Unique within the current repository. | |
=item rev_number (int) | |
The revision number of this record. Each time it is changed the revision | |
number is increased. This is not currently used for anything but it may | |
be used for logging later. | |
=item username (text) | |
The username of this user. Used for logging into the system. Unique within | |
this repository. | |
=item password (secret) | |
The crypted password for this user as generated by L<EPrints::Utils/crypt>. | |
This may be ignored if for example LDAP authentication is being used. | |
=item usertype (namedset) | |
The type of this user. The options are configured in metadata-phrases.xml. | |
=item newemail (email) | |
Used to store a new but as yet unconfirmed email address. | |
=item newpassword (secret) | |
Used to store a new but as yet unconfirmed password. | |
=item pin (text) | |
A code required to confirm a new username or password. This code is emailed | |
to the user to confirm they are who they say they are. | |
=item pinsettime (int) | |
When the pin code was set, so we can make it time out. | |
=item joined (time) | |
The date and time that the user account was created. Before EPrints 2.4 this | |
was a date field so users created before the upgrade will appear to have been | |
created at midnight. | |
=item email (email) | |
The email address of this user. Unique within the repository. | |
=item lang (namedset) | |
The ID of the preferred language of this user. Only really used in multilingual | |
repositories. | |
=item editperms (search, multiple) | |
This field is used to filter what eprints a staff member can approve and | |
modify. If it's unset then they can modify any (given the correct privs. but | |
if it is set then an eprint must match at least one of the searches to be | |
within their scope. | |
=item frequency (set) | |
Only relevant to staff accounts. Is the frequency they want to be mailed | |
about eprints matching their scope that are in editorial review. never, | |
daily, weekly or monthly. | |
=item mailempty (boolean) | |
Only relevant to staff accounts. If set to true then emails are sent | |
even if there are no items matching the scope. | |
=item preference (compound) | |
User preferences which need to be persistent (simple key-value pairs). | |
=back | |
=head1 METHODS | |
=over 4 | |
=cut | |
package EPrints::DataObj::User; | |
@ISA = ( 'EPrints::DataObj' ); | |
use EPrints; | |
use EPrints::Search; | |
use strict; | |
###################################################################### | |
=pod | |
=item $field_info = EPrints::DataObj::User->get_system_field_info | |
Return an array describing the system metadata of the this | |
dataset. | |
=cut | |
###################################################################### | |
sub get_system_field_info | |
{ | |
my( $class ) = @_; | |
return | |
( | |
{ name=>"userid", type=>"counter", required=>1, import=>0, can_clone=>1, | |
sql_counter=>"userid" }, | |
{ name=>"rev_number", type=>"int", required=>1, can_clone=>0, | |
default_value=>1 }, | |
{ name=>"saved_searches", type=>"subobject", datasetid=>'saved_search', | |
multiple=>1 }, | |
{ name=>"username", type=>"id", required=>1 }, | |
{ name=>"password", type=>"secret", show_in_html=>0, | |
fromform=>\&EPrints::Utils::crypt_password }, | |
{ name=>"usertype", type=>"namedset", required=>1, | |
set_name=>"user", input_style=>"medium", default_value=>"user" }, | |
{ name=>"newemail", type=>"email", show_in_html=>0 }, | |
{ name=>"newpassword", type=>"secret", show_in_html=>0, | |
fromform=>\&EPrints::Utils::crypt_password }, | |
{ name=>"pin", type=>"text", show_in_html=>0 }, | |
{ name=>"pinsettime", type=>"int", show_in_html=>0 }, | |
{ name=>"joined", type=>"timestamp", required=>1 }, | |
{ name=>"email", type=>"email", required=>1 }, | |
{ name=>"lang", type=>"arclanguage", required=>0, | |
input_rows=>1 }, | |
{ name => "editperms", | |
multiple => 1, | |
input_ordered => 0, | |
input_add_boxes => 1, | |
input_boxes => 1, | |
type => "search", | |
datasetid => "eprint", | |
fieldnames_config => "editor_limit_fields", | |
}, | |
{ name => "roles", multiple => 1, type => "id", text_index=>0 }, | |
{ name=>"frequency", type=>"set", input_style=>"medium", | |
options=>["never","daily","weekly","monthly"], | |
default_value=>"never" }, | |
{ name=>"mailempty", type=>"boolean", input_style=>"radio", | |
default_value=>"FALSE" }, | |
{ name=>"items_fields", type=>"fields", datasetid=>"eprint", | |
multiple=>1, input_ordered=>1, required=>1, volatile=>1 }, | |
{ name=>"latitude", type=>"float", required=>0 }, | |
{ name=>"longitude", type=>"float", required=>0 }, | |
{ | |
name => "preference", | |
type => "storable", | |
sql_index => 0, | |
text_index => 0, | |
volatile => 1, | |
}, | |
) | |
}; | |
###################################################################### | |
=pod | |
=item $user = EPrints::DataObj::User->new( $session, $userid ) | |
Load the user with the ID of $userid from the database and return | |
it as an EPrints::DataObj::User object. | |
=cut | |
###################################################################### | |
sub new | |
{ | |
my( $class, $session, $userid ) = @_; | |
return $session->get_database->get_single( | |
$session->dataset( "user" ), | |
$userid ); | |
} | |
###################################################################### | |
=pod | |
=item $user = EPrints::DataObj::User->new_from_data( $session, $data ) | |
Construct a new EPrints::DataObj::User object based on the $data hash | |
reference of metadata. | |
Used to create an object from the data retrieved from the database. | |
=cut | |
###################################################################### | |
sub new_from_data | |
{ | |
my( $class, $session, $known ) = @_; | |
return $class->SUPER::new_from_data( | |
$session, | |
$known, | |
$session->dataset( "user" ) ); | |
} | |
###################################################################### | |
# =pod | |
# | |
# =item $user = EPrints::DataObj::User::create( $session, $user_type ) | |
# | |
# Create a new user in the database with the specified user type. | |
# | |
# =cut | |
###################################################################### | |
sub create | |
{ | |
my( $session, $user_type ) = @_; | |
return EPrints::DataObj::User->create_from_data( | |
$session, | |
{ usertype=>$user_type }, | |
$session->dataset( "user" ) ); | |
} | |
###################################################################### | |
# =pod | |
# | |
# =item $dataobj = EPrints::DataObj->create_from_data( $session, $data, $dataset ) | |
# | |
# Create a new object of this type in the database. | |
# | |
# $dataset is the dataset it will belong to. | |
# | |
# $data is the data structured as with new_from_data. | |
# | |
# =cut | |
###################################################################### | |
sub create_from_data | |
{ | |
my( $class, $session, $data, $dataset ) = @_; | |
my $new_user = $class->SUPER::create_from_data( $session, $data, $dataset ); | |
$new_user->update_triggers(); | |
if( scalar( keys %{$new_user->{changed}} ) > 0 ) | |
{ | |
# Remove empty slots in multiple fields | |
$new_user->tidy; | |
# Write the data to the database | |
$session->get_database->update( | |
$new_user->{dataset}, | |
$new_user->{data}, | |
$new_user->{changed} ); | |
} | |
$session->get_database->counter_minimum( "userid", $new_user->get_id ); | |
return $new_user; | |
} | |
###################################################################### | |
=pod | |
=item $dataset = EPrints::DataObj::User->get_dataset_id | |
Returns the id of the L<EPrints::DataSet> object to which this record belongs. | |
=cut | |
###################################################################### | |
sub get_dataset_id | |
{ | |
return "user"; | |
} | |
###################################################################### | |
=pod | |
=item $defaults = EPrints::DataObj::User->get_defaults( $session, $data ) | |
Return default values for this object based on the starting data. | |
=cut | |
###################################################################### | |
# inherrits | |
###################################################################### | |
=pod | |
=item $user = EPrints::DataObj::User::user_with_email( $session, $email ) | |
Return the EPrints::user with the specified $email, or undef if they | |
are not found. | |
=cut | |
###################################################################### | |
sub user_with_email | |
{ | |
my( $repo, $email ) = @_; | |
my $dataset = $repo->dataset( "user" ); | |
$email = $repo->get_database->ci_lookup( | |
$dataset->field( "email" ), | |
); | |
my $results = $dataset->search( | |
filters => [ | |
{ | |
meta_fields => [qw( email )], | |
value => $email, match => "EX" | |
} | |
]); | |
return $results->item( 0 ); | |
} | |
###################################################################### | |
=pod | |
=item $user = EPrints::DataObj::User::user_with_username( $session, $username ) | |
Return the EPrints::user with the specified $username, or undef if | |
they are not found. | |
=cut | |
###################################################################### | |
sub user_with_username | |
{ | |
my( $repo, $username ) = @_; | |
my $dataset = $repo->dataset( "user" ); | |
$username = $repo->get_database->ci_lookup( | |
$dataset->field( "username" ), | |
$username | |
); | |
my $results = $dataset->search( | |
filters => [ | |
{ | |
meta_fields => [qw( username )], | |
value => $username, | |
match => "EX" | |
} | |
]); | |
return $results->item( 0 ); | |
} | |
###################################################################### | |
=pod | |
=item $problems = $thing->validate | |
Validate the user - find out if all the required fields are filled | |
out, and that what's been filled in is OK. Returns a reference to an | |
array of problem descriptions. | |
If there are no probelms then the array is empty. | |
The problems are XHTML DOM objects describing the problem. | |
=cut | |
###################################################################### | |
sub validate | |
{ | |
my( $self, $for_archive, $workflow_id ) = @_; | |
$workflow_id = "default" if !defined $workflow_id; | |
my @problems; | |
my $user_ds = $self->{session}->get_repository->get_dataset( "user" ); | |
my %opts = ( item=> $self, session=>$self->{session} ); | |
my $workflow = EPrints::Workflow->new( $self->{session}, $workflow_id, %opts ); | |
push @problems, $workflow->validate; | |
push @problems, @{ $self->SUPER::validate( $for_archive ) }; | |
return( \@problems ); | |
} | |
###################################################################### | |
=pod | |
=item $user->commit( [$force] ) | |
Write this object to the database. | |
If $force isn't true then it only actually modifies the database | |
if one or more fields have been changed. | |
=cut | |
###################################################################### | |
sub commit | |
{ | |
my( $self, $force ) = @_; | |
$self->update_triggers(); | |
if( !defined $self->{changed} || scalar( keys %{$self->{changed}} ) == 0 ) | |
{ | |
# don't do anything if there isn't anything to do | |
return( 1 ) unless $force; | |
} | |
if( $self->{non_volatile_change} ) | |
{ | |
$self->set_value( "rev_number", ($self->get_value( "rev_number" )||0) + 1 ); | |
} | |
if (exists $self->{changed}->{password}) | |
{ | |
$self->close_non_current_login_tickets; | |
} | |
my $success = $self->SUPER::commit( $force ); | |
return( $success ); | |
} | |
###################################################################### | |
=pod | |
=item $user->close_non_current_login_tickets; | |
Close all tickets for the current user except the one | |
they're currently logged in on | |
=cut | |
###################################################################### | |
sub close_non_current_login_tickets | |
{ | |
my ($self) = @_; | |
my $repo = $self->repository; | |
my $current_ticket = $repo->current_loginticket; | |
my $ticket_ds = $repo->dataset('loginticket'); | |
my $user_tickets = $ticket_ds->search( | |
filters => [ {meta_fields => ['userid'], value => $self->id} ] | |
); | |
$user_tickets->map( | |
sub | |
{ | |
my ($repo, $ds, $ticket, $current_ticket) = @_; | |
if ($ticket->value('code') ne $current_ticket->value('code')) | |
{ | |
$ticket->remove; | |
} | |
}, | |
$current_ticket | |
); | |
} | |
###################################################################### | |
=pod | |
=item $success = $user->remove | |
Remove this user from the database. Also, remove their saved searches, | |
but do not remove their eprints. | |
=cut | |
###################################################################### | |
sub remove | |
{ | |
my( $self ) = @_; | |
my $success = 1; | |
foreach my $saved_search ( $self->get_saved_searches ) | |
{ | |
$saved_search->remove; | |
} | |
# remove user record | |
my $user_ds = $self->{session}->get_repository->get_dataset( "user" ); | |
$success = $success && $self->{session}->get_database->remove( | |
$user_ds, | |
$self->get_value( "userid" ) ); | |
return( $success ); | |
} | |
=item $bool = $user->is_staff() | |
Returns true if the user's type is B<editor> or B<admin>. | |
=cut | |
sub is_staff | |
{ | |
my( $self ) = @_; | |
return $self->has_role( 'editor' ) || $self->has_role( 'admin' ); | |
} | |
=item $lang = $user->langauge() | |
Get the preferred language of the user. | |
=cut | |
sub language | |
{ | |
my( $self ) = @_; | |
my $langid = $self->value( "lang" ); | |
my $lang = $self->{session}->get_repository->get_language( $langid ); | |
return $lang; | |
} | |
=item $list = $user->owned_eprints_list( %opts ) | |
Returns a L<EPrints::List> of all the L<EPrints::DataObj::EPrint>s owned by this user. | |
%opts is passed to a L<EPrints::Search> which is used to filter the results. | |
=cut | |
sub owned_eprints_list | |
{ | |
my( $self, %opts ) = @_; | |
$opts{dataset} = $self->{session}->dataset( "eprint" ) if !defined $opts{dataset}; | |
my $searchexp = $opts{dataset}->prepare_search( %opts ); | |
# BACKWARDS COMPATIBILITY | |
# This method is predicated on doing an in-memory intersect of everything | |
# that the user "owns" and every eprint in the matching datasets | |
# If the user chose to show his 'live' eprints that could get really, | |
# really big | |
my $fn = $self->{session}->config( "get_users_owned_eprints" ); | |
if( !defined $fn ) | |
{ | |
$searchexp->add_field( $opts{dataset}->field( "userid" ), $self->id ); | |
return $searchexp->perform_search; | |
} | |
my $list = &$fn( $self->{session}, $self, $opts{dataset} ); | |
if (!$searchexp->is_blank()) { $list = $list->intersect( $searchexp->perform_search ); } | |
return $list; | |
} | |
=item $list = $user->editable_eprints_list( %opts ) | |
Returns a L<EPrints::List> of L<EPrints::DataObj::EPrint>s that match this user's editorial search expressions. If the user has no editorial scope a list of all eprints that match the given %opts is returned. | |
%opts is passed to a L<EPrints::Search> which is used to filter the results. | |
$list = $user->editable_eprints_list( | |
dataset => $repo->dataset( "buffer" ), | |
); | |
=cut | |
sub editable_eprints_list | |
{ | |
my( $self, %opts ) = @_; | |
$opts{dataset} = $self->{session}->dataset( "eprint" ) if !defined $opts{dataset}; | |
if( !$self->is_set( 'editperms' ) ) | |
{ | |
return $opts{dataset}->search( | |
custom_order => "-datestamp", | |
%opts ); | |
} | |
my @conds; | |
my $editperms = $self->{dataset}->get_field( "editperms" ); | |
foreach my $sv ( @{$self->get_value( 'editperms' )} ) | |
{ | |
push @conds, $editperms->make_searchexp( | |
$self->{session}, | |
$sv )->get_conditions; | |
} | |
my $cond = EPrints::Search::Condition->new( "OR", @conds ); | |
# Condition::process() doesn't check dataset filters, so manually | |
# add them here | |
$opts{filters} = [] if !defined $opts{filters}; | |
push @{$opts{filters}}, $opts{dataset}->get_filters; | |
if( EPrints::Utils::is_set( $opts{filters} ) ) | |
{ | |
my $searchexp = $opts{dataset}->prepare_search( %opts ); | |
$cond = EPrints::Search::Condition->new( "AND", | |
$searchexp->get_conditions, | |
$cond ); | |
} | |
my $ids = $cond->process( session => $self->{session}, dataset => $opts{dataset} ); | |
return EPrints::List->new( | |
session => $self->{session}, | |
dataset => $opts{dataset}, | |
ids => $ids, | |
order => "-datestamp" ); | |
} | |
###################################################################### | |
=pod | |
=item $boolean = $user->has_owner( $possible_owner ) | |
True if the users are the same record. | |
=cut | |
###################################################################### | |
sub has_owner | |
{ | |
my( $self, $possible_owner ) = @_; | |
if( $possible_owner->get_value( "userid" ) == $self->get_value( "userid" ) ) | |
{ | |
return 1; | |
} | |
return 0; | |
} | |
###################################################################### | |
=pod | |
=item $ok = $user->mail( $subjectid, $message, [$replyto], [$email], [$cc_list] ) | |
Send an email to this user. | |
$subjectid is the ID of a phrase to use as the subject of this email. | |
$message is an XML DOM object describing the message in simple XHTML. | |
$replyto is the reply to address for this email, if different to the | |
repository default. | |
$email is the email address to send this email to if different from | |
this users configured email address. | |
$cc_list is an optional cc_list (array ref) | |
Return true if the email was sent OK. | |
=cut | |
###################################################################### | |
sub mail | |
{ | |
my( $self, $subjectid, $message, $replyto, $email, $cc_list ) = @_; #EPrints Services/sf2 2010-11-18 added optional cc_list (array ref) for GREENWICH-17 | |
# User , string, DOM, User/undef Other Email | |
# Mail the admin in the default language | |
my $langid = $self->get_value( "lang" ); | |
my $lang = $self->{session}->get_repository->get_language( $langid ); | |
my $remail; | |
my $rname; | |
if( defined $replyto ) | |
{ | |
$remail = $replyto->get_value( "email" ); | |
$rname = EPrints::Utils::tree_to_utf8( $replyto->render_description() ); | |
} | |
if( !defined $email ) | |
{ | |
$email = $self->get_value( "email" ); | |
} | |
return EPrints::Email::send_mail( | |
session => $self->{session}, | |
langid => $langid, | |
to_name => EPrints::Utils::tree_to_utf8( $self->render_description ), | |
to_email => $email, | |
subject => EPrints::Utils::tree_to_utf8( $lang->phrase( $subjectid, {}, $self->{session} ) ), | |
message => $message, | |
sig => $lang->phrase( "mail_sig", {}, $self->{session} ), | |
replyto_name => $rname, | |
replyto_email => $remail, | |
cc_list => $cc_list, | |
); | |
} | |
###################################################################### | |
=pod | |
=item ( $page, $title ) = $user->render | |
Render this user into HTML using the "user_render" method in | |
ArchiveRenderConfig.pm. Returns both the rendered information and | |
the title as XHTML DOM. | |
=cut | |
###################################################################### | |
sub render | |
{ | |
my( $self ) = @_; | |
my( $dom, $title ) = $self->{session}->get_repository->call( "user_render", $self, $self->{session} ); | |
if( !defined $title ) | |
{ | |
$title = $self->render_description; | |
} | |
return( $dom, $title ); | |
} | |
# This should include all the info, not just that presented to the public. | |
###################################################################### | |
=pod | |
=item ( $page, $title ) = $user->render_full | |
The same as $user->render, but renders all fields, not just those | |
intended for public viewing. This is the admin view of the user. | |
=cut | |
###################################################################### | |
sub render_full | |
{ | |
my( $self ) = @_; | |
my( $table, $title ) = $self->SUPER::render_full; | |
my $ds = $self->{session}->get_repository->get_dataset( "saved_search" ); | |
foreach my $saved_search ( $self->get_saved_searches ) | |
{ | |
my $rowright = $self->{session}->make_doc_fragment; | |
foreach( "frequency","spec","mailempty" ) | |
{ | |
my $strong; | |
$strong = $self->{session}->make_element( "strong" ); | |
$strong->appendChild( $ds->get_field( $_ )->render_name( $self->{session} ) ); | |
$strong->appendChild( $self->{session}->make_text( ": " ) ); | |
$rowright->appendChild( $strong ); | |
$rowright->appendChild( $saved_search->render_value( $_ ) ); | |
$rowright->appendChild( $self->{session}->make_element( "br" ) ); | |
} | |
$table->appendChild( $self->{session}->render_row( | |
$self->{session}->html_phrase( | |
"page:saved_search" ), | |
$rowright ) ); | |
} | |
return( $table, $title ); | |
} | |
###################################################################### | |
=pod | |
=item $url = $user->get_url | |
Return the URL which will display information about this user. | |
If $staff is true then return the URL for an administrator to view | |
and modify this record. | |
=cut | |
###################################################################### | |
sub get_control_url | |
{ | |
my( $self ) = @_; | |
return $self->{session}->get_repository->get_conf( "http_cgiurl" )."/users/home?screen=User::View&userid=".$self->get_value( "userid" ); | |
} | |
###################################################################### | |
=pod | |
=item $type = $user->get_type | |
Return the type of this user. Equivalent of | |
$user->get_value( "usertype" ); | |
=cut | |
###################################################################### | |
sub get_type | |
{ | |
my( $self ) = @_; | |
return $self->get_value( "usertype" ); | |
} | |
###################################################################### | |
=pod | |
=item @saved_searches = $eprint->get_saved_searches | |
Return an array of all EPrint::DataObj::SavedSearch objects associated with this | |
user. | |
=cut | |
###################################################################### | |
sub get_saved_searches | |
{ | |
my( $self ) = @_; | |
my $dataset = $self->{session}->dataset( "saved_search" ); | |
my $results = $dataset->search( | |
filters => [ | |
{ | |
meta_fields => [qw( userid )], | |
value => $self->value( "userid" ), | |
} | |
], | |
custom_order => $dataset->key_field->name ); | |
return $results->slice; | |
} | |
=item $value = $user->preference( $key ) | |
Retrieve the preference $key. | |
=cut | |
sub preference | |
{ | |
my( $self, $key ) = @_; | |
my $prefs = $self->value( "preference" ); | |
return undef if !defined $prefs; | |
return $prefs->{$key}; | |
} | |
=item $user->set_preference( $key, $value ) | |
Set a preference $key for the user to $value. | |
=cut | |
sub set_preference | |
{ | |
my( $self, $key, $value ) = @_; | |
my $prefs = $self->value( "preference" ); | |
$prefs = defined $prefs ? { %$prefs } : {}; | |
if( EPrints::Utils::is_set( $value ) ) | |
{ | |
$prefs->{$key} = $value; | |
} | |
else | |
{ | |
delete $prefs->{$key}; | |
} | |
$self->set_value( "preference", $prefs ); | |
} | |
###################################################################### | |
=pod | |
=item $user->send_out_editor_alert | |
Called on users who are editors, when it's time to send their update | |
on what items are in the editorial review buffer. | |
Sends the email if needed. | |
=cut | |
###################################################################### | |
sub send_out_editor_alert | |
{ | |
my( $self ) = @_; | |
my $freq = $self->get_value( "frequency" ); | |
if( $freq eq "never" ) | |
{ | |
$self->{session}->get_repository->log( | |
"Attempt to send out an editor alert for a user\n". | |
"which has frequency 'never'\n" ); | |
return; | |
} | |
unless( $self->has_role( "editor" ) ) | |
{ | |
$self->{session}->get_repository->log( | |
"Attempt to send out an editor alert for a user\n". | |
"which does not have editor role (". | |
$self->get_value("username").")\n" ); | |
return; | |
} | |
my $origlangid = $self->{session}->get_langid; | |
$self->{session}->change_lang( $self->get_value( "lang" ) ); | |
# we're only interested in items under review (buffer) | |
my $list = $self->editable_eprints_list( | |
dataset => $self->{session}->dataset( "buffer" ), | |
); | |
if( $list->count > 0 || $self->get_value( "mailempty" ) eq 'TRUE' ) | |
{ | |
my $url = URI->new($self->{session}->get_repository->get_conf( "http_cgiurl" )."/users/home"); | |
$url->query_form( | |
screen => "User::Edit", | |
userid => $self->get_id | |
); | |
my $freqphrase = $self->{session}->html_phrase( | |
"lib/saved_search:".$freq ); # nb. reusing the SavedSearch.pm phrase | |
my $searchdesc = $self->render_value( "editperms" ); | |
my $matches = $self->{session}->make_doc_fragment; | |
$list->map( sub { | |
my( $session, $dataset, $eprint ) = @_; | |
my $p = $self->{session}->make_element( "p" ); | |
$p->appendChild( $eprint->render_citation_link_staff ); | |
$matches->appendChild( $p ); | |
} ); | |
my $mail = $self->{session}->html_phrase( | |
"lib/user:editor_update_mail", | |
howoften => $freqphrase, | |
n => $self->{session}->make_text( $list->count ), | |
search => $searchdesc, | |
matches => $matches, | |
url => $self->{session}->render_link( $url ) ); | |
$self->mail( | |
"lib/user:editor_update_subject", | |
$mail ); | |
EPrints::XML::dispose( $mail ); | |
} | |
$self->{session}->change_lang( $origlangid ); | |
} | |
###################################################################### | |
=pod | |
=item EPrints::DataObj::User::process_editor_alerts( $session, $frequency ); | |
Static method. | |
Called to send out all editor alerts of a given frequency (daily, | |
weekly, monthly) for the current repository. | |
=cut | |
###################################################################### | |
sub process_editor_alerts | |
{ | |
my( $session, $frequency ) = @_; | |
if( $frequency ne "daily" && | |
$frequency ne "weekly" && | |
$frequency ne "monthly" ) | |
{ | |
$session->get_repository->log( "EPrints::DataObj::User::process_editor_alerts called with unknown frequency: ".$frequency ); | |
return; | |
} | |
my $subs_ds = $session->dataset( "user" ); | |
my $searchexp = EPrints::Search->new( | |
session => $session, | |
dataset => $subs_ds ); | |
$searchexp->add_field( | |
$subs_ds->get_field( "frequency" ), | |
$frequency ); | |
my $fn = sub { | |
my( $session, $dataset, $item, $info ) = @_; | |
return unless( $item->has_role( "editor" ) ); | |
$item->send_out_editor_alert; | |
if( $session->get_noise >= 2 ) | |
{ | |
print "Sending out editor alert for ".$item->get_value( "username" )."\n"; | |
} | |
}; | |
my $list = $searchexp->perform_search; | |
$list->map( $fn, {} ); | |
# currently no timestamp for editor alerts | |
} | |
# Privs and Role related methods | |
# this maps roles onto privs | |
my $PRIVMAP = | |
{ | |
general => | |
[ | |
"user/view:owner", | |
"user/details:owner", | |
"user/history:owner", | |
], | |
"edit-own-record" => | |
[ | |
"user/edit:owner", | |
], | |
"set-password" => | |
[ | |
"set-password", | |
], | |
"change-email" => | |
[ | |
# not done | |
], | |
"change-user" => | |
[ | |
# not done | |
], | |
"staff-view" => | |
[ | |
# still needs search tools | |
"eprint/inbox/view", | |
"eprint/inbox/summary", | |
"eprint/inbox/export", | |
"eprint/inbox/details", | |
"eprint/inbox/history", | |
"eprint/buffer/view", | |
"eprint/buffer/summary", | |
"eprint/buffer/export", | |
"eprint/buffer/details", | |
"eprint/buffer/history", | |
"eprint/archive/view", | |
"eprint/archive/export", | |
"eprint/archive/details", | |
"eprint/archive/history", | |
"eprint/deletion/view", | |
"eprint/deletion/summary", | |
"eprint/deletion/export", | |
"eprint/deletion/details", | |
"eprint/deletion/history", | |
"eprint/search/staff", | |
], | |
"view-status" => | |
[ | |
"status" | |
], | |
"admin" => | |
[ | |
"indexer/stop", | |
"indexer/start", | |
"indexer/force_start", | |
"create_user", | |
"subject/edit", | |
"staff/user_search", | |
"staff/history_search", | |
"staff/issue_search", | |
"config/view", | |
"config/view/xml", | |
"config/view/workflow", | |
"config/view/citation", | |
"config/view/phrase", | |
"config/view/namedset", | |
"config/view/template", | |
"config/view/static", | |
"config/view/autocomplete", | |
"config/view/apache", | |
"config/view/perl", | |
"config/test_email", | |
"config/imports", | |
"config/add_field", | |
"config/remove_field", | |
"config/regen_abstracts", | |
"config/regen_views", | |
"config/edit/perl", | |
"storage/manager", | |
"repository/epm", #EPrints Package Manager | |
"event_queue/destroy", | |
"event_queue/details", | |
"event_queue/edit", | |
"event_queue/export", | |
"event_queue/view", | |
"eprint/destroy", | |
"eprint/details", | |
"eprint/edit", | |
"eprint/export", | |
"eprint/upsert", | |
"eprint/view", | |
"eprint/archive/remove", | |
"eprint/archive/edit", # BatchEdit | |
"file/destroy", | |
"file/export", | |
"file/view", | |
"import/view", | |
"import/edit", | |
"saved_search/destroy", | |
"saved_search/details", | |
"saved_search/edit", | |
"saved_search/export", | |
"saved_search/view", | |
"user/remove", | |
"user/edit", | |
"user/view", | |
"user/details", | |
"user/destroy", | |
"user/history", | |
"user/staff/edit", | |
"repository/epm-submit", #EPrints Package Manager - Bazaar Package Submission | |
], | |
"toolbox" => | |
[ | |
"toolbox", | |
], | |
"edit-config" => | |
[ | |
"config/edit", | |
"config/edit/xml", | |
"config/edit/workflow", | |
"config/edit/citation", | |
"config/edit/phrase", | |
"config/edit/namedset", | |
"config/edit/template", | |
"config/edit/static", | |
"config/edit/autocomplete", | |
# not editing perl files or apache files! | |
"config/reload", | |
], | |
"saved-searches" => | |
[ | |
"saved_search", | |
"create_saved_search", | |
"saved_search/view:owner", | |
"saved_search/edit:owner", | |
"saved_search/destroy:owner", | |
], | |
deposit => | |
[ | |
"items", | |
"create_eprint", | |
"user/history:owner", | |
"eprint/inbox/view:owner", | |
"eprint/inbox/export:owner", | |
"eprint/inbox/summary:owner", | |
"eprint/inbox/destroy:owner", | |
"eprint/inbox/deposit:owner", | |
"eprint/inbox/edit:owner", | |
"eprint/inbox/remove:owner", | |
"eprint/inbox/details:owner", | |
"eprint/inbox/history:owner", | |
"eprint/inbox/messages:owner", | |
"eprint/inbox/issues:owner", | |
"eprint/inbox/deposit:owner", | |
"eprint/inbox/use_as_template:owner", | |
"eprint/inbox/derive_version:owner", | |
"eprint/buffer/view:owner", | |
"eprint/buffer/export:owner", | |
"eprint/buffer/summary:owner", | |
"eprint/buffer/move_inbox:owner", | |
"eprint/buffer/details:owner", | |
"eprint/buffer/history:owner", | |
"eprint/buffer/messages:owner", | |
"eprint/buffer/request_removal:owner", | |
"eprint/buffer/use_as_template:owner", | |
"eprint/buffer/derive_version:owner", | |
"eprint/archive/view:owner", | |
"eprint/archive/export:owner", | |
"eprint/archive/summary:owner", | |
"eprint/archive/details:owner", | |
"eprint/archive/history:owner", | |
"eprint/archive/messages:owner", | |
"eprint/archive/request_removal:owner", | |
"eprint/archive/use_as_template:owner", | |
"eprint/archive/derive_version:owner", | |
"eprint/deletion/view:owner", | |
"eprint/deletion/export:owner", | |
"eprint/deletion/summary:owner", | |
"eprint/deletion/details:owner", | |
"eprint/deletion/history:owner", | |
"eprint/deletion/messages:owner", | |
"eprint/deletion/use_as_template:owner", | |
"eprint/deletion/derive_version:owner", | |
], | |
editor => | |
[ | |
"datasets", | |
"editorial_review", | |
"eprint/inbox/view:editor", | |
"eprint/inbox/export:editor", | |
"eprint/inbox/summary:editor", | |
"eprint/inbox/export:editor", | |
"eprint/inbox/details:editor", | |
"eprint/inbox/history:editor", | |
"eprint/inbox/messages:editor", | |
"eprint/inbox/remove_with_email:editor", | |
"eprint/inbox/move_archive:editor", | |
"eprint/inbox/move_buffer:editor", | |
"eprint/inbox/use_as_template:editor", | |
"eprint/inbox/derive_version:editor", | |
"eprint/inbox/edit:editor", | |
"eprint/inbox/takelock:editor", | |
"eprint/buffer/view:editor", | |
"eprint/buffer/export:editor", | |
"eprint/buffer/summary:editor", | |
"eprint/buffer/export:editor", | |
"eprint/buffer/details:editor", | |
"eprint/buffer/history:editor", | |
"eprint/buffer/messages:editor", | |
"eprint/buffer/issues:editor", | |
"eprint/buffer/remove_with_email:editor", | |
"eprint/buffer/reject_with_email:editor", | |
"eprint/buffer/move_inbox:editor", | |
"eprint/buffer/move_archive:editor", | |
"eprint/buffer/use_as_template:editor", | |
"eprint/buffer/derive_version:editor", | |
"eprint/buffer/edit:editor", | |
"eprint/buffer/takelock:editor", | |
"eprint/archive/view:editor", | |
"eprint/archive/export:editor", | |
"eprint/archive/details:editor", | |
"eprint/archive/history:editor", | |
"eprint/archive/messages:editor", | |
"eprint/archive/issues:editor", | |
"eprint/archive/move_buffer:editor", | |
"eprint/archive/move_deletion:editor", | |
"eprint/archive/use_as_template:editor", | |
"eprint/archive/derive_version:editor", | |
"eprint/archive/edit:editor", | |
"eprint/archive/takelock:editor", | |
"eprint/deletion/view:editor", | |
"eprint/deletion/export:editor", | |
"eprint/deletion/summary:editor", | |
"eprint/deletion/export:editor", | |
"eprint/deletion/details:editor", | |
"eprint/deletion/history:editor", | |
"eprint/deletion/messages:editor", | |
"eprint/deletion/move_archive:editor", | |
"eprint/deletion/use_as_template:editor", | |
"eprint/deletion/derive_version:editor", | |
"eprint/deletion/takelock:editor", | |
], | |
rest => [ | |
"eprint/archive/rest/get:editor", | |
"eprint/archive/rest/put:editor", | |
"eprint/buffer/rest/get:editor", | |
"eprint/buffer/rest/put:editor", | |
"eprint/inbox/rest/get:editor", | |
"eprint/inbox/rest/put:editor", | |
"eprint/deletion/rest/get:editor", | |
"eprint/deletion/rest/put:editor", | |
"eprint/inbox/rest/get:owner", | |
"eprint/inbox/rest/put:owner", | |
"eprint/buffer/rest/get:owner", | |
"eprint/archive/rest/get:owner", | |
"eprint/deletion/rest/get:owner", | |
"user/rest/get:owner", | |
"subject/rest/get", | |
], | |
}; | |
###################################################################### | |
=pod | |
=item $result = $user->allow( $priv ) | |
Returns true if $user can perform this action/view this screen. | |
To test whether a privilege is possible on an object use L<EPrints::DataObj/permit>. | |
=cut | |
###################################################################### | |
sub allow | |
{ | |
my( $self, $priv, $item ) = @_; | |
my $r = 0; | |
$r |= 1 if $self->{session}->allow_anybody( $priv ); | |
$r |= 2 if $self->has_privilege( $priv ); | |
$r |= $item->permit( $priv, $self ) if defined $item; | |
return $r; | |
} | |
=item $boolean = $user->has_privilege( $priv ) | |
Returns true if $priv is in the user's privileges table. | |
=cut | |
sub has_privilege | |
{ | |
my( $self, $priv ) = @_; | |
return $self->get_privs->{$priv}; | |
} | |
###################################################################### | |
# | |
# $privs = $user->get_privs; | |
# | |
# Return the privs a user has. Currently just based on roles, but | |
# could do more later. Returns a reference to a hash. Caches the | |
# result to save time. | |
# | |
###################################################################### | |
sub get_privs | |
{ | |
my( $self ) = @_; | |
return $self->{".privs"} if( defined $self->{".privs"} ) ; | |
my $rep = $self->{session}->get_repository; | |
my $role_config = $rep->get_conf( "user_roles", $self->get_value( "usertype" ) ); | |
my $extra_roles = $self->get_value( "roles" ) || []; | |
my %privmap = %{$PRIVMAP}; | |
# extra hats defined in this repository | |
my %override_roles = %{$rep->get_conf( "roles" )||{}}; | |
foreach my $role_id ( keys %override_roles ) | |
{ | |
$privmap{$role_id} = $override_roles{$role_id}; | |
} | |
$self->{".privs"} = {}; | |
foreach my $role ( @{$role_config}, @{$extra_roles} ) | |
{ | |
if( $role =~ m/^\+(.*)$/ ) | |
{ | |
$self->{".privs"}->{$1} = 1; | |
next; | |
} | |
if( $role =~ m/^-(.*)$/ ) | |
{ | |
delete $self->{".privs"}->{$1}; | |
next; | |
} | |
foreach my $priv ( @{$privmap{$role}} ) | |
{ | |
if( $priv =~ m/^\+(.*)$/ ) | |
{ | |
$self->{".privs"}->{$1} = 1; | |
next; | |
} | |
if( $priv =~ m/^-(.*)$/ ) | |
{ | |
delete $self->{".privs"}->{$1}; | |
next; | |
} | |
$self->{".privs"}->{$priv} = 1; | |
} | |
} | |
return $self->{".privs"}; | |
} | |
###################################################################### | |
# | |
# @roles = $user->get_roles; | |
# | |
# Return the roles the user has. Each role represents a whole bunch | |
# of privs. | |
# | |
###################################################################### | |
sub get_roles | |
{ | |
my( $self ) = @_; | |
my $rep = $self->{session}->get_repository; | |
my $role_config = $rep->get_conf( "user_roles", $self->get_value( "usertype" ) ); | |
my $extra_roles = $self->get_value( "roles" ) || []; | |
my @roles = (); | |
foreach my $role ( @{$role_config}, @{$extra_roles} ) | |
{ | |
next if( $role =~ m/^[+-]/ ); | |
push @roles, $role; | |
} | |
return @roles; | |
} | |
sub has_role | |
{ | |
my( $self, $roleid ) = @_; | |
foreach my $hasid ( $self->get_roles ) | |
{ | |
return 1 if $hasid eq $roleid; | |
} | |
return 0; | |
} | |
1; | |
###################################################################### | |
=pod | |
=back | |
=cut | |
=head1 COPYRIGHT | |
=for COPYRIGHT BEGIN | |
Copyright 2000-2011 University of Southampton. | |
=for COPYRIGHT END | |
=for LICENSE BEGIN | |
This file is part of EPrints L<http://www.eprints.org/>. | |
EPrints is free software: you can redistribute it and/or modify it | |
under the terms of the GNU Lesser General Public License as published | |
by the Free Software Foundation, either version 3 of the License, or | |
(at your option) any later version. | |
EPrints is distributed in the hope that it will be useful, but WITHOUT | |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |
License for more details. | |
You should have received a copy of the GNU Lesser General Public | |
License along with EPrints. If not, see L<http://www.gnu.org/licenses/>. | |
=for LICENSE END | |