Skip to content
Merged
Show file tree
Hide file tree
Changes from 116 commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
feab404
Added ApiKeyService, ApiKeyTrait, Developer settings, striped-table c…
LuomaJuha Jun 27, 2025
fa5bb48
Added new scss alignments for creating default element alignment classes
LuomaJuha Jul 10, 2025
b235bf8
Adjusted api key token generation to be more unpredictable, added salt
LuomaJuha Jul 10, 2025
78d900b
Added APIKeyController, user must have a verified email to create an …
LuomaJuha Jul 30, 2025
65ea6b6
Adjusted translations
LuomaJuha Jul 30, 2025
b8da4a8
Added test for api keys to search api controller test
LuomaJuha Jul 30, 2025
4b759ec
Adjusted comments
LuomaJuha Jul 30, 2025
8efab0a
Revert changes to compiled css files
LuomaJuha Jul 30, 2025
fe4853c
Update module/VuFind/config/module.config.php
LuomaJuha Jul 31, 2025
f366036
Update module/VuFind/config/module.config.php
LuomaJuha Jul 31, 2025
f8c2f82
Update module/VuFindApi/src/VuFindApi/Controller/SearchApiController.php
LuomaJuha Jul 31, 2025
7e73ab5
Update module/VuFind/src/VuFind/ApiKey/ApiKeyTrait.php
LuomaJuha Jul 31, 2025
3df7ca7
Update module/VuFind/src/VuFind/ApiKey/ApiKeyService.php
LuomaJuha Jul 31, 2025
3f8d251
Update module/VuFind/src/VuFind/ApiKey/ApiKeyTrait.php
LuomaJuha Jul 31, 2025
1517201
Unified API key, removed API key functionality from OAI-PMH, use conf…
LuomaJuha Aug 1, 2025
c39ac37
Fix errors
LuomaJuha Aug 1, 2025
2ffc3cc
Merge branch 'api-key-implementation' of https://github.com/LuomaJuha…
LuomaJuha Aug 1, 2025
2b717d9
Removed component adjustment
LuomaJuha Aug 1, 2025
70476cf
Adjusted template breadcrumbs to be API key specific
LuomaJuha Aug 1, 2025
fd583c3
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Sep 1, 2025
94566d6
Adjusted tests
LuomaJuha Sep 1, 2025
05789f4
Removed extra newline
LuomaJuha Sep 1, 2025
c0495ef
Use permissions and assertion
LuomaJuha Sep 2, 2025
b2220f4
Adjusted assertions to be more flexible, changeg apikey controller to…
LuomaJuha Sep 9, 2025
8d2be49
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Sep 11, 2025
4b0332a
Update hasverifiedemailassertion to use newer lmc rbac
LuomaJuha Sep 11, 2025
10a0cad
Update module/VuFind/src/VuFind/View/Helper/Root/DeveloperFactory.php
LuomaJuha Sep 12, 2025
50acf3e
Update module/VuFind/src/VuFind/Role/DynamicRoleProvider.php
LuomaJuha Sep 12, 2025
c1aab9b
Adjusted module order, adjusted apikeyservice factory, removed getDbS…
LuomaJuha Sep 12, 2025
7601d58
Merge branch 'dev' into api-key-implementation
demiankatz Sep 12, 2025
0bf6250
Fix broken test.
demiankatz Sep 12, 2025
4529be8
Update languages/Developer/en.ini
LuomaJuha Sep 17, 2025
35aaa04
Update module/VuFind/src/VuFind/ApiKey/ApiKeyServiceFactory.php
LuomaJuha Sep 17, 2025
c5e1938
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Sep 18, 2025
a039bda
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Sep 18, 2025
80159bb
Added authorizationservicefactory, adjusted to delete only allowed to…
LuomaJuha Sep 18, 2025
8d20379
Added translations for se and sv
LuomaJuha Sep 19, 2025
860bb87
Update module/VuFind/src/VuFind/Db/Service/AccessTokenService.php
LuomaJuha Sep 22, 2025
b96795e
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Sep 22, 2025
81ab265
Merge branch 'api-key-implementation' of https://github.com/LuomaJuha…
LuomaJuha Sep 22, 2025
ce26530
Removed developerfactory, simplify developer helper
LuomaJuha Sep 22, 2025
e1f2b10
Added hasverifiedemailassertion to lmc_rbac assertion_manager, added …
LuomaJuha Sep 22, 2025
7e38cb7
Use parameter instead of hard coded 1
LuomaJuha Sep 22, 2025
8590e2e
Renamed migrations
LuomaJuha Sep 22, 2025
5fb9001
Update config/vufind/config.ini
LuomaJuha Sep 26, 2025
d962aed
Update module/VuFindApi/src/VuFindApi/Controller/SearchApiController.php
LuomaJuha Sep 26, 2025
70507bc
Update module/VuFindApi/src/VuFindApi/Controller/SearchApiController.php
LuomaJuha Sep 26, 2025
653d92b
Update themes/bootstrap5/templates/developersettings/displaysettings.…
LuomaJuha Sep 26, 2025
f671a2f
Simplified api-key trait initialization, removed alignments and use b…
LuomaJuha Oct 7, 2025
0422818
Fixed and cleaned up tests
LuomaJuha Oct 8, 2025
27413c2
Adjusted templates, added option to create more than 1 key per user, …
LuomaJuha Oct 8, 2025
923ead1
Renamed tokens to keys where applicable, change setting to key_limit
LuomaJuha Oct 8, 2025
9c5777e
Adjusted names of the functions and variable to match with each other…
LuomaJuha Oct 8, 2025
99b302c
Removed implements from SearchApiController, fixed migration
LuomaJuha Oct 8, 2025
348a6b7
Create own table for api keys, developersettingsservice and apikeyser…
LuomaJuha Oct 9, 2025
73e3f64
Adjusted pgsql
LuomaJuha Oct 9, 2025
171dc81
Merge branch 'dev' into api-key-implementation
LuomaJuha Oct 9, 2025
814f644
Fixed wrong comment addresses
LuomaJuha Oct 9, 2025
a9e0e8a
renumber migrations
LuomaJuha Oct 9, 2025
f0f06bc
Update year
LuomaJuha Oct 9, 2025
9706d07
Use interface where plausible, removed extra lines from test
LuomaJuha Oct 9, 2025
f571a03
Removed unnecessary max min lengths
LuomaJuha Oct 9, 2025
189feda
Cleaned api key generation template
LuomaJuha Oct 9, 2025
e4886c0
Implement the last used update
LuomaJuha Oct 9, 2025
e893d55
Minor language / punctuation tweaks.
demiankatz Oct 11, 2025
50d5341
Update config/vufind/config.ini
LuomaJuha Oct 13, 2025
a62dc62
Update module/VuFind/src/VuFind/DeveloperSettings/DeveloperSettingsSe…
LuomaJuha Oct 13, 2025
4a67a17
Update module/VuFindApi/src/VuFindApi/Controller/ApiTrait.php
LuomaJuha Oct 13, 2025
f415ccd
Adjusted logics and test, readded developersettings viewhelper, added…
LuomaJuha Oct 13, 2025
c200917
Adjusted comments in config.ini
LuomaJuha Oct 13, 2025
0dfff64
Added DeveloperSettingsServiceTest with getTestTokenIsValid and testG…
LuomaJuha Oct 13, 2025
b9a4dc0
Reverted input-text component, introduce it outside this pr
LuomaJuha Oct 13, 2025
da48185
Update config/vufind/config.ini
demiankatz Oct 13, 2025
ea80494
Removed extra keys, added base mink test for testing keys with records
LuomaJuha Oct 14, 2025
0723215
Merge branch 'api-key-implementation' of https://github.com/LuomaJuha…
LuomaJuha Oct 14, 2025
6a5b708
Mink tests working, needs cleanup
LuomaJuha Oct 14, 2025
ebbee27
Qa fixes
LuomaJuha Oct 14, 2025
fad326d
Added link to verify user email if verify_email setting is not used
LuomaJuha Oct 14, 2025
dd94748
Added test to verify email address to the mink, check also if the use…
LuomaJuha Oct 14, 2025
feb9525
Removed contents of delete expired, added check that salt is at least…
LuomaJuha Oct 14, 2025
310150e
Adjusted test to use setconstructorargs
LuomaJuha Oct 14, 2025
6bdae30
Adjusted api key salt_token example, removed unnecessary indexes, add…
LuomaJuha Oct 15, 2025
3f5cbbe
Update module/VuFindApi/src/VuFindApi/Controller/ApiTrait.php
LuomaJuha Oct 15, 2025
6dff6ca
Change to isApiKeyAllowed, clarify isApiKeyAllowed function logic and…
LuomaJuha Oct 15, 2025
f3480ff
Merge branch 'api-key-implementation' of https://github.com/LuomaJuha…
LuomaJuha Oct 15, 2025
21a768f
Phpcbf
LuomaJuha Oct 15, 2025
04ff35f
Adjust phtml indentation
LuomaJuha Oct 16, 2025
df4f135
Removed verify email link, if verify_auth is off then it should not b…
LuomaJuha Oct 16, 2025
aee0d60
Fix array indentation in template
LuomaJuha Oct 16, 2025
c85d988
Removed verify email key generation for now, add after
LuomaJuha Oct 16, 2025
dbc025d
Adjusted test order
LuomaJuha Oct 16, 2025
17e8ab0
Moved request helper functions to its own trait, mock getHeader for m…
LuomaJuha Oct 16, 2025
1230bfc
Adjusted comments, changed name getParamArray to getAllRequestParams …
LuomaJuha Oct 17, 2025
38c7da4
Adjusted comments, sql files and tests.
LuomaJuha Oct 19, 2025
0a2e9ae
Added example for createMockWithMethods
LuomaJuha Oct 20, 2025
fe26818
Adjusted to override
LuomaJuha Oct 20, 2025
a26fa33
Update module/VuFind/sql/pgsql.sql
LuomaJuha Oct 21, 2025
d317d7c
Update module/VuFind/sql/migrations/pgsql/11.0/010-add-api-key-table.sql
LuomaJuha Oct 21, 2025
b95ddee
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Oct 21, 2025
5a17412
Merge branch 'api-key-implementation' of https://github.com/LuomaJuha…
LuomaJuha Oct 21, 2025
bfc3674
Added API key to the swagger, adjusted error message for unauthorized…
LuomaJuha Oct 21, 2025
56e90e0
Update module/VuFindApi/tests/unit-tests/src/VuFindTest/Controller/Se…
LuomaJuha Oct 22, 2025
b2ec4cf
Added token index to orm annotation
LuomaJuha Oct 22, 2025
0ee30fe
Merge branch 'api-key-implementation' of https://github.com/LuomaJuha…
LuomaJuha Oct 22, 2025
02da0dd
Fixed table definition scripts and entity annotations
LuomaJuha Oct 23, 2025
422a226
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Oct 23, 2025
f78f376
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Oct 23, 2025
19fcba2
Adjusted tests to work
LuomaJuha Oct 23, 2025
4c61c48
Adjusted migration number
LuomaJuha Oct 23, 2025
b326a62
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Oct 23, 2025
00de67f
Update module/VuFind/src/VuFind/Db/Entity/ApiKey.php
LuomaJuha Oct 23, 2025
ddf8262
Update module/VuFind/src/VuFind/Db/Entity/ApiKeyEntityInterface.php
LuomaJuha Oct 23, 2025
8f4fca5
Update module/VuFind/sql/migrations/pgsql/11.0/012-add-api-key-table.sql
LuomaJuha Oct 23, 2025
f8c5810
Update module/VuFind/sql/pgsql.sql
LuomaJuha Oct 23, 2025
06dbfe5
Merge branch 'api-key-implementation' of https://github.com/LuomaJuha…
LuomaJuha Oct 23, 2025
50b7c8e
Merge branch 'villanova-dev' into api-key-implementation
LuomaJuha Oct 24, 2025
89b29a4
Update config/vufind/config.ini
demiankatz Oct 24, 2025
7b42346
Update permissions.ini
demiankatz Oct 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions config/constants.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@

