Hi Sean,
We have a simple embargo setup working on a repository with
a single collection and a simple embargo model.
I can give you a dspace-1.5.1ish-api.jar that implements this
if you like.
Good luck!
Reuben
1. Modify input-submission forms so that a submitter
can set dc:date-available and dc:rights to indicate
an embargo's duration and type (Global or Local).
config/input-forms.xml
<field>
<dc-schema>dc</dc-schema>
<dc-element>date</dc-element>
<dc-qualifier>available</dc-qualifier>
<repeatable>false</repeatable>
<label>Embargo</label>
<input-type
value-pairs-name="etd_embargo">dropdown</input-type>
<hint>
An embargo prevents access to a thesis for a period of time
while the author resolves some issue like a pending patent,
security restriction, or other similar constraint on public
access.
</hint>
<required></required>
</field>
<field>
<dc-schema>dc</dc-schema>
<dc-element>rights</dc-element>
<repeatable>false</repeatable>
<label>Embargo Type</label>
<input-type
value-pairs-name="etd_embargo_type">dropdown</input-type>
<hint>A normal Embargo prevents unauthenticated access to the
thesis, but allows access to members of the
Auburn community that login to the ETD server.
A global embargo also prevents access by Auburn logins.
</hint>
<required></required>
</field>
...
<value-pairs value-pairs-name="etd_embargo_type" dc-term="rights">
<pair>
<displayed-value>Outside Auburn Embargo</displayed-value>
<stored-value>EMBARGO_NOT_AUBURN</stored-value>
</pair>
<pair>
<displayed-value>Global Embargo</displayed-value>
<stored-value>EMBARGO_GLOBAL</stored-value>
</pair>
</value-pairs>
<value-pairs value-pairs-name="etd_embargo" dc-term="date.available">
<pair>
<displayed-value>No embargo - immediate access to
thesis</displayed-value>
<stored-value>NO_RESTRICTION</stored-value>
</pair>
<pair>
<displayed-value>Access to thesis in 6 months</displayed-value>
<stored-value>MONTHS_WITHHELD:6</stored-value>
</pair>
<pair>
<displayed-value>Access to thesis in 1 year</displayed-value>
<stored-value>MONTHS_WITHHELD:12</stored-value>
</pair>
<pair>
<displayed-value>Access thesis in 2 years</displayed-value>
<stored-value>MONTHS_WITHHELD:24</stored-value>
</pair>
<pair>
<displayed-value>Access to thesis in 3 years</displayed-value>
<stored-value>MONTHS_WITHHELD:36</stored-value>
</pair>
<pair>
<displayed-value>Access to thesis in 4 years</displayed-value>
<stored-value>MONTHS_WITHHELD:48</stored-value>
</pair>
<pair>
<displayed-value>Access thesis in 5 years</displayed-value>
<stored-value>MONTHS_WITHHELD:60</stored-value>
</pair>
</value-pairs>
2. Modify
src/main/java/org/dspace/authorize/AuthorizeManager.java
to call out to an EmbargoManager to check if an embargo
is active on an object, but ignore the embargo if the user
has WRITE permission.
svn diff:
Index: src/main/java/org/dspace/authorize/AuthorizeManager.java
===================================================================
---
src/main/java/org/dspace/authorize/AuthorizeManager.java (revision
2942)
+++ src/main/java/org/dspace/authorize/AuthorizeManager.java (working
copy)
@@ -40,11 +40,19 @@
package org.dspace.authorize;
import java.sql.SQLException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.Iterator;
import java.util.List;
+import org.apache.log4j.Logger;
+import org.dspace.content.Bitstream;
+import org.dspace.content.Bundle;
+import org.dspace.content.DCValue;
import org.dspace.content.DSpaceObject;
+import org.dspace.content.Item;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
@@ -70,6 +78,7 @@
*/
public class AuthorizeManager
{
+ private static final Logger log =
Logger.getLogger(AuthorizeManager.class);
/**
* Utility method, checks that the current user of the given
context can
* perform all of the specified actions on the given object. An
@@ -236,6 +245,9 @@
return isAuthorized;
}
+
+ private static final EmbargoManager mgr_embargo = new
SimpleEmbargoManager ();
+
/**
* Check to see if the given user can perform the given action on
the given
* object. Always returns true if the ignore authorization flat is
set in
@@ -266,6 +278,11 @@
return false;
}
+
+ //if (log.isDebugEnabled()) {
+
log.info( "authorizing access to object id: " + o.getID () );
+ //}
+
// is authorization disabled for this context?
if (c.ignoreAuthorization())
{
@@ -289,6 +306,18 @@
}
}
+ if ( (Constants.READ == action)
+ && (Constants.BITSTREAM == o.getType ())
+ && mgr_embargo.checkEmbargo( (Bitstream) o, userid )
+ ) {
+ if ( 0 == userid ) {
+ return false;
+ }
+ // a user with WRITE permission on the object does
+ // not need to respect the EMBARGO
+ return authorize( c, o, Constants.WRITE, e );
+ }
+
for (ResourcePolicy rp : getPoliciesActionFilter(c, o,
action))
{
// check policies for date validity
3. Implement the EmbargoManager interface to check if the item
above a bitstream has dc:date-available and dc:rights values
that indicate an active embargo.
A "local access ok" embargo does not apply to an authenticated
user.
package org.dspace.authorize;
import java.sql.SQLException;
import org.dspace.content.Bitstream;
/**
* Controller knows how to check whether an
* embargo is in place on a given thing for a given user
*/
public interface EmbargoManager {
/**
* Check whether an embargo on thing is active
* for user with id i_userid
*
* @return true if an embargo is active
*/
public boolean checkEmbargo ( Bitstream thing, int i_userid )
throws SQLException;
}
--
package org.dspace.authorize;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.log4j.Logger;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.content.DCValue;
/**
* Simple implementation of EmbargoManager.
* Hard to unittest this stuff since it's coupled
* strongly with the server environment.
*/
public class SimpleEmbargoManager implements EmbargoManager {
private static final Logger log =
Logger.getLogger(SimpleEmbargoManager.class);
/**
* Check if there's an embargo on the given item -
* dc.issued.date_available and dc.rights
* metadata needs to be checked
*
* @return true if an embargo is still in effect for
* the given item and user
*/
private boolean checkEmbargoOnItem ( Item item, int i_userid ) {
for ( DCValue dc_embargo : item.getMetadata( "dc", "date",
"available", Item.ANY ) ) {
boolean b_embargo = false;
if ( dc_embargo.value.startsWith( "MONTHS_WITHHELD:" ) ) {
DateFormat formatter = new
SimpleDateFormat("yyyy-MM-dd");
Date t_now = new Date ();
int i_months_withheld = Integer.parseInt(
dc_embargo.value.substring( "MONTHS_WITHHELD:".length () ) );
// Frick - figure out if embargo is still in effect
DCValue[] v_issued = item.getMetadata( "dc", "date",
"issued", Item.ANY );
if ( v_issued.length < 1 ) {
log.info( "embargo failed to find ISSUED date for
item: " + item.getID () );
}
for ( DCValue dc_issued : v_issued ) {
String s_date = dc_issued.value;
int i_split = s_date.indexOf( "T" );
if ( i_split > 0 ) {
s_date = s_date.substring( 0, i_split );
}
try {
Date t_issued = formatter.parse( s_date );
// Just a loose estimate - 31 days/month
Date t_embargo = new Date( t_issued.getTime ()
+
(long)
i_months_withheld*31*24*60*60*1000
);
if ( t_now.getTime () < t_embargo.getTime () )
{
// embargo is still in effect!
log.debug( "Embargo in effect on item id: "
+ item.getID () + " t_now: " + t_now + ", t_issued: " + t_issued + ",
t_embargo: " + t_embargo );
b_embargo = true;
} else {
log.debug( "Embargo expired on item: " +
item.getID() + " t_now: " + t_now + ", t_issued: " + t_issued + ",
t_embargo: " + t_embargo );
}
} catch ( java.text.ParseException e ) {
log.info( "Failed to parse date.available
embargo string: " + s_date );
}
break; // Should be exactly 1 issue date
} // endfor - dc:date.issued
if ( b_embargo ) {
if ( 0 == i_userid ) {
// anonymous users are all embargoed
return true;
}
// An authenticated user only has to respect a
// GLOBAL embargo
DCValue[] v_rights = item.getMetadata( "dc",
"rights", null, Item.ANY );
for ( DCValue dc_rights : v_rights ) {
if ( "EMBARGO_GLOBAL".equals( dc_rights.value )
) {
return true;
}
break; // only one
}
// authenticated users can access non-global
embargo items
}
break; // break out of the date.available loop!
}
} // endfor dc:date.available
// no active embargo detected during metadata scan
return false;
}
/**
* Return true if an embargo is in effect on the given thing.
* Application policy determines which users must respect an
embargo.
* Embargo is only checked for BitStream objects by crawling
* up to the Item level and checking for date.available
* metadata specifying MONTHS_WITHHELD:#
* TODO: make this method configurable via a config file
* and plugin mechanism.
*
* @param i_userid of user trying to access thing, 0 == Anonymous
* @param thing to test for embargo
* @return true if an embargo needs enforced, false otherwise
*/
public boolean checkEmbargo ( Bitstream thing, int i_userid )
throws SQLException {
log.info( "checking embargo on bitstream id: " + thing.getID ()
);
// Check for an embargo on the owning item - ugh!
for ( Bundle bundle : ((Bitstream) thing).getBundles () ) {
for ( Item item : bundle.getItems () ) {
if ( checkEmbargoOnItem( item, i_userid ) ) {
return true;
}
} // endfor item
} // endofor bundle
return false;
}
}
>>> Sean Carte <
sean....@gmail.com> 2/11/2009 5:27 AM >>>
------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with
Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and
code to
build responsive, highly engaging applications that combine the power
of local
resources and data with the reach of the web. Download the Adobe AIR
SDK and
Ajax docs to start building applications
today-
http://p.sf.net/sfu/adobe-com
_______________________________________________
DSpace-tech mailing list
DSpac...@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dspace-tech