Sunday, November 6, 2016

Eprints Install 3, Setting domain

UNIMAS Official Wiki » Dashboard » HOW-TO, Tutorial & User Manual » HOW-TO : Install Eprints v3.3.12 on Ubuntu 14.04 With LDAP Authentication

HOW-TO : Install Eprints v3.3.12  on Ubuntu 14.04 With LDAP Authentication

Last modified by Khairilzamrie bin Rosle on 2014/11/14 10:06
Comments (0) · Attachments (0) · History · Information
This HOW-TO is produced to assist people interested to installEprints v3.3.12 on Ubuntu 14.04 LTS with integration of LDAP Authentication. It also meant to make the installation process of Eprints v 3.3.12 on Ubuntu 14.04 (which has known issues) to be much more easier and straightforward. People interested to just simply install Eprints without LDAP Authentication just need to complete Step 1 of 4.

Pre-requisite

  • Ubuntu 14.04 64bit
  • Apache 2.4 (bundled with Ubuntu 14.04)
  • Perl/v5.18.2 (bundled with Ubuntu 14.04)
  • Eprints v 3.3.12
  • Domain name for eprints server - In this tutorial we will use myeprints.example.my
  • IP Address for eprints server - In this tutorial we will use 10.0.0.11
  • Ldap v3 server - In this tutorial we will use fictional LDAP server ldap.example.org
  • Port 443 needs to be opened on the EPrints server to allow web access over https (EPrints will switch from HTTP on port 80 to HTTPS on port 443 from the time you log in to the time you log back out again)

Step 1 of 4 : Install Eprints via APT

First, log into your EPrints server via ssh from your PC. If you are using Windows PC, you can use Putty. If you are using a Mac or a Linux PC then open a terminal and issue this command (replace eprintsuser with your own user which has sudo privillege and also replace 10.0.0.11 with your eprints server real IP Address):
ssh eprintsuser@10.0.0.11
Once you logged in, add Eprints repository to your Ubuntu /etc/apt/sources.list file :
sudo nano /etc/apt/sources.list
and add the following at the bottom of the file :
deb http://deb.eprints.org/3.3/ stable/
deb-src http://deb.eprints.org/3.3/ source/
Then, install Eprints via apt-get
sudo apt-get update && sudo apt-get install eprints
Now, before we proceed, we have to sort out some issue first. Eprints v3.3.12 and below have a known issues running on Apache 2.4 (and Perl/v5.16+) which bundled with Ubuntu 14.04 (and 13.10). To solve these issues, we need to patch some of Eprints files. We are going to patch 4 files :
  • /usr/share/eprints3/perl_lib/EPrints/Repository.pm
  • /usr/share/eprints3/lib/defaultcfg/cfg.d/security.pl
  • usr/share/eprints3/perl_lib/EPrints/Apache/LogHandler.pm
  • /usr/share/eprints3/perl_lib/EPrints/DataObj/LoginTicket.pm
sudo su eprints
wget -N https://raw.githubusercontent.com/eprints/eprints/88567f9cf9deb146c24a8088e452d4561c90f05e/perl_lib/EPrints/Repository.pm -O /usr/share/eprints3/perl_lib/EPrints/Repository.pm
wget -N https://raw.githubusercontent.com/eprints/eprints/26e97fc3dbaa28e89e7ffbe0e6f8eedbfc7804cd/lib/defaultcfg/cfg.d/security.pl -O /usr/share/eprints3//lib/defaultcfg/cfg.d/security.pl
wget -N https://raw.githubusercontent.com/eprints/eprints/67986a00f042077a8388278cbcfdd51e0d737647/perl_lib/EPrints/Apache/LogHandler.pm -O /usr/share/eprints3/perl_lib/EPrints/Apache/LogHandler.pm
wget -N https://raw.githubusercontent.com/eprints/eprints/34f85e9b994d47cb95e225874749c274020688b5/perl_lib/EPrints/DataObj/LoginTicket.pm -O /usr/share/eprints3/perl_lib/EPrints/DataObj/LoginTicket.pm
sed -i 's/$r->connection->remote_ip/$r->connection->client_ip()/g' /usr/share/eprints3/perl_lib/EPrints/DataObj/LoginTicket.pm
Cool! We are done with patching. Now, lets create a repository for Eprints. Please follow the on-screen instructions to set up an eprints repository. You will be asked to enter Archive ID during the installation. Please remember the Archive ID you entered as it will be used for the next steps.
/usr/share/eprints3/bin/epadmin create
Now we need to edit an apache config file which generated during previous step.  Replace <YOURARCHIVEID> below with the Archive ID you just created in previous step :
nano /usr/share/eprints3/cfg/apache/<YOURARCHIVEID>.conf
and replace all the content with these scripts. Please don't forget to replace <YOURARCHIVEID> in the file below with your Archive ID :
#
# apache.conf include file for ir
#
# Any changes made here will be lost if you run generate_apacheconf
# with the replace option
#
# The main virtual host for this repository
<VirtualHost *:80>
  ServerName myeprints.example.my
  ServerAdmin admin@example.com
  <Location "">
    PerlSetVar EPrints_ArchiveID <YOURARCHIVEID>
    Options +ExecCGI
   # Order allow,deny
   # Allow from all
    Require all granted
  </Location>
  ErrorLog ${APACHE_LOG_DIR}/eprintserror.log
  CustomLog ${APACHE_LOG_DIR}/eprintsaccess.log combined
  # Note that PerlTransHandler can't go inside
  # a "Location" block as it occurs before the
  # Location is known.
  PerlTransHandler +EPrints::Apache::Rewrite
