Skip to content

Commit 0dc27ff

Browse files
authored
Merge branch 'develop' into metadataLanguage-API-call
2 parents fe749bc + ad031a9 commit 0dc27ff

File tree

11 files changed

+166
-98
lines changed

11 files changed

+166
-98
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Suppression of the Host Dataverse field
2+
3+
When creating a dataset, the _host dataverse_ field is not shown when the user can only add datasets to one collection.

doc/sphinx-guides/source/container/dev-usage.rst

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,13 @@ Accessing Harvesting Log Files
145145

146146
\1. Open a terminal and access the Dataverse container.
147147

148-
Run the following command to access the Dataverse container (assuming your container is named dataverse-1):
148+
Run the following command to access the Dataverse container:
149149

150150
.. code-block::
151151
152-
docker exec -it dataverse-1 bash
152+
docker exec -it dev_dataverse bash
153153
154-
This command opens an interactive shell within the dataverse-1 container.
154+
This command opens an interactive shell within the dev_dataverse container.
155155

156156
\2. Navigate to the log files directory.
157157

@@ -233,6 +233,13 @@ Hotswapping methods requires using JDWP (Debug Mode), but does not allow switchi
233233
**Requires IntelliJ Ultimate!**
234234
(Note that `free educational licenses <https://www.jetbrains.com/community/education/>`_ are available)
235235

236+
Go to settings, then plugins. Install "Payara Ultimate Tools". For more information:
237+
238+
- `plugin homepage <https://plugins.jetbrains.com/plugin/15114-payara-ultimate-tools>`_
239+
- `docs <https://docs.payara.fish/community/docs/Technical%20Documentation/Ecosystem/IDE%20Integration/IntelliJ%20Plugin/Overview.html>`_
240+
- `source <https://github.com/payara/ecosystem-intellij-plugin>`_
241+
- `issues <https://github.com/payara/ecosystem-support>`_
242+
236243
.. image:: img/intellij-payara-plugin-install.png
237244

238245
#. Configure a connection to Payara:
@@ -284,6 +291,7 @@ Hotswapping methods requires using JDWP (Debug Mode), but does not allow switchi
284291

285292
You might want to tweak the hot deploy behavior in the "Server" tab now.
286293
"Update action" can be found in the run window (see below).
294+
By default it is "Hot Swap classes", which works fine, but as the screenshot shows you can also change it to "Redeploy".
287295
"Frame deactivation" means switching from IntelliJ window to something else, e.g. your browser.
288296
*Note: static resources like properties, XHTML etc will only update when redeploying!*
289297

@@ -305,7 +313,11 @@ Hotswapping methods requires using JDWP (Debug Mode), but does not allow switchi
305313
See cheat sheet above for more options.
306314
Note that this command either assumes you built the :doc:`app-image` first or will download it from Docker Hub.
307315
.. group-tab:: IntelliJ
308-
You can create a service configuration to automatically start services for you.
316+
Note that you can skip this step if you're ok running the command under the "Maven" tab, which is this:
317+
318+
``mvn -Pct docker:run -Dapp.skipDeploy``
319+
320+
In IntelliJ you can create a service configuration to automatically start services for you.
309321

310322
**IMPORTANT**: This requires installation of the `Docker plugin <https://plugins.jetbrains.com/plugin/7724-docker>`_.
311323

@@ -362,7 +374,7 @@ Hotswapping methods requires using JDWP (Debug Mode), but does not allow switchi
362374

363375
.. image:: img/intellij-payara-run-output.png
364376

365-
Manually hotswap classes in "Debug" mode via "Run" > "Debugging Actions" > "Reload Changed Classes".
377+
Manually hotswap classes in "Debug" mode via "Run" > "Debugging Actions" > "Compile and Reload Modified Files".
366378

367379
.. image:: img/intellij-payara-run-menu-reload.png
368380

doc/sphinx-guides/source/developers/tips.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ Here's an example of using these credentials from within the PostgreSQL containe
124124