// Define default latest year offset from current year for date ranges
defined('VUFIND_DEFAULT_LATEST_YEAR_OFFSET') || define('VUFIND_DEFAULT_LATEST_YEAR_OFFSET', 1);

// Define default API key header field name
defined('VUFIND_API_KEY_DEFAULT_HEADER_FIELD') || define('VUFIND_API_KEY_DEFAULT_HEADER_FIELD', 'X-API-KEY');
18 changes: 18 additions & 0 deletions config/vufind/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2689,6 +2689,24 @@ description = "The REST API provides access to search functions and records cont
; URL pointing to a Terms of Service page (optional, default is none):
;termsOfServiceUrl = "https://something"

; These settings control usage of API keys
[API_Keys]
; Mode for using API keys.
; 'disabled' means API keys are not in use and cannot be created. Default.
; 'optional' allows users to create API keys and use them, but it is not mandatory.
; 'enforced' forces users to create and provide an API key in a header field (see
; header_field setting below).
;mode = 'optional'
; Token salt to add when generating a new API key for a user.
Comment thread
EreMaijala marked this conversation as resolved.
Outdated
Comment thread
demiankatz marked this conversation as resolved.
Outdated
; Minimum allowed length for salt is 10 characters.
; Example command for creating a salt in terminal:
; php -r "echo hash('sha256', random_bytes(16)) . PHP_EOL;"
;token_salt =
; The header field key that should be used to provide the API key. Default is X-API-KEY.
;header_field = 'X-API-KEY'
; How many API keys can a user have at maximum. Default is 5.
;key_limit = 5