</VirtualHost>
Once you're done :
exit
sudo mv /etc/apache2/sites-available/eprints /etc/apache2/sites-available/eprints.conf 
sudo a2dismod mpm_event
sudo a2enmod mpm_prefork
sudo a2ensite eprints
sudo apache2ctl stop
sudo apache2ctl start
You should now have a working installation of eprints in /usr/share/eprints3/

Step 2 of 4 : Configure HTTPS for Eprints

This is still the same process as the standard HTTPS setup. First, edit/usr/share/eprints3/archives/<YOURARCHIVEID>/cfg/cfg.d/10_core.pl file (where <YOURARCHIVEID> is your Archive IDcreated above) :
sudo su eprints
nano /usr/share/eprints3/archives/<YOURARCHIVEID>/cfg/cfg.d/10_core.pl
Replace the file content with following lines :
$c->{host} = 'myeprints.example.my';
$c->{port} = 80;
$c->{aliases} = [];
$c->{securehost} = 'myeprints.example.my';
$c->{secureport} = 443;
$c->{securepath} = '/secure';
$c->{http_root} = '';
$c->{https_root} = '';
$c->{http_cgiroot} = '/cgi';
$c->{https_cgiroot} = '/cgi';
Next you need to run the generate_apacheconf command;
/usr/share/eprints3/bin/generate_apacheconf
The command will generate an apache config file at /usr/share/eprints3/cfg/apache_ssl/<YOURARCHIVEID>.conf . We now need to edit it .  Replace <YOURARCHIVEID> with the Archive ID created above :
nano /usr/share/eprints3/cfg/apache_ssl/<YOURARCHIVEID>.conf
and replace the whole content with these. Please don't forget to replace <YOURARCHIVEID> in the file below with your Archive ID :
#
# secure.conf include file for ir
#
# Any changes made here will be lost if you run generate_apacheconf
# with the replace option
#
  <Location "">
    PerlSetVar EPrints_ArchiveID <YOURARCHIVEID>
    PerlSetVar EPrints_Secure yes
    Options +ExecCGI
    #Order allow,deny 
    #Allow from all
    Require all granted
  </Location>
Once you are done, issue this command :
exit
EPrints should now be ready for SSL. Now we need to configure Apache for https.
The first thing you need to do is install the SSL certificate generator if you don't already have it;
sudo apt-get install ssl-cert
Next make a directory for all your SSL certificates in your apache2 directory;
sudo mkdir /etc/apache2/ssl
Now we can generate the certificate;
sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem
Now enable the module for apache2 which should already be installed as part of the apache2 package;
sudo a2enmod ssl
We now need to create a new virtualhost since EPrints makes some assumptions about the existence of the SSL virtualhost, but it does not exist on Debian/Ubuntu. Create a new file eprints-ssl.conf in /etc/apache2/sites-available/ :
sudo nano /etc/apache2/sites-available/eprints-ssl.conf
and in this file you want to put the following :
<VirtualHost *:443>
  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/apache.pem
  Include /usr/share/eprints3/cfg/apache_ssl.conf
