Access

By Daniel Berthereau Allow a visitor or a user to access to selected reserved resources via a request, an ip check, an authentication, or a token.
Download 3.4.45

Access (module for Omeka S)

New versions of this module and support for Omeka S version 3.0 and above are available on GitLab, which seems to respect users and privacy better than the previous repository.

Access is a module for Omeka S that allows to protect files to be accessed from the anonymous visitors, but nevertheless available globally or on requests by guests users, reserved to a list of ips, or available by an email or a token. Start and end dates of an embargo can be used too, separately or not.

See below for more information on usage.

You may use module Guest Private to access public or private resources on private sites.

This module can be tested directly in your browser
Try Access in your browser

Installation

Associated modules

To allow access to reserved resources for user with role "Guest", the module will need to identify users, generally with the module Guest or Guest Role.

To define specific item sets, you can use standard item sets or use the module Dynamic Item Sets to include items automatically in specific items sets according to metadata.

For old themes, the public part can be managed easily via the module Blocks Disposition, but it is recommended to use resource page blocks for new themes.

The module is compatible with the module Analytics (and the older Statistics) for download tracking. When Access is active with its own .htaccess rule, the download rule is not needed because Access calls Analytics directly. On uninstall, the Access rule is automatically converted to an Analytics (or Statistics) download rule if the module is active (see below).

The module is compatible with the module Derivative Media that allows to use specific derivative files instead original (for example a standard mp4 instead of a proprietary and unreadable Microsoft wmf). Note the paths should be added to the Apache config (htaccess).

Incompatibility

Until version 3.4.16, the module was not compatible with module Group.

If the module Statistics is installed, it must be version 3.4.12 or later. The version that was tracking downloads was moved to the dedicated module Analytics.

Installation of the module

See general end user documentation for installing a module.

This module requires the module Common, that should be installed first.

  • From the zip

Download the last release Access.zip from the list of releases, and uncompress it in the modules directory.

  • From the source and for development:

If the module was installed from the source, rename the name of the folder of the module to Access.

  • For test

The module includes a comprehensive test suite with unit and functional tests. Run them from the root of Omeka:

vendor/bin/phpunit -c modules/Access/phpunit.xml

Configuration of the web server

Without a rewrite rule, the web server (Apache or Nginx) serves files directly, bypassing Omeka entirely. You must configure the web server to redirect file requests to the module so it can check access rights before serving or denying the file.

Automatic management of .htaccess

The module can automatically manage the Apache rewrite rule in the root .htaccess file. On installation, a rule protecting original and large files is written automatically.

The Files to protect sub-section provides:

  • Skip .htaccess management: when checked, the module will not write or update the rewrite rule in the root .htaccess. Use this option when you prefer to manage the Apache redirections manually (virtual host, manual .htaccess edits, or an infrastructure where the file is not writable).
  • File type checkboxes: select which standard derivative types to protect among original, large, medium and square.
  • Custom types field: add extra path segments separated by spaces, for example mp3 mp4 webm ogg pdf when using module Derivative Media.

When you save the configuration, the module inserts or updates a managed block in the .htaccess:

# Module Access: protect files.
# This rule is automatically managed by the module.
RewriteRule "^files/(original|large)/(.*)$" "access/files/$1/$2" [NC,L]

The block is identified by its marker comment, so the module can update or remove it without affecting the rest of the file.

When the .htaccess is not writable, the module cannot modify it. In that case the rule to add or remove is displayed in the configuration form so you can apply it manually.

Important: by default with Omeka, files are not protected. Installing the module alone does not restrict access to files when the .htaccess is write-protected.

Legacy rules

If the module detects a rewrite rule that was written manually (without the marker comment), it is treated as a legacy rule. A warning is displayed with the detected file types. Saving the configuration converts the legacy rule into the managed format automatically.

Uninstall and module Analytics (ex-part of module Statistics)

When the module is uninstalled, the managed block is removed from the .htaccess. If the module Analytics is active and has no download rule of its own, the Access rule is automatically converted into an Analytics download rule so that download tracking continues to work:

# Module Analytics: count downloads.
# This rule is automatically managed by the module.
RewriteRule "^files/(original|large)/(.*)$" "download/files/$1/$2" [NC,L]

Manual Apache configuration

If you prefer to configure Apache manually, or if the .htaccess is not writable, follow the instructions below.