[Sorting]
; By default, VuFind sorts text in a locale-agnostic way; if this setting is
; turned on, the current user-selected locale will impact sort order.
Expand Down
4 changes: 4 additions & 0 deletions config/vufind/permissionBehavior.ini
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ defaultDeniedTemplateBehavior = false
[access.EITModule]
deniedTemplateBehavior = showTemplate:error/loginForAccess

; Configuration for developer settings
[feature.Developer]
deniedTemplateBehavior = "showTemplate:error/developer-settings-denied"

; Example configuration for non-standard favorites permission behavior:
;[feature.Favorites]
;deniedTemplateBehavior = "showMessage:Login for Favorites"
Expand Down
12 changes: 12 additions & 0 deletions config/vufind/permissions.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
; combined may vary from provider to provider (see below).
; permission - The name(s) of the permission(s) to grant. May be a single string or
; an array of strings.
; assertion - The name(s) of the assertion(s) class(es) to check for permission.
; May be a single assertion name or an array of assertion names.
; - Currently supported assertions:
; - VerifiedEmail: Asserts that the user has a verified email.
;
; Any other keys in the section should be the names of permission provider services.
; The values associated with these keys will be passed along to the services.
Expand Down Expand Up @@ -75,6 +79,7 @@
; ipRange[] = "1.2.3.7-1.2.5.254"
; insecureCookie = "VUFIND_CUSTOM_COOKIE_NAME"
; permission = sample.permission
; assertion[] = VerifiedEmail
; sessionKey = "VUFIND_SESSION_KEY_NAME"