</VirtualHost>
Once you have done this enable the site;
sudo a2ensite eprints-ssl
Then restart apache2 :
sudo service apache2 restart 
Now your Eprints ready to be accessed via https

Step 3 of 4 : Enable Eprints Authentication with LDAP

To enable LDAP authentication, first install perl-ldap library :
sudo apt-get install libnet-ldap-perl
It is recommended that certain user rights are removed when using LDAP for login. The user should not be allowed to change their password or their email address. It is also suggested that the user not be allowed to edit their profile, however there are certain fields that we would like the user to edit. To set the rights edit the file (where <YOURARCHIVEID> is your Archive ID created above):
sudo su eprints
nano /usr/share/eprints3/archives/<YOURARCHIVEID>/cfg/cfg.d/user_roles.pl

#
# User Roles
#
#  Here you can configure which different types of user are 
#  parts of the system they are allowed to use.
#

$c->{user_roles}->{user} = [qw{
        general
        edit-own-record
        saved-searches
#       set-password
        deposit
#       change-email
}];
$c->{user_roles}->{editor} = [qw{
        general
        edit-own-record
        saved-searches
#       set-password
        deposit
#       change-email
        editor
        view-status
        staff-view
}];
$c->{user_roles}->{admin} = [qw{
        general
        edit-own-record
        saved-searches
        set-password
        deposit
        change-email
        editor
        view-status
        staff-view
        admin
        edit-config
}];
# Note  nobody has the very powerful "toolbox" or "rest" roles, by default!
# Use this to set public privilages. 
$c->{public_roles} = [qw{
        +eprint/archive/rest/get
        +subject/rest/get
}];
#$c->{user_roles}->{minuser} = [qw{
#       general
#       edit-own-record
#       saved-searches
#       set-password
#       lock-username-to-email
#}];
# If you want to add additional roles to the system, you can do it here.
# These can be useful to create "hats" which can be given to a user via
# the roles field. You can also override the default roles.
#
#$c->{roles}->{"approve-hat"} = [
#       "eprint/buffer/view:editor",
#       "eprint/buffer/summary:editor",
#       "eprint/buffer/details:editor",
#       "eprint/buffer/move_archive:editor",
#];
Now we are going to configure Eprints to use LDAP Authentication with On-Demand Creation of Users. This will :
  • allowing LDAP accounts to login, using the "Advanced LDAP Configuration" example
  • allowing the local eprints admin account to login w/ database authentication
  • creating Eprints accounts for all successfully authenticated LDAP users on the fly
* Make sure to only use this over HTTPS!
Edit /usr/share/eprints3/archives/<YOURARCHIVEID>/cfg/cfg.d/user_login.pl (<YOURARCHIVEID> is your Archive ID created above) :
nano /usr/share/eprints3/archives/<YOURARCHIVEID>/cfg/cfg.d/user_login.pl
and replace the whole content with below script. Make sure you replace values for :
  • $ldap_host  - Change to your LDAP server domain name or IP Address
  • $base - Change to your base DN for user tree
  • $groupbase - Change to your base DN for group tree which you want the user to be member of  (this will act as group filter)
  • $dn -  Change to your Proxy account which must exist in your LDAP tree and has appropriate permissions (ACL settings) to search for users and read their uid,givenname,sn,mail attributes
  • $ldappass - Change to your password for the proxy account

=pod


# Please see http://wiki.eprints.org/w/User_login.pl
$c->{check_user_password} = sub {

        my( $repo, $password, $username ) = @_;

        return $ok ? $username : undef;
};


=cut