WARNING: Because the configuration of Apache is complex and infrastructures vary, always check access to free and restricted files from a private browser.

The Apache file .htaccess at the root of Omeka should be updated to avoid direct access to files and to redirect urls to the module.

For that, you have to adapt the following code to your needs in the main .htaccess at the root of Omeka, in a .htaccess file in the files directory, or directly in the config of the virtual host of the server (quicker). The example below is written for the Omeka .htaccess file. If you prefer to use other files, adapt the paths.

In this example, all original and large files will be protected: a check will be done by the module before delivering files. If the user has no access to a file, a fake file is displayed.

The small derivatives files (medium and square thumbnails), can be protected too, but it is generally useless. Anyway, it depends on the original images.

Don't forget to add derivative paths if you use module Derivative Media.

You can adapt routes.ini as you wish too, but this is useless in most cases.

Process of the rewrite

The goal of the rewrite rule is to prevent Apache from serving files directly (bypassing Omeka) and to route the request through the module's controller (AccessFileController). The controller checks the user's rights before serving the file or a locked placeholder.

The module's Laminas route ([/access]/files/:type/:filename) matches both /files/... and /access/files/.... A simple internal rewrite [NC,L] is enough: its only role is to prevent Apache from serving the static file directly (the RewriteCond %{REQUEST_FILENAME} -f rule in Omeka's default .htaccess would otherwise bypass PHP entirely). No mod_proxy and no external redirect are needed.

For the flag [P], useless in most of the cases, you should enable the module Proxy and restart Apache:

# Depending on your config, either:
sudo a2enmod proxy
# Or something similar:
sudo a2enmod proxy_fcgi
# Then:
sudo systemctl restart apache2
When Omeka S is installed at the root of a domain or a sub-domain

Insert the following lines at line 4 of .htaccess, just after RewriteEngine On, eventually adding |medium|square to the list of thumbnails:

# Set rule for original and selected derivative files (usually at least large thumbnails).
RewriteRule "^files/(original|large)/(.*)$" "/access/files/$1/$2" [NC,L]

Alternatively, with flag [P] (requires mod_proxy):

RewriteRule "^files/(original|large)/(.*)$" "/access/files/$1/$2" [P]

Using a full URL to force an external redirect (302) is not recommended, as it adds a round-trip and may expose internal ports behind a reverse proxy:

# Not recommended.
RewriteRule "^files/(original|large)/(.*)$" "%{REQUEST_SCHEME}://%{HTTP_HOST}/access/files/$1/$2" [NC,L]
When Omeka S is installed in a sub-path (https://example.org/digital-library/)

Insert the following lines at line 4 of .htaccess, just after RewriteEngine On, adapting it to your real config (here, the sub-path is digital-library), eventually adding |medium|square to the list of thumbnails:

# Set rule for original and selected derivative files (usually at least large thumbnails).
RewriteRule "^files/(original|large)/(.*)$" "/digital-library/access/files/$1/$2" [NC,L]
Common issues
  • Remove the leading "/" before "files/" in .htaccess

In .htaccess context, Apache strips the leading / before matching RewriteRule patterns. Use ^files/... instead of ^/files/.... The leading / form is only valid inside the virtual host configuration.

  • Unable to proxy with https (flag [P] only)

If the flag [P] is used with a secured server (https), the certificate should be running and up-to-date and the option SSLProxyEngine on should be set in the Apache config of the web server.

If you have access to the Apache config, you can include all rules inside it directly (ProxyPass). If you don't have access to it, just use the full unsecure url with http:// (with real domain or %{HTTP_HOST}), for the internal proxy. Because it is a fake proxy, it doesn't matter if the internal redirect url is unsecure:

RewriteRule "^files/(original|large)/(.*)$" "http://%{HTTP_HOST}/digital-library/access/files/$1/$2" [P]

Compatibility with module Analytics (ex-part of module Statistics)

The module is compatible with the module Analytics for download tracking. When Access is active with its own .htaccess rule, only the Access rule (/access/files/) is needed: the module calls Analytics directly when serving files, so a separate /download/ rule is not necessary.

Important: do not keep a /download/ rule alongside the /access/ rule. The /download/ route does not check access rights, so a private file would become public.

When the module Access is uninstalled, it automatically converts its .htaccess rule into an Analytics download rule if the module is active, so download tracking continues seamlessly (see above).

Nginx

The configuration of Apache above should be adapted for Nginx.

Usage

Omeka has two modes of visibility: public or private. The Access module adds a second, independant check on file content only: the right to download a media file. The record itself is never hidden by this module: it follows Omeka core visibility.

So in this module, three independent conditions must be satisfied for a visitor to download a file:

  • the item and the media must be public (Omeka core check);
  • the access level on the media (after cascade) must allow access for this visitor;
  • the embargo dates, if any, must not block access.

A level set on an item set cascades automatically to its items and medias. A level set on an item cascades automatically to its medias.

The access and the embargo are stored in the database, even if they are set via a property value. The computed effective rights are stored too for quicker access: it is the result of the cascade item set > item > media. This level is the strictest along the chain, on the order free < reserved < protected < forbidden, taking the maximum over the own level of the resource, its parent item and all its item sets:

  • set a level on an item set: all its items and media inherit it (they can still be set stricter individually, never looser);
  • set a level per media or per item: the collection is left neutral (free) and does not interfere;
  • an item in several item sets with contradictory levels takes the strictest of them (a cataloguing error can only make a resource more restricted, never more open).

There is no more "propagation mode" and no more "apply recursive" option: the cascade is permanent and non destructive. The value set by the admin is never overwritten and only the effective column is recomputed. A media is thus always at least as restricted as its item and item sets, but a free media in a reserved collection cannot be made public: the cascade is one-way (an ancestor can only tighten a descendant). To keep a document public, leave its collections neutral.

A Rebuild access index task recomputes the effective columns for the whole base. It is normally not needed (the recompute is automatic on each save) but repairs the index after a bulk import, a direct database edit, a bulk edit of the access property values (in property-storage mode), or a change of the option for the "Cascade embargo dates".

Access levels: semantic summary

Level Record File Admin access request Contact author
free Visible Downloadable by anyone Useless Useless
reserved Visible Blocked for anonymous; unlocked by any active bypass mode or by an approved individual access request Yes Possible
protected Visible Blocked for everyone; unlocked only by an approved individual access request (no automatic bypass) Yes (mandatory) Possible
forbidden Visible Blocked for everyone; no path through the admin access request flow No Only way to get file

reserved vs protected is the difference between silently granted to known contexts (a reader on the right IP, a logged-in SSO user, a member of the guest role) and always individually validated (the admin must approve every single download).

forbidden does not deny existence (the record is still publicly visible). It only removes the standard request flow. If you also want the record to be hidden, set the resource itself to private (is_public = 0).

The right to view a reserved file can be granted through several channels: the guest role, an external identity provider (module CAS, LDAP or Single Sign-On), by IP (v4 or v6), by email, or by token. For protected files, only the individual access request flow (user/email/token modes) is honoured.

The cascade is applied automatically and retroactively: adding an item to an item set, or a media to an item, immediately recomputes the effective level of the new resource from the hierarchy. No manual step is needed.

When an embargo is set, it can be bypassed (or not) per user via the access_embargo_bypass setting. Currently only files can be under embargo. The embargo is checked independently from the level: a file may be free but under embargo, or reserved without embargo. By default an embargo is per-resource and only gates the resource it is set on. The access_embargo_cascade setting (off by default) makes an embargo set on an item set or an item cascade to its items and media too (widest window: earliest start, latest end), the same way the level does; run the Rebuild access index task after changing it. The access_embargo_ended_level and access_embargo_ended_date settings control what the level becomes when an embargo expires: keep leaves the document at its level (e.g. still university-only), while free / under drop it so a facet can show "restricted" during the embargo and "free" afterwards.

For a "forbidden" resource, the standard admin access request flow is not offered. The recommended recourse is the view helper accessContactAuthor($resource): when the ContactUs module is installed, the helper delegates to its contactUs helper with contact='author', which resolves the author email from a configured property (e.g. dcterms:creator) and renders a styled contact form with consent, hashcash, etc. Without ContactUs, the helper falls back to a short message inviting the visitor to reach the site administrator (who can then forward the request to the author).

Access mode

The rights to see the files are controlled on the fly. The reserved visibility can be managed in multiple ways:

  • Global modes
  • ip: all visitors with a specific ip, for example the ip of the physical library or the one of a researcher, can have access to all the reserved files. Ip can be configured to access specific item sets, for example 123.45.67.89 = 51, 54
  • guest: all guest users have access to all the reserved files.
  • auth_external: all users authenticated via an external identity provider (currently via module CAS and SingleSignOn, later for Ldap) have access to media contents.
  • auth_cas: all users authenticated via CAS (module CAS) have access to all reserved files.
  • auth_ldap: all users authenticated via Ldap (module Ldap) have access to all reserved files (currently unsupported).
  • auth_sso: all users authenticated via SAML/Shibboleth (module SingleSignOn) have access to all reserved files.
  • auth_sso_idp: users authenticated by specified identity providers have access to a list of reserved media by item sets.
  • email_regex: all authenticated users with an email matching a regex pattern have access to all reserved files.
  • Individual modes
  • user: each file should be made accessible by a specific user one by one. So the module has some forms to manage individual requests and accesses.
  • email: anybody authenticated via an email have access to specific media contents. This protection is simple and light, but not the most secure.
  • token: all users or visitor authenticated via a token have access to specific media contents.

Individual modes require that an admin allow each right for each resource.

When none of the individual modes (user, email, token) is enabled, the "Access" tab on the item/media/item-set show page is hidden, and the admin pages /admin/access-request and /admin/access-log display an inline warning stating that these pages only manage individual access requests.

Identification of the reserved resources

After the configuration, you should identify all resources that you want to make available via a reserved access. By default, private resources remain private, so you need to allow visitors to know that they exist. That is to say you can keep some private resources private, and some other ones available on request, or globally.

There are two ways to indicate which resources are reserved. The storage mode is chosen in the sub-section Access rights of the configuration form via the "Storage of access level and embargo" radio button:

  • Resource metadata (default): the access level and embargo are stored as specific metadata of the resource, edited via a dedicated radio button in the advanced tab of the resource form.
  • Property in the resource: the access level and embargo dates are stored as standard property values (for example dcterms:accessRights or curation:access), searchable and exportable like any other property. The default labels are "free", "reserved", "protected" or "forbidden". The properties and the labels can be translated or modified in the config. It is recommended to create a custom vocab and to set the datatype as customvocab:X used via the resource templates to avoid errors in the values.

A private media remains private. A public media will be accessible only if its status is not forbidden and not during an embargo, if any.

Note that a public item can have a private media and vice-versa. So, the value may be set in the metadata of the media. The value can be specified for the item too to simplify management when all medias have the same access righs.

Inheritance and cascade

Access levels and embargo cascade automatically down the hierarchy item set > item > media. Two values are stored per resource in the access_status table:

  • level_set (and embargo_*_set): the decision made by the admin on this resource, before inheritance. This is what the edit form and the API edit.
  • level (and embargo_start, embargo_end): the effective value, the materialized cascade. This is what the file gating, the facets and the search read. It is recomputed on every save and never edited directly.

The effective level is the strictest (free < reserved < protected < forbidden) of the resource own level, its parent item and all its item sets. The effective embargo equals the set embargo, unless access_embargo_cascade is on, in which case it is the widest window (earliest start, latest end) of the chain.

Consequences:

  • A restricted item set restricts all its items and media, with no manual step.
  • A media or an item may be set stricter than its ancestors, never looser (the cascade is one-way: an ancestor can only tighten a descendant).
  • An item in several item sets takes the strictest of their levels, so a cataloguing error can only make a resource more restricted, never more open.
  • A media without its own level follows its item dynamically: if the item level later changes, the media effective level follows.

There is no propagation mode and no "apply recursive" option: the cascade is permanent and non destructive. The Rebuild access index task only rebuilds the effective columns after a bulk operation that bypassed the save events. In property-storage mode, the rebuild first resyncs the set columns from the property values, then recomputes the effective columns.

The Tasks tab also offers a Reset the access status action, to align an existing base with a chosen management logic after the upgrade (the upgrade itself is neutral: it keeps the current effective levels for every install). Check the resource types to neutralize, then the task clears their level and embargo decisions and rebuilds the effective index:

  • check item sets to switch to a "by document" logic (the access is driven by items and medias; the collections stop restricting);
  • check items and medias to switch to a "by collection" logic (the access is driven by the item sets; the documents inherit).

For example, a base that used the former propagation to push a collection level down onto every item and media should reset items and medias, so those inherited levels become neutral again and follow their collections. This is a one-time, irreversible operation. In property-storage mode, it also deletes the corresponding property values of the reset resources.

Embargo expiry

The embargo is checked independently from the level. When an embargo ends, the access_embargo_ended_level setting controls the transition of the resource own level:

  • keep: the level is unchanged, so a document stays restricted after its embargo (e.g. still university-only);
  • free: the level drops to free;
  • under: the level drops one step (reserved → free, protected/forbidden → reserved).

Combined with access_embargo_ended_date (keep or clear the dates), this lets a facet show a "restricted" status while a document is under embargo and "free" once the embargo has passed. In property-storage mode, the transition is also written back into the property values.

Advanced search

The advanced search form includes a multi-select filter for access levels. You can select multiple levels to search for resources matching any of the selected levels. When no levels are selected, all resources are returned regardless of their access level.

Item sets

As indicated above, it is possible to define specific rights by item sets when using some access mode, mainly ip and sso idp.

To define a specific rights, set the ip or the idp, then "=", then the item set ids to which the ip or the idp can access. If there is no item set defined, the check will be defined per item. Each item set may be prepended with a "-" to forbid access to a specific item set. This option is useful when a global item set is defined to identify all reserved resources. When a federation like Renater is used, set "federation =" then the item sets.

The order matters: the user is checked in the order of the list, so the federation is generally specified at last.

The use of the module Dynamic Item Sets may be useful, because it allows to define items included in a item sets according to a standard query.

Example for the access mode "ip"

12.34.56.78
124.8.16.32 = 17 89 -1940
65.43.21.0/24 = -2005

Here, the user identified via the first ip has access to all reserved resources; the user identified via the second ip has access to item sets #17 and #89, but not to item set #1940. The federation has access to all items, except those of item set 2005.

Reverse proxy and private IPs

When Omeka S is behind a reverse proxy (Traefik, nginx, Apache, Docker bridge, load balancer), fill the field "Trusted proxies" with the internal IPs of your reverse proxy. The module then reads X-Forwarded-For or X-Real-IP instead of the proxy socket address, but only when the request comes from one of these trusted IPs, to prevent header spoofing. Without this list, every visitor is seen with the proxy IP and, if that IP is listed in the rules, all visitors inherit the rights attached to it.

The trusted proxy is auto-detected on install, on upgrade and on config form submit: if the list is empty and proxy headers are present on the current admin request, REMOTE_ADDR is added automatically. An existing list is never overwritten.

The configuration page warns automatically when: - a reverse proxy header is detected but no trusted proxy is configured; - trusted proxies are configured but no proxy header is detected on the current request; - a private or loopback IP (RFC1918, 127/8, fc00::/7, link-local, etc.) is listed in the access rules, typical sign of a Docker bridge or internal proxy leaking to external visitors; - the IP of the current administrator request is itself listed in the access rules and no trusted proxy is configured (critical: indicates a proxy bypass).

Authorization endpoint for external services

The module exposes a lightweight endpoint at /access/authorize returning the authorization result as an HTTP status code with an empty body:

  • 200: access allowed
  • 403: access denied
  • 404: media not found

Accepts one of the following query parameters:

  • media=<id>: internal media id
  • storage=<storage_id>: storage_id (filename without extension)
  • filename=<storage_id.ext>: full filename

It reuses the same isAllowedMediaContent logic as the main controller (IP rules, embargo, individual requests, SSO IdP, etc.). The setting "Trusted proxies" applies, so the endpoint honors X-Forwarded-For / X-Real-IP only when the calling service (Cantaloupe, traefik, nginx auth_request) is listed as a trusted proxy.

Typical uses: Cantaloupe delegate script, Traefik ForwardAuth, nginx auth_request, Apache auth subrequest. Without such a check, an IIIF image server reverse-proxied on /iiif/* fully bypasses Omeka and Access.

A ready-to-use Cantaloupe delegate script is provided at data/delegates/cantaloupe.rb. Adjust the OMEKA_AUTHORIZE_URL constant and point Cantaloupe at it via delegate_script.pathname. The Cantaloupe server IP must be listed in "Trusted proxies" in the Omeka Access configuration.

Example for the access mode "sso idp"

idp.example.org =
shibboleth.another-example.org = 17 89 -1940
federation = -2005

Here, the user identified via idp.example.org has access to all reserved resources; the user identifier via the second idp has access to item sets #17 and #89, but not to item set #1940. The federation has access to all items, except those of item set #2005.

Embargo

By construction, the embargo works only on the media files: metadata are always visible for public and reserved resources.

An option in the config can be used to use it with or without the reserved access.

To create an embargo on a file, simply set the dates in the advanced tab or use properties curation:start and/or curation:end, or the ones specified in the config.

If you use a property to define the date of the embargo, it is recommended to use the datatype "numeric timestamp" from the module Numeric Datatypes, but a literal is fine. The date must be an iso one (2022-03-14). A time can be set too (2022-03-14T12:34:56).

Important: Generally, it is enough to set the embargo on the item. Set it on medias only when there are multiple medias with various status or date of embargo.

Two settings control what happens when an embargo ends:

  • What to do with the access level:
  • free: Set access level to "free"
  • under: Set access level to the level under ("free" for reserved, "reserved" for protected/forbidden)
  • keep: Keep the current access level
  • What to do with the embargo dates:
  • clear: Remove the embargo dates
  • keep: Keep the embargo dates

A job is run automatically once a day to update access status and embargo.

Furthermore, a check is automatically done when an anonymous visitor or a restricted user is accessing a restricted file. In that case, the media may be set public automatically when the embargo is finished.

The job does not update the resource when the visibility is not logical, for example when the resource have been set public with a date of end of embargo. Of course, don't set a date of end of embargo if the record is not ready or when it should remain private.

Status display in admin sidebar

The access status (level and, if any, embargo dates) is displayed in the right sidebar of the admin pages item/show, item-set/show and media/show, and also in the resource details sidebar (popup). When a resource has no row in access_status, the default level free is shown, matching the module runtime behavior (absence of status = free).

Management of requests

If you choose modes ip, guest, or external, there is nothing to do more. Once users are authenticated or authorized, they will be able to see the files.

In the case of the single modes user, email or token, there are two ways to process.

  • The admin can made some item sets, items or medias available directly in the menu "Access requests" in the sidebar. Simply add a new access, select a resource and a user, a email or a token, and the person will be able to view it.

  • The user or visitor can request an access to a specific resource. It can be done directly via a button, for logged users, or via a contact form for the anonymous visitors. The contact form may be added by this module or the module Contact Us. After the request, the admin will receive an email to accept or reject the request.

Once accepted, the requester will receive an email with an url to click, that will add a session cookie that will allow to browse the selected resources.

In public front-end, a dashboard is added for visitors: /s/my-site/access-request. Guest users have a specific board too: /s/my-site/guest/access-request.

Check of status levels

In some cases, when the status is stored in a property, you may want to check if all resources values statuses are well stored in the table access_status. Here are some sql queries for that, with French values and where curation:access is used (property 185 here):

# Items
SELECT `access_status`.`id`, `access_status`.`level`, `resource`.`is_public`
FROM `value`
INNER JOIN `access_status` ON `value`.`resource_id` = `access_status`.`id`
INNER JOIN `item` ON `item`.`id` = `access_status`.`id`
INNER JOIN `resource` ON `resource`.`id` = `item`.`id`
WHERE `value`.`property_id` = 185
    AND `value`.`value` = "Accès libre"
    AND `access_status`.`level` != 'free';

SELECT `access_status`.`id`, `access_status`.`level`, `resource`.`is_public`
FROM `value`
INNER JOIN `access_status` ON `value`.`resource_id` = `access_status`.`id`
INNER JOIN `item` ON `item`.`id` = `access_status`.`id`
INNER JOIN `resource` ON `resource`.`id` = `item`.`id`
WHERE `value`.`property_id` = 185
    AND `value`.`value` = "Accès restreint"
    AND `access_status`.`level` != 'reserved';

SELECT `access_status`.`id`, `access_status`.`level`, `resource`.`is_public`
FROM `value`
INNER JOIN `access_status` ON `value`.`resource_id` = `access_status`.`id`
INNER JOIN `item` ON `item`.`id` = `access_status`.`id`
INNER JOIN `resource` ON `resource`.`id` = `item`.`id`
WHERE `value`.`property_id` = 185
    AND `value`.`value` = "Non consultable"
    AND `access_status`.`level` != 'forbidden';

# Media
SELECT `access_status`.`id`, `access_status`.`level`, `resource`.`is_public`
FROM `value`
INNER JOIN `access_status` ON `value`.`resource_id` = `access_status`.`id`
INNER JOIN `media` ON `media`.`id` = `access_status`.`id`
INNER JOIN `resource` ON `resource`.`id` = `media`.`id`
WHERE `value`.`property_id` = 185
    AND `value`.`value` = "Accès libre"
    AND `access_status`.`level` != 'free';

SELECT `access_status`.`id`, `access_status`.`level`, `resource`.`is_public`
FROM `value`
INNER JOIN `access_status` ON `value`.`resource_id` = `access_status`.`id`
INNER JOIN `media` ON `media`.`id` = `access_status`.`id`
INNER JOIN `resource` ON `resource`.`id` = `media`.`id`
WHERE `value`.`property_id` = 185
    AND `value`.`value` = "Accès restreint"
    AND `access_status`.`level` != 'reserved';

SELECT `access_status`.`id`, `access_status`.`level`, `resource`.`is_public`
FROM `value`
INNER JOIN `access_status` ON `value`.`resource_id` = `access_status`.`id`
INNER JOIN `media` ON `media`.`id` = `access_status`.`id`
INNER JOIN `resource` ON `resource`.`id` = `media`.`id`
WHERE `value`.`property_id` = 185
    AND `value`.`value` = "Non consultable"
    AND `access_status`.`level` != 'forbidden';

TODO

  • [x] Fix ip check for ipv6.
  • [ ] Use Omeka Store instead of local file system.
  • [ ] Update temporal to avoid to check embargo each time via php.
  • [x] Reindexation (trigger event?) when embargo is updated automatically. Use the cron task of module EasyAdmin?
  • [ ] Clarify process for embargo start and update embargo start date with a specific option (no one seems to use it anyway).
  • [ ] Add a mode cas_itemsets to define access rules by cas attributes and item sets (like sso_idp).

Warning

Use it at your own risk.

It’s always recommended to backup your files and your databases and to check your archives regularly so you can roll back if needed.

Troubleshooting

See online issues on the module issues page on GitLab.

License

Module

This module is published under the CeCILL v2.1 license, compatible with GNU/GPL and approved by FSF and OSI.

This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software. You can use, modify and/ or redistribute the software under the terms of the CeCILL license as circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".

As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software’s author, the holder of the economic rights, and the successive licensors have only limited liability.

In this respect, the user’s attention is drawn to the risks associated with loading, using, modifying and/or developing or reproducing the software by the user in light of its specific status of free software, that may mean that it is complicated to manipulate, and that also therefore means that it is reserved for developers and experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the software’s suitability as regards their requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and operate it in the same conditions as regards security.

The fact that you are presently reading this means that you have had knowledge of the CeCILL license and that you accept its terms.

Image Locked file

The image Locked file is licensed under GNU/GPL.

Copyright

Version Released Minimum Omeka version
3.4.45July 06, 2026 [info]^4.1.0
3.4.44June 01, 2026 [info]^4.1.0
3.4.43May 04, 2026 [info]^4.1.0
3.4.42April 20, 2026 [info]^4.1.0
3.4.41April 06, 2026 [info]^4.1.0
3.4.40March 09, 2026 [info]^4.1.0
3.4.39February 23, 2026 [info]^4.1.0
3.4.38February 16, 2026 [info]^4.1.0
3.4.37January 12, 2026 [info]^4.1.0
3.4.36December 01, 2025 [info]^4.1.0
3.4.35November 03, 2025 [info]^4.1.0
3.4.34September 01, 2025 [info]^4.1.0
3.4.33June 09, 2025 [info]^4.1.0
3.4.32June 02, 2025 [info]^4.1.0
3.4.31February 03, 2025 [info]^4.1.0
3.4.30January 27, 2025 [info]^4.1.0
3.4.29January 06, 2025 [info]^4.1.0
3.4.28November 25, 2024 [info]^4.1.0
3.4.27July 29, 2024 [info]^4.1.0
3.4.26May 13, 2024 [info]^4.0.0
3.4.25April 14, 2024 [info]^4.0.0
3.4.24April 01, 2024 [info]^4.0.0
3.4.23March 25, 2024 [info]^4.0.0
3.4.22October 30, 2023 [info]^4.0.0
3.4.21October 02, 2023 [info]^4.0.0
3.4.20August 28, 2023 [info]^4.0.0
3.4.19August 21, 2023 [info]^4.0.0
3.4.18July 31, 2023 [info]^4.0.0