From a36570af8fb4c0164034a8904cf4b0abdac8b5e2 Mon Sep 17 00:00:00 2001 From: Prakash Sagadevan Date: Mon, 11 Dec 2017 21:48:45 +0530 Subject: [PATCH] Added Basic authentication for Ontology Loader and import wizard --- pom.xml | 10 +- .../src/main/assembly/dependency-sets.xml | 1 + .../src/main/assembly/protege-os-x.xml | 1 + protege-editor-owl/pom.xml | 6 + .../org/protege/editor/owl/OWLEditorKit.java | 5 + .../editor/owl/model/OWLModelManager.java | 7 + .../editor/owl/model/OWLModelManagerImpl.java | 81 ++++++- .../editor/owl/model/io/OntologyLoader.java | 11 + .../repository/MasterOntologyIDExtractor.java | 9 +- .../extractors/LastResortExtractor.java | 95 +++++++- .../BasicAuthenticationDialog.java | 208 ++++++++++++++++++ .../BasicAuthenticationHandler.java | 24 ++ .../ontology/imports/AddImportsStrategy.java | 8 +- .../ontology/imports/wizard/ImportInfo.java | 10 + .../wizard/page/AnticipateOntologyIdPage.java | 16 +- protege-launcher/pom.xml | 5 + 16 files changed, 489 insertions(+), 8 deletions(-) create mode 100644 protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/authentication/BasicAuthenticationDialog.java create mode 100644 protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/authentication/BasicAuthenticationHandler.java diff --git a/pom.xml b/pom.xml index c3ea43a81..45c550026 100644 --- a/pom.xml +++ b/pom.xml @@ -128,7 +128,7 @@ net.sourceforge.owlapi owlapi-osgidistribution - 4.2.8 + 4.2.9 @@ -226,7 +226,13 @@ commons-io 2.4 - + + + commons-codec + commons-codec + 1.9 + + edu.stanford.protege org.protege.xmlcatalog diff --git a/protege-desktop/src/main/assembly/dependency-sets.xml b/protege-desktop/src/main/assembly/dependency-sets.xml index 6874a719f..d9ebc025b 100644 --- a/protege-desktop/src/main/assembly/dependency-sets.xml +++ b/protege-desktop/src/main/assembly/dependency-sets.xml @@ -30,6 +30,7 @@ org.slf4j:log4j-over-slf4j:jar org.slf4j:jul-to-slf4j:jar commons-io:commons-io:jar + commons-codec:commons-codec:jar com.google.inject:guice:jar com.google.inject.extensions:guice-assistedinject:jar com.google.inject.extensions:guice-multibindings:jar diff --git a/protege-desktop/src/main/assembly/protege-os-x.xml b/protege-desktop/src/main/assembly/protege-os-x.xml index 3c433a36f..c8c3702cd 100644 --- a/protege-desktop/src/main/assembly/protege-os-x.xml +++ b/protege-desktop/src/main/assembly/protege-os-x.xml @@ -41,6 +41,7 @@ org.slf4j:log4j-over-slf4j:jar org.slf4j:jul-to-slf4j:jar commons-io:commons-io:jar + commons-codec:commons-codec:jar com.google.inject:guice:jar com.google.inject.extensions:guice-assistedinject:jar com.google.inject.extensions:guice-multibindings:jar diff --git a/protege-editor-owl/pom.xml b/protege-editor-owl/pom.xml index 3b7bf936c..c87ffe36c 100644 --- a/protege-editor-owl/pom.xml +++ b/protege-editor-owl/pom.xml @@ -130,6 +130,12 @@ test + + commons-codec + commons-codec + 1.9 + + diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/OWLEditorKit.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/OWLEditorKit.java index 7d6fc0df2..ae539c6e6 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/OWLEditorKit.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/OWLEditorKit.java @@ -20,6 +20,7 @@ import org.protege.editor.owl.ui.UIHelper; import org.protege.editor.owl.ui.error.OntologyLoadErrorHandlerUI; import org.protege.editor.owl.ui.explanation.ExplanationManager; +import org.protege.editor.owl.ui.ontology.authentication.BasicAuthenticationDialog; import org.protege.editor.owl.ui.ontology.OntologyPreferences; import org.protege.editor.owl.ui.ontology.imports.missing.MissingImportHandlerUI; import org.semanticweb.owlapi.formats.PrefixDocumentFormat; @@ -66,6 +67,8 @@ public class OWLEditorKit extends AbstractEditorKit { private final Set newPhysicalURIs = new HashSet<>(); private final OntologyLoadErrorHandlerUI loadErrorHandler; + + private final BasicAuthenticationDialog basicAuthenticationDialogHandler; private final ServiceRegistration registration; @@ -97,7 +100,9 @@ public OWLEditorKit(@Nonnull OWLEditorKitFactory editorKitFactory) { modelManager.setExplanationManager(new ExplanationManager(this)); modelManager.setMissingImportHandler(new MissingImportHandlerUI(this)); loadErrorHandler = new OntologyLoadErrorHandlerUI(this); + basicAuthenticationDialogHandler = new BasicAuthenticationDialog(this); modelManager.setLoadErrorHandler(loadErrorHandler); + modelManager.setBasicAuthenticationHandler(basicAuthenticationDialogHandler); loadIOListenerPlugins(); diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/OWLModelManager.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/OWLModelManager.java index c4383727f..9422d5634 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/OWLModelManager.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/OWLModelManager.java @@ -17,6 +17,7 @@ import org.protege.editor.owl.ui.explanation.ExplanationManager; import org.protege.editor.owl.ui.renderer.OWLModelManagerEntityRenderer; import org.protege.editor.owl.ui.renderer.OWLObjectRenderer; +import org.protege.editor.owl.ui.ontology.authentication.BasicAuthenticationHandler; import org.protege.xmlcatalog.XMLCatalog; import org.semanticweb.owlapi.model.*; import org.semanticweb.owlapi.reasoner.OWLReasoner; @@ -312,6 +313,12 @@ default void setSaveErrorHandler(SaveErrorHandler handler) { void setLoadErrorHandler(OntologyLoadErrorHandler handler); + + /** + * Set the basic authentication value. + * @param handler + */ + void setBasicAuthenticationHandler(BasicAuthenticationHandler handler); XMLCatalog addRootFolder(File dir); diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/OWLModelManagerImpl.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/OWLModelManagerImpl.java index 467b1d653..d27703534 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/OWLModelManagerImpl.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/OWLModelManagerImpl.java @@ -37,6 +37,7 @@ import org.protege.editor.owl.ui.explanation.ExplanationManager; import org.protege.editor.owl.ui.renderer.*; import org.protege.editor.owl.ui.renderer.plugin.RendererPlugin; +import org.protege.editor.owl.ui.ontology.authentication.BasicAuthenticationHandler; import org.protege.xmlcatalog.XMLCatalog; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.formats.RDFXMLDocumentFormat; @@ -130,6 +131,8 @@ public class OWLModelManagerImpl extends AbstractModelManager implements OWLMode // error handlers private OntologyLoadErrorHandler loadErrorHandler; + + private BasicAuthenticationHandler basicAuthenticationHandler; private final UserResolvedIRIMapper userResolvedIRIMapper = new UserResolvedIRIMapper(new MissingImportHandlerImpl()); @@ -273,11 +276,63 @@ public boolean loadOntologyFromPhysicalURI(URI uri) { return loadedOntology.isPresent(); } catch (OWLOntologyCreationException e) { OWLOntologyID id = new OWLOntologyID(com.google.common.base.Optional.of(IRI.create(uri)), com.google.common.base.Optional.absent()); - handleLoadError(id, uri, e); + // Check error message contain HTTP response code: 401 or 403 status then show the popup for basic authentication + if (e.getMessage().contains("Server returned HTTP response code: 401") || e.getMessage().contains("Server returned HTTP response code: 403")) { + logger.info(e.getMessage()); + String authenticationValue = handleBasicAuthentication(id, uri, e); + if (authenticationValue != null) { + return loadOntologyFromPhysicalURIWithAuthentication(uri, authenticationValue); + } else { + handleLoadError(id, uri, e); + } + } else { + handleLoadError(id, uri, e); + } + return false; + } + } + + /** + * A convenience method that loads an ontology from a file The location of + * the file is specified by the URI argument with basic authentication value. + */ + public boolean loadOntologyFromPhysicalURIWithAuthentication(URI uri, String authenticationValue) { + Stopwatch stopwatch = Stopwatch.createUnstarted(); + try { + logger.info(LogBanner.start("Loading Ontology")); + logger.info("Loading ontology from {}", uri); + stopwatch.start(); + if (UIUtil.isLocalFile(uri)) { + // Load the URIs of other ontologies that are contained in the same folder. + File parentFile = new File(uri).getParentFile(); + addRootFolder(parentFile); + } + OntologyLoader loader = new OntologyLoader(this, userResolvedIRIMapper,authenticationValue); + Optional loadedOntology = loader.loadOntology(uri); + logger.info("Loading for ontology and imports closure successfully completed in {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS)); + loadedOntology.ifPresent(ontology -> { + DocumentFormatUpdater formatUpdater = new DocumentFormatUpdater(new DocumentFormatMapper()); + formatUpdater.updateFormat(ontology); + }); + logger.info(LogBanner.end()); + return loadedOntology.isPresent(); + } catch (OWLOntologyCreationException e) { + OWLOntologyID id = new OWLOntologyID(com.google.common.base.Optional.of(IRI.create(uri)), com.google.common.base.Optional.absent()); + // Check error message contain HTTP response code: 401 or 403 status then show the popup for basic authentication + if (e.getMessage().contains("Server returned HTTP response code: 401") || e.getMessage().contains("Server returned HTTP response code: 403")) { + logger.info(e.getMessage()); + String base64AuthenticationValue = handleBasicAuthentication(id, uri, e); + if (base64AuthenticationValue != null) { + return loadOntologyFromPhysicalURIWithAuthentication(uri, base64AuthenticationValue); + } else { + handleLoadError(id, uri, e); + } + } else { + handleLoadError(id, uri, e); + } return false; } } - public void startedLoadingOntology(@Nonnull LoadingStartedEvent event) { logger.info("Loading {} from {}", event.getOntologyID(), event.getDocumentIRI()); @@ -302,6 +357,18 @@ private void handleLoadError(OWLOntologyID owlOntologyID, URI documentURI, Excep } } } + + private String handleBasicAuthentication(OWLOntologyID owlOntologyID, URI documentURI, Exception e) { + if (basicAuthenticationHandler != null) { + try { + return basicAuthenticationHandler.handleBasicAuthenticationOntology(owlOntologyID, documentURI, e); + } catch (Throwable e1) { + // if, for any reason, the loadErrorHandler cannot report the error + ErrorLogPanel.showErrorDialog(e1); + } + } + return null; + } public XMLCatalog addRootFolder(File dir) { return ontologyCatalogManager.addFolder(dir); @@ -958,6 +1025,16 @@ public void setMissingImportHandler(MissingImportHandler missingImportHandler) { public void setLoadErrorHandler(OntologyLoadErrorHandler handler) { this.loadErrorHandler = handler; } + + ////////////////////////////////////////////////////////////////////////////////////// + // + // Basic Authentication handling + // + ////////////////////////////////////////////////////////////////////////////////////// + public void setBasicAuthenticationHandler(BasicAuthenticationHandler handler) { + this.basicAuthenticationHandler = handler; + } + } diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/io/OntologyLoader.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/io/OntologyLoader.java index 940d28b6f..cd426f8a9 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/io/OntologyLoader.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/io/OntologyLoader.java @@ -35,6 +35,8 @@ public class OntologyLoader { private final OWLModelManager modelManager; private final UserResolvedIRIMapper userResolvedIRIMapper; + + private String authenticationValue = null; private final ProgressDialog dlg = new ProgressDialog(); @@ -46,6 +48,12 @@ public OntologyLoader(OWLModelManager modelManager, UserResolvedIRIMapper userRe this.modelManager = modelManager; this.userResolvedIRIMapper = userResolvedIRIMapper; } + + public OntologyLoader(OWLModelManager modelManager, UserResolvedIRIMapper userResolvedIRIMapper,String authenticationValue) { + this.modelManager = modelManager; + this.userResolvedIRIMapper = userResolvedIRIMapper; + this.authenticationValue = authenticationValue; + } public Optional loadOntology(URI documentUri) throws OWLOntologyCreationException { if (!SwingUtilities.isEventDispatchThread()) { @@ -99,6 +107,9 @@ private Optional loadOntologyInternal(URI documentURI) throws OWLOn loadingManager.addOntologyLoaderListener(new ProgressDialogOntologyLoaderListener(dlg, logger)); OWLOntologyLoaderConfiguration configuration = new OWLOntologyLoaderConfiguration(); configuration = configuration.setMissingImportHandlingStrategy(MissingImportHandlingStrategy.SILENT); + if(authenticationValue != null && !authenticationValue.isEmpty()) { + configuration = configuration.setAuthorizationValue(authenticationValue); + } IRIDocumentSource documentSource = new IRIDocumentSource(IRI.create(documentURI)); OWLOntology ontology = loadingManager.loadOntologyFromOntologyDocument(documentSource, configuration); Set alreadyLoadedOntologies = new HashSet<>(); diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/repository/MasterOntologyIDExtractor.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/repository/MasterOntologyIDExtractor.java index d7beeb3a9..8009274c6 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/repository/MasterOntologyIDExtractor.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/repository/MasterOntologyIDExtractor.java @@ -4,6 +4,8 @@ import org.protege.editor.owl.model.repository.extractors.LastResortExtractor; import org.protege.editor.owl.model.repository.extractors.OntologyIdExtractor; import org.protege.editor.owl.model.repository.extractors.RdfXmlExtractor; +import org.protege.editor.owl.ui.error.OntologyLoadErrorHandlerUI; +import org.protege.editor.owl.ui.ontology.authentication.BasicAuthenticationDialog; import org.semanticweb.owlapi.model.OWLOntologyID; import java.net.URI; @@ -15,10 +17,15 @@ public class MasterOntologyIDExtractor implements OntologyIdExtractor { private List extractors = new ArrayList<>(); // TODO - all the callers of this method have problems which need fixing. - public MasterOntologyIDExtractor() { + public MasterOntologyIDExtractor() { extractors.add(new RdfXmlExtractor()); extractors.add(new LastResortExtractor()); } + + public MasterOntologyIDExtractor(BasicAuthenticationDialog basicAuthenticationDialogHandler, OntologyLoadErrorHandlerUI ontologyLoadErrorHandler) { + extractors.add(new RdfXmlExtractor()); + extractors.add(new LastResortExtractor(basicAuthenticationDialogHandler, ontologyLoadErrorHandler)); + } public Optional getOntologyId(URI location) { Optional id = Optional.absent(); diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/repository/extractors/LastResortExtractor.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/repository/extractors/LastResortExtractor.java index caa377ca8..78cfcaf93 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/repository/extractors/LastResortExtractor.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/repository/extractors/LastResortExtractor.java @@ -1,29 +1,122 @@ package org.protege.editor.owl.model.repository.extractors; import com.google.common.base.Optional; +import org.protege.editor.core.ui.error.ErrorLogPanel; +import org.protege.editor.owl.ui.error.OntologyLoadErrorHandler; +import org.protege.editor.owl.ui.error.OntologyLoadErrorHandlerUI; +import org.protege.editor.owl.ui.ontology.authentication.BasicAuthenticationDialog; +import org.protege.editor.owl.ui.ontology.authentication.BasicAuthenticationHandler; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLOntologyID; import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.model.MissingImportHandlingStrategy; +import org.semanticweb.owlapi.model.OWLOntologyLoaderConfiguration; +import org.semanticweb.owlapi.io.IRIDocumentSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URI; + public class LastResortExtractor implements OntologyIdExtractor { private Logger log = LoggerFactory.getLogger(LastResortExtractor.class); + + private BasicAuthenticationHandler basicAuthenticationHandler; + + private OntologyLoadErrorHandler loadErrorHandler; + + public LastResortExtractor() { + } + + public LastResortExtractor(BasicAuthenticationDialog basicAuthenticationDialogHandler, OntologyLoadErrorHandlerUI ontologyLoadErrorHandler) { + this.basicAuthenticationHandler = basicAuthenticationDialogHandler; + this.loadErrorHandler = ontologyLoadErrorHandler; + } public Optional getOntologyId(URI location) { OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); try { OWLOntology ontology = manager.loadOntologyFromOntologyDocument(IRI.create(location)); return Optional.of(ontology.getOntologyID()); + } catch (Throwable t) { + log.info("Exception caught trying to get ontology id for " + location, t); + OWLOntologyID id = new OWLOntologyID(com.google.common.base.Optional.of(IRI.create(location)), com.google.common.base.Optional.absent()); + // Check error message contain HTTP response code: 401 or 403 status then show the popup for basic authentication + if (t.getMessage().contains("Server returned HTTP response code: 401") || t.getMessage().contains("Server returned HTTP response code: 403")) { + String base64AuthenticationValue = handleBasicAuthentication(id, location, (Exception) t); + + if (base64AuthenticationValue != null) { + return getOntologyId(location, base64AuthenticationValue); + } else { + handleLoadError(id, location, (Exception) t); + } + } else { + handleLoadError(id, location, (Exception) t); + } + return null; } - catch (Throwable t) { + } + + public Optional getOntologyId(URI location, String authenticationValue) { + OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); + try { + OWLOntologyLoaderConfiguration configuration = new OWLOntologyLoaderConfiguration(); + configuration = configuration.setMissingImportHandlingStrategy(MissingImportHandlingStrategy.SILENT); + if (authenticationValue != null && !authenticationValue.isEmpty()) { + configuration = configuration.setAuthorizationValue(authenticationValue); + } + IRIDocumentSource documentSource = new IRIDocumentSource(IRI.create(location)); + OWLOntology ontology = manager.loadOntologyFromOntologyDocument(documentSource, configuration); + return Optional.of(ontology.getOntologyID()); + } catch (Throwable t) { log.info("Exception caught trying to get ontology id for " + location, t); + OWLOntologyID id = new OWLOntologyID(com.google.common.base.Optional.of(IRI.create(location)), com.google.common.base.Optional.absent()); + // Check error message contain HTTP response code: 401 or 403 status then show the popup for basic authentication + if (t.getMessage().contains("Server returned HTTP response code: 401") || t.getMessage().contains("Server returned HTTP response code: 403")) { + String base64AuthenticationValue = handleBasicAuthentication(id, location, (Exception) t); + if (base64AuthenticationValue != null) { + return getOntologyId(location, base64AuthenticationValue); + } else { + handleLoadError(id, location, (Exception) t); + } + } else { + handleLoadError(id, location, (Exception) t); + } return null; } } + + private String handleBasicAuthentication(OWLOntologyID owlOntologyID, URI documentURI, Exception e) { + if (basicAuthenticationHandler != null) { + try { + return basicAuthenticationHandler.handleBasicAuthenticationOntology(owlOntologyID, documentURI, e); + } catch (Throwable e1) { + // if, for any reason, the loadErrorHandler cannot report the error + ErrorLogPanel.showErrorDialog(e1); + } + } + return null; + } + + private void handleLoadError(OWLOntologyID owlOntologyID, URI documentURI, Exception e) { + if (loadErrorHandler != null) { + try { + loadErrorHandler.handleErrorLoadingOntology(owlOntologyID, documentURI, e); + } catch (Throwable e1) { + // if, for any reason, the loadErrorHandler cannot report the error + ErrorLogPanel.showErrorDialog(e1); + } + } + } + + public void setLoadErrorHandler(OntologyLoadErrorHandler handler) { + this.loadErrorHandler = handler; + } + + public void setBasicAuthenticationHandler(BasicAuthenticationHandler handler) { + this.basicAuthenticationHandler = handler; + } } diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/authentication/BasicAuthenticationDialog.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/authentication/BasicAuthenticationDialog.java new file mode 100644 index 000000000..d4e57ba44 --- /dev/null +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/authentication/BasicAuthenticationDialog.java @@ -0,0 +1,208 @@ +package org.protege.editor.owl.ui.ontology.authentication; + +import java.awt.BorderLayout; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import org.apache.commons.codec.binary.Base64; +import org.protege.editor.core.ui.util.InputVerificationStatusChangedListener; +import org.protege.editor.core.ui.util.VerifiedInputEditor; +import org.protege.editor.owl.OWLEditorKit; +import org.protege.editor.owl.ui.UIHelper; +import org.semanticweb.owlapi.model.OWLOntologyID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BasicAuthenticationDialog implements BasicAuthenticationHandler { + + private OWLEditorKit owlEditorKit; + + private String savedBasicAuthenticationString; + + public BasicAuthenticationDialog(OWLEditorKit owlEditorKit) { + this.owlEditorKit = owlEditorKit; + this.savedBasicAuthenticationString = null; + } + + @Override + public String handleBasicAuthenticationOntology(OWLOntologyID ontologyID, URI loc, T e) throws Throwable { + AuthenticationPanel panel = new AuthenticationPanel(); + int ret1 = new UIHelper(owlEditorKit).showValidatingDialog( + "Basic Authentication", + panel, + panel.userNameField); + if (ret1 == JOptionPane.OK_OPTION) { + this.setSavedBasicAuthenticationString(panel.getBasicAuthenticationString()); + return savedBasicAuthenticationString; + } else { + return null; + } + } + + public String getSavedBasicAuthenticationString() { + return savedBasicAuthenticationString; + } + + public void setSavedBasicAuthenticationString(String savedBasicAuthenticationString) { + this.savedBasicAuthenticationString = savedBasicAuthenticationString; + } + + public class AuthenticationPanel extends JPanel implements VerifiedInputEditor { + + private String username, password; + + private JPanel authenticationPanel; + + private JTextField userNameField; + + private JPasswordField passwordField; + + private List listeners + = new ArrayList<>(); + + private boolean currentlyValid = true; + + public AuthenticationPanel() { + createUI(); + } + + private void createUI() { + setLayout(new BorderLayout()); + JPanel holder = new JPanel(new GridBagLayout()); + add(holder); + Insets insets = new Insets(0, 0, 2, 4); + + int rowIndex = 0; + + JLabel usernameLabel = new JLabel("Username:"); + holder.add(usernameLabel, new GridBagConstraints(0, rowIndex, 1, 1, 0.0, 0.0, GridBagConstraints.BASELINE_TRAILING, GridBagConstraints.NONE, insets, 0, 0)); + usernameLabel.setFont(usernameLabel.getFont().deriveFont(Font.BOLD)); + + userNameField = new JTextField(30); + userNameField.getDocument().addDocumentListener(new DocumentListener() { + public void insertUpdate(DocumentEvent e) { + update(); + } + + public void removeUpdate(DocumentEvent e) { + update(); + } + + public void changedUpdate(DocumentEvent e) { + } + }); + + holder.add(userNameField, new GridBagConstraints(1, rowIndex, 1, 1, 100.0, 0.0, GridBagConstraints.BASELINE_LEADING, GridBagConstraints.HORIZONTAL, insets, 0, 0)); + + rowIndex++; + JLabel passwordLabel = new JLabel("Password:"); + holder.add(passwordLabel, new GridBagConstraints(0, rowIndex, 1, 1, 0.0, 0.0, GridBagConstraints.BASELINE_TRAILING, GridBagConstraints.NONE, insets, 0, 0)); + passwordLabel.setFont(passwordLabel.getFont().deriveFont(Font.BOLD)); + + passwordField = new JPasswordField(30); + passwordField.getDocument().addDocumentListener(new DocumentListener() { + public void insertUpdate(DocumentEvent e) { + update(); + } + + public void removeUpdate(DocumentEvent e) { + update(); + } + + public void changedUpdate(DocumentEvent e) { + } + }); + holder.add(passwordField, new GridBagConstraints(1, rowIndex, 1, 1, 100.0, 0.0, GridBagConstraints.BASELINE_TRAILING, GridBagConstraints.HORIZONTAL, insets, 0, 0)); + + holder.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + update(); + } + + public void setEnabled(boolean b) { + userNameField.setEnabled(b); + passwordField.setEditable(b); + super.setEnabled(b); + } + + public void setUserName(String name) { + userNameField.setText(name); + } + + public void setPassword(String password) { + passwordField.setText(password); + } + + public String getEntityUsername() { + return userNameField.getText().trim(); + } + + public String getEntityPassword() { + return new String(passwordField.getPassword()); + } + + @Override + public void addStatusChangedListener(InputVerificationStatusChangedListener listener) { + listeners.add(listener); + listener.verifiedStatusChanged(currentlyValid); + } + + @Override + public void removeStatusChangedListener(InputVerificationStatusChangedListener listener) { + listeners.remove(listener); + } + + private void update() { + try { + + if (userNameField.getText().trim().isEmpty()) { + setValid(false); + return; + } + if (getEntityPassword().trim().isEmpty()) { + setValid(false); + return; + } + + setValid(true); + } catch (RuntimeException e) { + setValid(false); + throw e; + } + + } + + private void setValid(boolean valid) { + currentlyValid = valid; + fireVerificationStatusChanged(); + } + + private void fireVerificationStatusChanged() { + for (InputVerificationStatusChangedListener l : listeners) { + l.verifiedStatusChanged(currentlyValid); + } + } + + private String getBasicAuthenticationString() { + username = this.getEntityUsername(); + password = this.getEntityPassword(); + String authString = username + ":" + password; + byte[] authEncBytes = Base64.encodeBase64(authString.getBytes()); + String authStringEnc = new String(authEncBytes); + String basicAuth = "Basic " + authStringEnc; + return basicAuth; + } + } +} diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/authentication/BasicAuthenticationHandler.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/authentication/BasicAuthenticationHandler.java new file mode 100644 index 000000000..ecd7f764c --- /dev/null +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/authentication/BasicAuthenticationHandler.java @@ -0,0 +1,24 @@ +package org.protege.editor.owl.ui.ontology.authentication; + +import java.awt.BorderLayout; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.net.URI; +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import org.apache.commons.codec.binary.Base64; +import org.protege.editor.owl.OWLEditorKit; +import org.protege.editor.owl.ui.UIHelper; +import org.semanticweb.owlapi.model.OWLOntologyID; + +public interface BasicAuthenticationHandler { + + String handleBasicAuthenticationOntology(OWLOntologyID ontologyID, URI loc, T e) throws Throwable; + +} diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/AddImportsStrategy.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/AddImportsStrategy.java index 2f3c2cbff..2fcf79a09 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/AddImportsStrategy.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/AddImportsStrategy.java @@ -99,9 +99,15 @@ private List loadImportsInternal() { .add(man.getIRIMappers()); ProgressDialogOntologyLoaderListener listener = new ProgressDialogOntologyLoaderListener(dlg, logger); loadingManager.addOntologyLoaderListener(listener); - loadingManager.loadOntologyFromOntologyDocument( + if(importParameters.getBasicAuthentication() != null && !importParameters.getBasicAuthentication().isEmpty()) { + loadingManager.loadOntologyFromOntologyDocument( + new IRIDocumentSource(IRI.create(physicalLocation)), + new OWLOntologyLoaderConfiguration().setMissingImportHandlingStrategy(MissingImportHandlingStrategy.SILENT).setAuthorizationValue(importParameters.getBasicAuthentication())); + } else { + loadingManager.loadOntologyFromOntologyDocument( new IRIDocumentSource(IRI.create(physicalLocation)), new OWLOntologyLoaderConfiguration().setMissingImportHandlingStrategy(MissingImportHandlingStrategy.SILENT)); + } loadingManager.removeOntologyLoaderListener(listener); // editorKit.getModelManager().fireEvent(EventType.ONTOLOGY_LOADED); for(OWLOntology importedOntology : loadingManager.getOntologies()) { diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/wizard/ImportInfo.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/wizard/ImportInfo.java index a6bf776b0..4d6813ba9 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/wizard/ImportInfo.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/wizard/ImportInfo.java @@ -23,6 +23,8 @@ public class ImportInfo { private URI physicalLocation; private IRI importLocation; + + private String basicAuthentication; public OWLOntologyID getOntologyID() { return ontologyID; @@ -47,6 +49,14 @@ public IRI getImportLocation() { public void setImportLocation(IRI importLocation) { this.importLocation = importLocation; } + + public String getBasicAuthentication() { + return basicAuthentication; + } + + public void setBasicAuthentication(String basicAuthentication) { + this.basicAuthentication = basicAuthentication; + } public boolean isReady() { return importLocation != null && ontologyID != null & physicalLocation != null; diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/wizard/page/AnticipateOntologyIdPage.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/wizard/page/AnticipateOntologyIdPage.java index 19b270e19..9d48246ee 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/wizard/page/AnticipateOntologyIdPage.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/ontology/imports/wizard/page/AnticipateOntologyIdPage.java @@ -6,8 +6,10 @@ import org.protege.editor.owl.model.library.folder.XmlBaseAlgorithm; import org.protege.editor.owl.model.repository.MasterOntologyIDExtractor; import org.protege.editor.owl.ui.AbstractOWLWizardPanel; +import org.protege.editor.owl.ui.error.OntologyLoadErrorHandlerUI; import org.protege.editor.owl.ui.ontology.imports.wizard.ImportInfo; import org.protege.editor.owl.ui.ontology.imports.wizard.OntologyImportWizard; +import org.protege.editor.owl.ui.ontology.authentication.BasicAuthenticationDialog; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLOntologyID; import org.slf4j.LoggerFactory; @@ -38,9 +40,16 @@ public class AnticipateOntologyIdPage extends AbstractOWLWizardPanel { private JProgressBar progressBar; private Runnable checker; + + private BasicAuthenticationDialog basicAuthenticationDialogHandler; + + private OntologyLoadErrorHandlerUI loadErrorHandler; + + private final OWLEditorKit owlEditorKit; public AnticipateOntologyIdPage(OWLEditorKit owlEditorKit) { super(ID, "Import verification", owlEditorKit); + this.owlEditorKit = owlEditorKit; checker = () -> checkImport(); } @@ -105,10 +114,15 @@ protected void checkImport() { continue; } try { - MasterOntologyIDExtractor extractor = new MasterOntologyIDExtractor(); + basicAuthenticationDialogHandler = new BasicAuthenticationDialog(owlEditorKit); + loadErrorHandler = new OntologyLoadErrorHandlerUI(owlEditorKit); + MasterOntologyIDExtractor extractor = new MasterOntologyIDExtractor(basicAuthenticationDialogHandler, loadErrorHandler); Optional id = extractor.getOntologyId(parameters.getPhysicalLocation()); if (id.isPresent()) { parameters.setOntologyID(id.get()); + if(basicAuthenticationDialogHandler.getSavedBasicAuthenticationString() != null && !basicAuthenticationDialogHandler.getSavedBasicAuthenticationString().isEmpty()) { + parameters.setBasicAuthentication(basicAuthenticationDialogHandler.getSavedBasicAuthenticationString()); + } } else { parameters.setOntologyID(null); diff --git a/protege-launcher/pom.xml b/protege-launcher/pom.xml index 6b3c77653..67396da99 100644 --- a/protege-launcher/pom.xml +++ b/protege-launcher/pom.xml @@ -92,6 +92,11 @@ commons-io + + commons-codec + commons-codec + + junit junit