$c->{check_user_password} = sub {
   my( $session, $username, $password ) = @_;

   # LDAP authentication for "user", "editor" and "admin" types (roles)

   use Net::LDAP; # IO::Socket::SSL also required
   use Time::Piece ();

   # LDAP tunables
   my $ldap_host = "ldap.example.org";
   my $base      = "dc=example,dc=org";
   my $groupbase = "cn=Groups,dc=example,dc=org";
   my $dn        = "cn=someProxyAccount";
   my $ldappass   = "someProxyAccountPassword";


   my $ldap      = Net::LDAP->new ( $ldap_host, version => 3 );
   unless( $ldap )
   {
        print STDERR Time::Piece::localtime->strftime('[%a %b %d %H:%M:%S %Y]');
        print STDERR " LDAP error: $@\n";
        return 0;
   }

   # Start secure connection (not needed if using LDAPS)
   my $ssl = $ldap->start_tls();
   if( $ssl->code() )
   {
       print STDERR Time::Piece::localtime->strftime('[%a %b %d %H:%M:%S %Y]');
       print STDERR " LDAP SSL error: " . $ssl->error() . "\n";
       return 0;
   }

   # Get password for the search-bind-account
   my $repository = $session->get_repository;
   my $id         = $repository->get_id;
   my $mesg = $ldap->bind( $dn, password=>$ldappass     );
   if( $mesg->code() )
   {
       print STDERR "LDAP Bind error: " . $mesg->error() . "\n";
       return 0;
   }

   # Distinguished name (and attribues needed later on) for this user
   my $result = $ldap->search (
       base    => "$base",
       scope   => "sub",
       filter  => "(&(uid=$username)(objectclass=inetOrgPerson))",
       attrs   =>  ['1.1', 'uid', 'sn', 'mail'],
       sizelimit=>1
   );

   my $entr = $result->pop_entry;
   unless( defined $entr )
   {
       # Allow local EPrints authentication for admins (accounts not found in LDAP)
       my $user = EPrints::DataObj::User::user_with_username( $session, $username );
       return 0 unless $user;

       my $user_type = $user->get_type;
       if( $user_type eq "admin" )
       {
           # internal authentication for "admin" type
           return $session->get_database->valid_login( $username, $password );
       }
       return 0;
   }
   my $ldap_dn = $entr->dn;

   #filter the user found based on group (make sure the user is in Staff_grp group in OID)
   my $userGroup = $ldap->search (
       base    => "$groupbase",
       scope   => "sub",
       filter  => "(&(uniquemember=$ldap_dn))",
       attrs   =>  ['cn'],
       sizelimit=>1

   );

   my $entrGroup = $userGroup->pop_entry;
   unless( defined $entrGroup )
   {
        # User Not in Staff group - reject login
        print STDERR Time::Piece::localtime->strftime('[%a %b %d %H:%M:%S %Y]');
        print STDERR " NOT AUTHORIZED : User $username is not a staff\n";
        return 0;
   }

   # Check password
   my $mesg = $ldap->bind( $ldap_dn, password => $password );
   if( $mesg->code() )
   {
       return 0;
   }

   # Does account already exist?
   my $user = EPrints::DataObj::User::user_with_username( $session, $username );
   if( !defined $user )
   {
       # New account
       $user = EPrints::DataObj::User::create( $session, "user" );
       $user->set_value( "username", $username );
   }

   # Set metadata
   my $name = {};
   $name->{family} = $entr->get_value( "sn" );
   $name->{given} = $entr->get_value( "given" );
   $user->set_value( "name", $name );
   $user->set_value( "username", $username );
   $user->set_value( "email", $entr->get_value( "mail" ) );
   $user->commit();

   $ldap->unbind if $ldap;

   return 1;
}
Things to note
  • This script uses a dedicated proxy account which must exist in your LDAP tree and has appropriate permissions (ACL settings) to search for users and read their uid,givenname,sn,mail attributes.
  • It changes the flow of user_login.pl a little to only check for local admin accounts (no users or editors; we have them all in our LDAP tree) and only when no user is found for ldap authentication. This allows you to have your admins in LDAP (if you want) but still use the local admin for "promoting" other users to admins, among other things (which could also be done with a simple SQL update directly in the RDBMS). If you don't need the local admin, remove those lines and just return 0 since no user was found in LDAP.
  • You could change the default role for generated user accounts from user, if you really wanted.
Now restart your apache
exit
sudo service apache2 restart 
Now your Eprints ready for LDAP authentication!

Step 4 of 4 : Finally, test the installation

On your PC (not your server) set the Eprints server  domain name you just setup in your hosts file. In this tutorial we used myeprints.example.my as the domain name with 10.0.0.11 IP Address for the Eprint server.
In Windows 7 :

Select the Start menu key and locate Notepad. ...
Right click on Notepad. ...
Select Run as administrator.
Using notepad, open C:\Windows\System32\Drivers\etc\hosts


In Linux PC or Mac :

sudo nano /etc/hosts
and add this line at the bottom of the file (Replace 10.0.0.11 with the eprints server IP Address) :

10.0.0.11       myeprints.example.my
Save and close.
To test it, using your browser go to http://myeprints.example.my . Eprints default page should be displayed if you are successful. Enjoy your brand-new shiny Eprints!


EmoticonEmoticon