; Example configuration (grants the "sample.permission" permission to users
Expand Down Expand Up @@ -118,6 +123,13 @@ permission = access.StaffViewTab
role[] = loggedin
permission = feature.Favorites

; This default example configuration allows logged in users
; with verified email addresses to use developer settings.
[default.Developer]
role[] = loggedin
permission = feature.Developer
assertion[] = VerifiedEmail

; Example for dynamic debug mode
;[default.DebugMode]
;username[] = admin
Expand Down
16 changes: 16 additions & 0 deletions module/VuFind/config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
'VuFind\Controller\AjaxController' => 'VuFind\Controller\AjaxControllerFactory',
'VuFind\Controller\AlmaController' => 'VuFind\Controller\AbstractBaseFactory',
'VuFind\Controller\AlphabrowseController' => 'VuFind\Controller\AbstractBaseFactory',
'VuFind\Controller\DeveloperSettingsController' => 'VuFind\Controller\AbstractBaseFactory',
'VuFind\Controller\AuthorController' => 'VuFind\Controller\AbstractBaseFactory',
'VuFind\Controller\AuthorityController' => 'VuFind\Controller\AbstractBaseFactory',
'VuFind\Controller\AuthorityRecordController' => 'VuFind\Controller\AbstractBaseFactory',
Expand Down Expand Up @@ -246,6 +247,8 @@
'alma' => 'VuFind\Controller\AlmaController',
'Alphabrowse' => 'VuFind\Controller\AlphabrowseController',
'alphabrowse' => 'VuFind\Controller\AlphabrowseController',
'DeveloperSettings' => 'VuFind\Controller\DeveloperSettingsController',
'developersettings' => 'VuFind\Controller\DeveloperSettingsController',
'Author' => 'VuFind\Controller\AuthorController',
'author' => 'VuFind\Controller\AuthorController',
'Authority' => 'VuFind\Controller\AuthorityController',
Expand Down Expand Up @@ -424,6 +427,7 @@
'League\CommonMark\MarkdownConverter' => 'VuFind\Service\MarkdownFactory',
'VuFind\Account\UserAccountService' => 'VuFind\Account\UserAccountServiceFactory',
'VuFind\AjaxHandler\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
'VuFind\DeveloperSettings\DeveloperSettingsService' => 'VuFind\DeveloperSettings\DeveloperSettingsServiceFactory',
'VuFind\Auth\EmailAuthenticator' => 'VuFind\Auth\EmailAuthenticatorFactory',
'VuFind\Auth\ILSAuthenticator' => 'VuFind\Auth\ILSAuthenticatorFactory',
'VuFind\Auth\LoginTokenManager' => 'VuFind\Auth\LoginTokenManagerFactory',
Expand Down Expand Up @@ -571,6 +575,7 @@
'VuFindHttp\HttpService' => 'VuFind\Service\HttpServiceFactory',
'VuFindSearch\Service' => 'VuFind\Service\SearchServiceFactory',
'Laminas\Session\SessionManager' => 'VuFind\Session\ManagerFactory',
'Lmc\Rbac\Mvc\Service\AuthorizationService' => 'VuFind\Service\AuthorizationServiceFactory',
],
'delegators' => [
'Laminas\Mvc\I18n\Translator' => [
Expand Down Expand Up @@ -787,6 +792,14 @@
],
],
'vufind_permission_provider_manager' => [ /* see VuFind\Role\PermissionProvider\PluginManager for defaults */ ],
'assertion_manager' => [
'factories' => [
'VuFind\Role\Assertion\HasVerifiedEmailAssertion' => 'Laminas\ServiceManager\Factory\InvokableFactory',
],
'aliases' => [
'VerifiedEmail' => 'VuFind\Role\Assertion\HasVerifiedEmailAssertion',
],
],
],
];