125125
.. code-block:: bash
126126
127-
pdurbin@beamish dataverse % docker exec -it postgres-1 bash
127+
pdurbin@beamish dataverse % docker exec -it dev_postgres bash
128128
root@postgres:/# export PGPASSWORD=secret
129129
root@postgres:/# psql -h localhost -U dataverse dataverse
130130
psql (16.3 (Debian 16.3-1.pgdg120+1))

doc/sphinx-guides/source/installation/config.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,23 @@ See the :ref:`payara` section of :doc:`prerequisites` for details and init scrip
115115

116116
Related to this is that you should remove ``/root/.payara/pass`` to ensure that Payara isn't ever accidentally started as root. Without the password, Payara won't be able to start as root, which is a good thing.
117117

118+
.. _payara-ports-localhost-only:
119+
120+
Restricting Payara's Ports to localhost
121+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
122+
123+
In the recommended setup of Dataverse, you do not expose Payara's ports directly to the Internet. Rather, you front Payara with a proxy such as Apache.
124+
125+
If you are running Payara and your proxy on the same server, we recommend having Payara listen only to localhost, which is how your proxy talks to it, with the following command:
126+
127+
``./asadmin set server-config.network-config.network-listeners.network-listener.http-listener-1.address=127.0.0.1``
128+
129+
(You should **NOT** use the configuration option above if you are running in a load-balanced environment, or otherwise have your proxy on a different host than Payara.)
130+
131+
To test that Payara is now only listening on localhost, try hitting port 8080 from the Internet. Payara should not respond.
132+
133+
See also :ref:`network-ports`.
134+
118135
.. _secure-password-storage:
119136

120137
Secure Password Storage
@@ -246,6 +263,8 @@ If you are running an installation with Apache and Payara on the same server, an
246263

247264
You should **NOT** use the configuration option above if you are running in a load-balanced environment, or otherwise have the web server on a different host than the application server.
248265

266+
This security tip is also mentioned at :ref:`payara-ports-localhost-only`.
267+
249268
.. _root-collection-permissions:
250269

251270
Root Dataverse Collection Permissions

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,7 @@
12661266
</image>
12671267
</images>
12681268
<autoCreateCustomNetworks>true</autoCreateCustomNetworks>
1269+
<containerNamePattern>%a</containerNamePattern>
12691270
</configuration>
12701271
</plugin>
12711272
<plugin>

src/main/java/edu/harvard/iq/dataverse/DatasetPage.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package edu.harvard.iq.dataverse;
22

