Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

integrate work for vault transfer negotiation and magic preauth keys #547

Merged
merged 12 commits into from
Dec 19, 2023
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
************************************************************************
*/

package org.opencadc.vault;
package org.opencadc.inventory.transfer;

import ca.nrc.cadc.rest.InlineContentHandler;
import ca.nrc.cadc.rest.RestAction;
Expand All @@ -77,7 +77,9 @@
import org.opencadc.inventory.PreauthKeyPair;

/**
*
* Simple GET action that finds a PreauthKeyPair via JNDI and writes
* the binary public key to the output.
*
* @author pdowler
*/
public class GetKeyAction extends RestAction {
Expand All @@ -97,9 +99,9 @@ public void doAction() throws Exception {
String jndiPreauthKeys = appName + "-" + PreauthKeyPair.class.getName();
Context ctx = new InitialContext();
try {
log.warn("lookup: " + jndiPreauthKeys);
log.debug("lookup: " + jndiPreauthKeys);
PreauthKeyPair keys = (PreauthKeyPair) ctx.lookup(jndiPreauthKeys);
log.warn("found: " + keys);
log.debug("found: " + keys);
byte[] pub = keys.getPublicKey();
syncOutput.setHeader("content-length", pub.length);
syncOutput.setHeader("content-type", "application/octet-stream");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,19 +330,31 @@ List<Protocol> doPullFrom(URI artifactURI, Transfer transfer, String authToken)

List<Protocol> protos = new ArrayList<>();
Artifact artifact = artifactDAO.get(artifactURI);
// produce URLs to each of the copies for each of the protocols
List<StorageSite> storageSites = new ArrayList<>();

if (artifact == null) {
if (this.preventNotFound) {
log.debug("Artifact " + artifactURI.toASCIIString() + " not found in global. Check sites.");
artifact = getUnsyncedArtifact(artifactURI, transfer, sites, authToken);
}
}

List<StorageSite> storageSites = new ArrayList<>();
if (artifact != null) {
for (SiteLocation site : artifact.siteLocations) {
StorageSite storageSite = getSite(sites, site.getSiteID());
storageSites.add(storageSite);
if (artifact.storageLocation != null) {
// this is a single storage site
Iterator<StorageSite> iter = sites.iterator();
if (iter.hasNext()) {
storageSites.add(iter.next());
}
if (iter.hasNext()) {
log.error("BUG: found second StorageSite in database with assigned Artifact.storageLocation");
}
} else {
// this is a global inventory
for (SiteLocation site : artifact.siteLocations) {
StorageSite storageSite = getSite(sites, site.getSiteID());
storageSites.add(storageSite);
}
}
}

Expand Down Expand Up @@ -383,7 +395,7 @@ List<Protocol> doPullFrom(URI artifactURI, Transfer transfer, String authToken)
log.debug("added: " + p);

// add a plain anon URL
if (authToken != null && Standards.SECURITY_METHOD_ANON.equals(sec)) {
if (authToken != null && !requirePreauthAnon && Standards.SECURITY_METHOD_ANON.equals(sec)) {
sb = new StringBuilder();
sb.append(baseURL.toExternalForm()).append("/");
sb.append(artifactURI.toASCIIString());
Expand Down Expand Up @@ -426,10 +438,8 @@ List<Protocol> doPullFrom(URI artifactURI, Transfer transfer, String authToken)
}
}

if (protos.isEmpty() && ((artifact == null) || artifact.siteLocations.size() == 0)) {
// artifact not find internally and has no external resolvers either
// TODO: second condition can currently happen but maybe should not:
// --- when the last siteLocation is removed, the artifact should be deleted (fenwick, ratik)
if (protos.isEmpty()) {
// unable to generate any URLs
throw new ResourceNotFoundException("not found: " + artifactURI.toString());
}

Expand Down
17 changes: 14 additions & 3 deletions minoc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,27 @@ currently must be "inventory" due to configuration limitations in <a href="../lu

The following keys are optional:
```
# public key to validate pre-auth URLs generated by another service
org.opencadc.minoc.publicKeyFile={public key file from raven}
# services that are trusted to generate pre-auth URLs
org.opencadc.minoc.trust.preauth = {resourceID}

# permission granting services (optional)
org.opencadc.minoc.readGrantProvider={resourceID of a permission granting service}
org.opencadc.minoc.writeGrantProvider={resourceID of a permission granting service}

# configure StorageAdapter delete behaviour
org.opencadc.minoc.recoverableNamespace = {namespace}
```
The _publicKeyFile_ (optional) is the the key used to decode pre-authorization information in request URLs generated by <a href="../raven">raven</a>.
The optional _trust.preauth_ key(s) configure `minoc` to trust an external service to have performed
authorization checks. Such services may include a signed token in the URL and `minoc` will validate
the request using a public key retrieved from the service instead of performing authorization checks
itself. Example:
```
# trust a SI global inventory
org.opencadc.minoc.trust.preauth = ivo://example.net/raven

# trust a SI VOSpace service
org.opencadc.minoc.trust.preauth = ivo://example.net/vault
```

The optional _readGrantProvider_ and _writeGrantProvider_ keys configure minoc to call other services to get grants (permissions) for
operations. Multiple values of the granting service resourceID(s) may be provided by including multiple property
Expand Down
Loading
Loading