Expand Down Expand Up @@ -889,6 +902,9 @@
'Confirm/Confirm',
'Cover/Show',
'Cover/Unavailable',
'DeveloperSettings/DeleteApiKey',
'DeveloperSettings/DisplaySettings',
'DeveloperSettings/GenerateApiKey',
'EDS/Advanced',
'EDS/Home',
'EDS/Search',
Expand Down
13 changes: 13 additions & 0 deletions module/VuFind/sql/migrations/mysql/11.0/012-add-api-key-table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE TABLE `api_key` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`title` varchar(255) NOT NULL,
`token` varchar(255) NOT NULL,
`revoked` tinyint(1) NOT NULL DEFAULT 0,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `api_key_user_id_idx` (`user_id`),
KEY `api_key_token_idx` (`token`),
CONSTRAINT `api_key_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;
14 changes: 14 additions & 0 deletions module/VuFind/sql/migrations/pgsql/11.0/012-add-api-key-table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CREATE TABLE api_key (
id SERIAL,
user_id int NOT NULL,
title varchar(255) NOT NULL,
token varchar(255) NOT NULL,
revoked boolean NOT NULL DEFAULT '0',
created timestamp NOT NULL default CURRENT_TIMESTAMP,
last_used timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
CREATE INDEX api_key_user_id_idx ON api_key (user_id);
CREATE INDEX api_key_token_idx ON api_key (token);
ALTER TABLE api_key
ADD CONSTRAINT api_key_ibfk_1 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE CASCADE;
21 changes: 21 additions & 0 deletions module/VuFind/sql/mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,27 @@ CREATE TABLE `access_token` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `api_key`
--

/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `api_key` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`title` varchar(255) NOT NULL,
`token` varchar(255) NOT NULL,
`revoked` tinyint(1) NOT NULL DEFAULT 0,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `api_key_user_id_idx` (`user_id`),
KEY `api_key_token_idx` (`token`),
CONSTRAINT `api_key_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
Comment thread
demiankatz marked this conversation as resolved.
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `login_token`
--
Expand Down
21 changes: 21 additions & 0 deletions module/VuFind/sql/pgsql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,21 @@ PRIMARY KEY (id, type)
);
CREATE INDEX access_token_user_id_idx ON access_token (user_id);

DROP TABLE IF EXISTS "api_key";