3+
import edu.harvard.iq.dataverse.authorization.DataverseRole;
4+
import edu.harvard.iq.dataverse.engine.command.DataverseRequest;
5+
import edu.harvard.iq.dataverse.globus.Permissions;
36
import edu.harvard.iq.dataverse.provenance.ProvPopupFragmentBean;
47
import edu.harvard.iq.dataverse.api.AbstractApiBean;
58
import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean;
@@ -332,6 +335,7 @@ public enum DisplayMode {
332335
private List<SelectItem> linkingDVSelectItems;
333336
private Dataverse linkingDataverse;
334337
private Dataverse selectedHostDataverse;
338+
private Boolean hasDataversesToChoose;
335339

336340
public Dataverse getSelectedHostDataverse() {
337341
return selectedHostDataverse;
@@ -1781,6 +1785,22 @@ public void setDataverseTemplates(List<Template> dataverseTemplates) {
17811785
this.dataverseTemplates = dataverseTemplates;
17821786
}
17831787

1788+
public boolean isHasDataversesToChoose() {
1789+
1790+
if (this.hasDataversesToChoose == null) {
1791+
var user = this.session.getUser();
1792+
if (!user.isAuthenticated()) {
1793+
this.hasDataversesToChoose = false;
1794+
} else {
1795+
var req = dvRequestService.getDataverseRequest();
1796+
var permissionBit = 1 << Permission.AddDataset.ordinal();
1797+
var authenticatedUser = (AuthenticatedUser) user;
1798+
this.hasDataversesToChoose = permissionService.hasMultiplePermittedCollections(req, authenticatedUser, permissionBit);
1799+
}
1800+
}
1801+
return this.hasDataversesToChoose;
1802+
}
1803+
17841804
public Template getDefaultTemplate() {
17851805
return defaultTemplate;
17861806
}
@@ -2118,6 +2138,10 @@ private String init(boolean initFull) {
21182138

21192139
if (retrieveDatasetVersionResponse != null && !retrieveDatasetVersionResponse.wasRequestedVersionRetrieved()) {
21202140
//msg("checkit " + retrieveDatasetVersionResponse.getDifferentVersionMessage());
2141+
if ("DRAFT".equals(version)) {
2142+
// redirect to the latest published instead:
2143+
return "/dataset.xhtml?persistentId=" + dataset.getGlobalId().asString() + "&faces-redirect=true";
2144+
}
21212145
JsfHelper.addWarningMessage(retrieveDatasetVersionResponse.getDifferentVersionMessage());//BundleUtil.getStringFromBundle("dataset.message.metadataSuccess"));
21222146
}
21232147

src/main/java/edu/harvard/iq/dataverse/DataverseConverter.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,34 @@
1313
import jakarta.faces.convert.Converter;
1414
import jakarta.faces.convert.FacesConverter;
1515

16+
import java.util.logging.Logger;
17+
1618
/**
1719
*
1820
* @author skraffmiller
1921
*/
2022
@FacesConverter("dataverseConverter")
2123
public class DataverseConverter implements Converter {
24+
private static final Logger logger = Logger.getLogger(DataverseConverter.class.getCanonicalName());
25+
2226

2327
//@EJB
2428
DataverseServiceBean dataverseService = CDI.current().select(DataverseServiceBean.class).get();
2529

2630
@Override
2731
public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {
28-
return dataverseService.find(new Long(submittedValue));
32+
if (submittedValue == null || !submittedValue.matches("[0-9]+")) {
33+
logger.fine("Submitted value is not a host dataverse number but: " + submittedValue);
34+
return CDI.current().select(DatasetPage.class).get().getSelectedHostDataverse();
35+
}
36+
else {
37+
try {
38+
return dataverseService.find(Long.parseLong(submittedValue));
39+
} catch (NumberFormatException e) {
40+
logger.warning("Submitted value is out of range for a Long: " + submittedValue);
41+
return CDI.current().select(DatasetPage.class).get().getSelectedHostDataverse();
42+
}
43+
}
2944
//return dataverseService.findByAlias(submittedValue);
3045
}
3146

src/main/java/edu/harvard/iq/dataverse/PermissionServiceBean.java

Lines changed: 76 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -953,96 +953,90 @@ public List<Dataverse> findPermittedCollections(DataverseRequest request, Authen
953953

954954
public List<Dataverse> findPermittedCollections(DataverseRequest request, AuthenticatedUser user, int permissionBit, String searchTerm) {
955955
if (user != null) {
956-
// IP Group - Only check IP if a User is calling for themself
957-
String ipRangeSQL = "FALSE";
958-
if (request != null
959-
&& request.getAuthenticatedUser() != null
960-
&& !request.getAuthenticatedUser().isSuperuser()
961-
&& request.getSourceAddress() != null
962-
&& request.getAuthenticatedUser().getUserIdentifier().equalsIgnoreCase(user.getUserIdentifier())) {
963-
IpAddress ip = request.getSourceAddress();
964-
if (ip instanceof IPv4Address) {
965-
IPv4Address ipv4 = (IPv4Address) ip;
966-
ipRangeSQL = ipv4.toBigInteger() + " BETWEEN ipv4range.bottomaslong AND ipv4range.topaslong";
967-
} else if (ip instanceof IPv6Address) {
968-
IPv6Address ipv6 = (IPv6Address) ip;
969-
long[] vals = ipv6.toLongArray();
970-
if (vals.length == 4) {
971-
ipRangeSQL = """
972-
(@0 BETWEEN ipv6range.bottoma AND ipv6range.topa
973-
AND @1 BETWEEN ipv6range.bottomb AND ipv6range.topb
974-
AND @2 BETWEEN ipv6range.bottomc AND ipv6range.topc
975-
AND @3 BETWEEN ipv6range.bottomd AND ipv6range.topd)
976-
""";
977-
for (int i = 0; i < vals.length; i++) {
978-
ipRangeSQL = ipRangeSQL.replace("@" + i, String.valueOf(vals[i]));
979-
}
980-
}
981-
}
956+
var sqlCode = getBaseQueryForAllPermittedDataverses(request, user, permissionBit);
957+
if (searchTerm == null || searchTerm.isEmpty()) {
958+
return em.createNativeQuery(sqlCode, Dataverse.class).getResultList();
959+
} else if (user.isSuperuser()) {
960+
Query query = em.createNativeQuery(sqlCode.concat(WHERE).concat(SEARCH_PARAMS), Dataverse.class);
961+
setSearchParamValues(searchTerm, query);
962+
return query.getResultList();
982963
}
983-
String sqlCode;
984-
if (user.isSuperuser()) {
985-
sqlCode = LIST_ALL_DATAVERSES_SUPERUSER_HAS_PERMISSION;
986-
987-
if (searchTerm == null || searchTerm.isEmpty()) {
988-
return em.createNativeQuery(sqlCode, Dataverse.class).getResultList();
989-
} else {
990-
sqlCode = LIST_ALL_DATAVERSES_SUPERUSER_HAS_PERMISSION.concat(WHERE).concat(SEARCH_PARAMS);
964+
else {
965+
Query query = em.createNativeQuery(sqlCode.concat(AND).concat(SEARCH_PARAMS), Dataverse.class);
966+
setSearchParamValues(searchTerm, query);
967+
return query.getResultList();
968+
}
969+
}
970+
return null;
971+
}
991972

992-
String pattern = searchTerm.toLowerCase();
993-
String pattern1 = pattern + "%";
994-
String pattern2 = "% " + pattern + "%";
973+
public boolean hasMultiplePermittedCollections(DataverseRequest request, AuthenticatedUser user, int permissionBit) {
974+
if (user != null) {
975+
var sqlCode = getBaseQueryForAllPermittedDataverses(request, user, permissionBit) + " LIMIT 2";
976+
var resultList = em.createNativeQuery(sqlCode, Dataverse.class).getResultList();
977+
return resultList.size() > 1;
978+
}
979+
return false;
980+
}
995981

996-
// Adjust the queries for very short, 1
997-
if (pattern.length() == 1) {
998-
pattern1 = pattern;
999-
pattern2 = pattern + " %";
1000-
}
1001-
Query query = em.createNativeQuery(sqlCode, Dataverse.class);
1002-
query.setParameter(1, "%dataverse");
1003-
query.setParameter(2, pattern1);
1004-
query.setParameter(3, pattern2);
1005-
query.setParameter(4, "%dataverse");
1006-
query.setParameter(5, pattern1);
1007-
query.setParameter(6, pattern2);
1008-
return query.getResultList();
982+
private String getBaseQueryForAllPermittedDataverses(DataverseRequest request, AuthenticatedUser user, int permissionBit) {
983+
if (user.isSuperuser()) {
984+
return LIST_ALL_DATAVERSES_SUPERUSER_HAS_PERMISSION;
985+
} else {
986+
return LIST_ALL_DATAVERSES_USER_HAS_PERMISSION
987+
.replace("@USERID", String.valueOf(user.getId()))
988+
.replace("@PERMISSIONBIT", String.valueOf(permissionBit))
989+
.replace("@IPRANGESQL", getIpRange(request, user));
990+
}
991+
}
1009992

1010-
}
1011-
} else {
1012-
if (searchTerm == null || searchTerm.isEmpty()) {
1013-
sqlCode = LIST_ALL_DATAVERSES_USER_HAS_PERMISSION
1014-
.replace("@USERID", String.valueOf(user.getId()))
1015-
.replace("@PERMISSIONBIT", String.valueOf(permissionBit))
1016-
.replace("@IPRANGESQL", ipRangeSQL);
1017-
return em.createNativeQuery(sqlCode, Dataverse.class).getResultList();
1018-
} else {
1019-
String pattern = searchTerm.toLowerCase();
1020-
String pattern1 = pattern + "%";
1021-
String pattern2 = "% " + pattern + "%";
1022-
1023-
// Adjust the queries for very short, 1
1024-
if (pattern.length() == 1) {
1025-
pattern1 = pattern;
1026-
pattern2 = pattern + " %";
993+
private String getIpRange(DataverseRequest request, AuthenticatedUser user) {
994+
// IP Group - Only check IP if a User is calling for themself
995+
String ipRangeSQL = "FALSE";
996+
if (request != null
997+
&& request.getAuthenticatedUser() != null
998+
&& !request.getAuthenticatedUser().isSuperuser()
999+
&& request.getSourceAddress() != null
1000+
&& request.getAuthenticatedUser().getUserIdentifier().equalsIgnoreCase(user.getUserIdentifier())) {
1001+
IpAddress ip = request.getSourceAddress();
1002+
if (ip instanceof IPv4Address) {
1003+
IPv4Address ipv4 = (IPv4Address) ip;
1004+
ipRangeSQL = ipv4.toBigInteger() + " BETWEEN ipv4range.bottomaslong AND ipv4range.topaslong";
1005+
} else if (ip instanceof IPv6Address) {
1006+
IPv6Address ipv6 = (IPv6Address) ip;
1007+
long[] vals = ipv6.toLongArray();
1008+
if (vals.length == 4) {
1009+
ipRangeSQL = """
1010+
(@0 BETWEEN ipv6range.bottoma AND ipv6range.topa
1011+
AND @1 BETWEEN ipv6range.bottomb AND ipv6range.topb
1012+
AND @2 BETWEEN ipv6range.bottomc AND ipv6range.topc
1013+
AND @3 BETWEEN ipv6range.bottomd AND ipv6range.topd)
1014+
""";
1015+
for (int i = 0; i < vals.length; i++) {
1016+
ipRangeSQL = ipRangeSQL.replace("@" + i, String.valueOf(vals[i]));
10271017
}
1028-
1029-
sqlCode = LIST_ALL_DATAVERSES_USER_HAS_PERMISSION.concat(AND).concat(SEARCH_PARAMS)
1030-
.replace("@USERID", String.valueOf(user.getId()))
1031-
.replace("@PERMISSIONBIT", String.valueOf(permissionBit))
1032-
.replace("@IPRANGESQL", ipRangeSQL);
1033-
1034-
Query query = em.createNativeQuery(sqlCode, Dataverse.class);
1035-
query.setParameter(1, "%dataverse");
1036-
query.setParameter(2, pattern1);
1037-
query.setParameter(3, pattern2);
1038-
query.setParameter(4, "%dataverse");
1039-
query.setParameter(5, pattern1);
1040-
query.setParameter(6, pattern2);
1041-
return query.getResultList();
10421018
}
10431019
}
10441020
}
1045-
return null;
1021+
return ipRangeSQL;
1022+
}
1023+
1024+
private void setSearchParamValues(String searchTerm, Query query) {
1025+
String pattern = searchTerm.toLowerCase();
1026+
String pattern1 = pattern + "%";
1027+
String pattern2 = "% " + pattern + "%";
1028+
1029+
// Adjust the queries for very short, 1
1030+
if (pattern.length() == 1) {
1031+
pattern1 = pattern;
1032+
pattern2 = pattern + " %";
1033+
}
1034+
query.setParameter(1, "%dataverse");
1035+
query.setParameter(2, pattern1);
1036+
query.setParameter(3, pattern2);
1037+
query.setParameter(4, "%dataverse");
1038+
query.setParameter(5, pattern1);
1039+
query.setParameter(6, pattern2);
10461040
}
10471041

10481042
/**

0 commit comments

Comments
 (0)