CREATE TABLE api_key (
id SERIAL,
user_id int NOT NULL,
title varchar(255) NOT NULL,
token varchar(255) NOT NULL,
revoked boolean NOT NULL DEFAULT '0',
created timestamp NOT NULL default CURRENT_TIMESTAMP,
last_used timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
CREATE INDEX api_key_user_id_idx ON api_key (user_id);
CREATE INDEX api_key_token_idx ON api_key (token);

--
-- Table structure for table `login_token`
--
Expand Down Expand Up @@ -614,3 +629,9 @@ ADD CONSTRAINT payment_fee_ibfk_1 FOREIGN KEY (payment_id) REFERENCES "payment"
ALTER TABLE audit_event
ADD CONSTRAINT audit_event_ibfk_1 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE SET NULL,
ADD CONSTRAINT audit_event_ibfk_2 FOREIGN KEY (payment_id) REFERENCES "payment" (id) ON DELETE CASCADE;

---
-- Constraints for table api_key
---
ALTER TABLE api_key
ADD CONSTRAINT api_key_ibfk_1 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE CASCADE;
2 changes: 2 additions & 0 deletions module/VuFind/src/VuFind/Controller/AbstractBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
use Laminas\View\Model\ViewModel;
use VuFind\Config\Feature\EmailSettingsTrait;
use VuFind\Controller\Feature\AccessPermissionInterface;
use VuFind\Controller\Feature\RequestHelperTrait;
use VuFind\Db\Entity\UserEntityInterface;
use VuFind\Db\Service\AuditEventServiceInterface;
use VuFind\Db\Service\PluginManager as DatabaseServiceManager;
Expand Down Expand Up @@ -82,6 +83,7 @@ class AbstractBase extends AbstractActionController implements AccessPermissionI
use EmailSettingsTrait;
use GetServiceTrait;
use TranslatorAwareTrait;
use RequestHelperTrait;

/**
* Permission that must be granted to access this module (false for no
Expand Down
123 changes: 123 additions & 0 deletions module/VuFind/src/VuFind/Controller/DeveloperSettingsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

/**
* Controller for developer settings i.e API keys
*
* PHP version 8
*
* Copyright (C) Villanova University 2025.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see
* <https://www.gnu.org/licenses/>.
*
* @category VuFind
* @package Controller
* @author Juha Luoma <juha.luoma@helsinki.fi>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org Main Site
*/

namespace VuFind\Controller;

use VuFind\DeveloperSettings\DeveloperSettingsService;
use VuFind\Exception\Forbidden;

/**
* Controller for developer settings i.e API keys
*
* @category VuFind
* @package Controller
* @author Juha Luoma <juha.luoma@helsinki.fi>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org Main Site
*/
class DeveloperSettingsController extends AbstractBase
{
/**
* Display developer settings
*
* @return mixed
*/
public function displaySettingsAction()
{
if (!$user = $this->getUser()) {
return $this->forceLogin();
}
$developerSettingsService = $this->getService(DeveloperSettingsService::class);
if (!$developerSettingsService->apiKeysEnabled()) {
throw new Forbidden('Developer settings disabled.');
}
$view = $this->createViewModel();
$view->apiKeys = $developerSettingsService->getApiKeysForUser($user);
$view->createAllowed = !$developerSettingsService->apiKeysBlocked($view->apiKeys);
return $view;
}

/**
* Generate an API key for a user.
*
* @return mixed
*/
public function generateApiKeyAction()
{
if (!$user = $this->getUser()) {
return $this->forceLogin();
}
$developerSettingsService = $this->getService(DeveloperSettingsService::class);
if (!$developerSettingsService->apiKeysEnabled() || !$this->permission()->isAuthorized('feature.Developer')) {
throw new Forbidden('Access denied.');
}

$view = $this->createViewModel();
if ($this->formWasSubmitted()) {
if ($title = $this->getParam('title', true)) {
if ($apiKey = $developerSettingsService->generateApiKeyForUser($user, $title)) {
$successMsg = $this->translate(
'Developer::api_key_generation_success',
['%%TOKEN%%' => $apiKey->getToken()]
);
$this->flashMessenger()->addSuccessMessage($successMsg);
return $view;
}
}
$this->flashMessenger()->addErrorMessage('An error has occurred');
}

return $view;
}

/**
* Delete an API key for a user.
*
* @return mixed
*/
public function deleteApiKeyAction()
{
if (!$user = $this->getUser()) {
return $this->forceLogin();
}
$developerSettingsService = $this->getService(DeveloperSettingsService::class);
if (!$developerSettingsService->apiKeysEnabled() || !$this->permission()->isAuthorized('feature.Developer')) {
throw new Forbidden('Access denied.');
}
if ($this->getParam('confirm') === '1') {
$id = $this->getParam('id');
if ($id && $developerSettingsService->deleteApiKeyForUser($user, $id)) {
$this->flashMessenger()->addSuccessMessage('Developer::api_key_deletion_success');
} else {
$this->flashMessenger()->addErrorMessage('An error has occurred');
}
}
return $this->redirect()->toRoute('developersettings-displaysettings');
}
}
Loading