Skip to content

Commit

Permalink
OAuth refactoring
Browse files Browse the repository at this point in the history
* Defer initializing default Google oAuth until needed
* Support multiple oAuth configurations as an array in oauth-config.json.  e.g. an Azure and Amazon config
  • Loading branch information
jrobinso committed Sep 12, 2023
1 parent ee5ea52 commit 4994be2
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 136 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ out/
/test/batch/snapshots/
/src/main/java/org/broad/igv/sam/mods/BMScale.java
/src/main/java/org/broad/igv/sam/mods/BMScale.form
/ignore/
11 changes: 5 additions & 6 deletions examples/oauth/oauth-config-amazon.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
{
"client_id": "3f4ujenfmr77tg12idlkebpkoh",
"client_secret": "en1q6638m4dogrr6erhrmitim67sjilc6htjnfmf6ljk2q3j9og",
"apiKey": "",
"project_id": "igv",
"auth_provider": "Amazon",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"aws_region": "ap-southeast-2",
"scope": "email%20openid%20profile",
"redirect_uris": [
"http://localhost:60151/oauthCallback"
],
"client_id": "3f4ujenfmr77tg12iofbebpkoh",
"client_secret": "en1q6638m4dogrr6erhosetim67sjilc6htjnfmf6ljk2q3j9og",
"authorization_endpoint": "https://igv-demo.auth.ap-southeast-2.amazoncognito.com/login",
"token_endpoint": "https://igv-demo.auth.ap-southeast-2.amazoncognito.com/token",
"aws_cognito_fed_pool_id": "ap-southeast-2:15b7bf93-18ca-40d5-99e9-38b4eb69363e",
"aws_cognito_pool_id": "ap-southeast-2_IYMvlZzmv",
"aws_cognito_role_arn": "arn:aws:iam::YOUR_AWS_ACCOUNT:role/YOUR_Cognito_igvAuth_Role"
}
}
10 changes: 3 additions & 7 deletions examples/oauth/oauth-config-google.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
{
"client_id": "661332306814-gb4r480jnb6rres3iv8a5f48dms5ququu.apps.googleusercontent.com",
"client_secret": "MFqdc7apizmtb8n08Ze810V6",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"redirect_uris": [
"http://localhost:60151/oauthCallback"
],
"hosts": ["www.googleapis.com", "storage.cloud.google.com", "storage.googleapis.com"]
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs"
}
12 changes: 6 additions & 6 deletions examples/oauth/oauth-config-microsoft.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"client_id": "hbq82djj-qwer-7iub-j7zq-7i8nv72n48nq",
"client_secret": "cVAX64fXRikCLmtAow/cktrAtaHz/tmB3WHKhnbXN2Gq",
"authorization_endpoint": "https://login.microsoftonline.com/77nwe2q2-e53r-uq2p-7vdh-9z7px83zmtiv/oauth2/authorize",
"token_endpoint": "https://login.microsoftonline.com/77nwe2q2-e53r-wk32-7vdh-9z7px83zmtiv/oauth2/token",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"authorization_endpoint": "https://login.microsoftonline.com/.../oauth2/authorize",
"token_endpoint": "https://login.microsoftonline.com/.../oauth2/token",
"hosts": ["prod_host.mayo.edu", "dev_host.mayo.edu", "int_host.mayo.edu"],
"auth_provider": "Mayo Clinic",
"app_id_uri": "https://orgtools.onmicrosoft.com/6q9qk3mr-pu78-eu73-vx5a-nqw2aqidutm9",
"auth_provider": "YOUR PROVIDER",
"app_id_uri": "https://orgtools.onmicrosoft.com/...",
"scope": "openid"
}

42 changes: 10 additions & 32 deletions src/main/java/org/broad/igv/oauth/OAuthProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.broad.igv.batch.CommandListener;
import org.broad.igv.event.IGVEventBus;
import org.broad.igv.prefs.PreferencesManager;
import org.broad.igv.ui.IGV;
import org.broad.igv.ui.util.MessageUtils;
import org.broad.igv.util.AmazonUtils;
import org.broad.igv.util.GoogleUtils;
Expand All @@ -19,10 +20,7 @@

import java.awt.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.*;
import java.time.Duration;
import java.util.*;
import java.util.prefs.Preferences;
Expand All @@ -32,15 +30,12 @@ public class OAuthProvider {
private static Logger log = LogManager.getLogger(OAuthProvider.class);

private String authProvider = "";
private String appIdURI = null;
private String appIdURI;
public static String findString = null;
public static String replaceString = null;

private static final String REFRESH_TOKEN_KEY = "oauth_refresh_token";

private String state; // "RFC6749: An opaque value used by the client to maintain state"
private String portNumber = PreferencesManager.getPreferences().getPortNumber();
private String redirectURI = "http%3A%2F%2Flocalhost%3A" + portNumber + "%2FoauthCallback";
private String redirectURI;
private String clientId;
private String clientSecret;
private String authEndpoint;
Expand All @@ -54,13 +49,10 @@ public class OAuthProvider {
private String currentUserID;
private String currentUserEmail;
private JsonObject response;
private JsonObject config;


public OAuthProvider(JsonObject obj) throws IOException {

config = obj;

state = UUID.randomUUID().toString(); // "RFC6749: An opaque value used by the client to maintain state"

// For backward compatibility
Expand All @@ -84,6 +76,9 @@ public OAuthProvider(JsonObject obj) throws IOException {
"authorization_endpoint/auth_uri or token_endpoint/token_uri");
}

String portNumber = PreferencesManager.getPreferences().getPortNumber();
redirectURI = "http://localhost:" + portNumber + "/oauthCallback";;

// Optional or custom attributes, fail on runtime, depending on identity provider configuration
clientSecret = obj.has("client_secret") ? obj.get("client_secret").getAsString() : null;
setAuthProvider(obj.has("auth_provider") ? obj.get("auth_provider").getAsString() : authProvider);
Expand Down Expand Up @@ -119,10 +114,6 @@ public OAuthProvider(JsonObject obj) throws IOException {
String gsScope = "https://www.googleapis.com/auth/devstorage.read_only";
String emailScope = "https://www.googleapis.com/auth/userinfo.email";
scope = gsScope + "%20" + emailScope;

}
if (authProvider == null) {
authProvider = "Google";
}
}
}
Expand All @@ -131,14 +122,6 @@ public String getState() {
return state;
}

public String[] getHosts() {
return hosts;
}

public void setHosts(String[] hosts) {
this.hosts = hosts;
}

/**
* Send request to authorization provider to start the oauth 2.0
* authorization process. If the listener is up, wait for a callback
Expand Down Expand Up @@ -168,7 +151,7 @@ public void openAuthorizationPage() throws IOException, URISyntaxException {
} else {

url = authEndpoint + "?state=" + state +
"&redirect_uri=" + redirectURI +
"&redirect_uri=" + URLEncoder.encode(redirectURI, "utf-8") +
"&client_id=" + clientId +
"&response_type=code";

Expand All @@ -185,7 +168,7 @@ public void openAuthorizationPage() throws IOException, URISyntaxException {
if (desktop.isSupported(Desktop.Action.BROWSE)) {
desktop.browse(new URI(url));
} else {
MessageUtils.showMessage("Copy this authorization URL into your web browser: " + url);
OAuthURLForm.open(IGV.getInstance().getMainFrame(), url);
}
}
}
Expand All @@ -201,7 +184,7 @@ public void setAuthorizationCode(String authorizationCode) throws IOException {
if (clientSecret != null) {
params.put("client_secret", clientSecret);
}
params.put("redirect_uri", URLDecoder.decode(redirectURI, "utf-8"));
params.put("redirect_uri", redirectURI);
params.put("grant_type", "authorization_code");

// set the resource if it necessary for the auth provider dwm08
Expand Down Expand Up @@ -446,7 +429,6 @@ public boolean appliesToUrl(URL url) {
}
}
}

if (this.isGoogle()) {
return GoogleUtils.isGoogleURL(url.toExternalForm());
}
Expand All @@ -465,10 +447,6 @@ public void setResponse(JsonObject res) {
response = res;
}

public String getAuthProvider() {
return authProvider;
}

public void setAuthProvider(String authProvider) {
this.authProvider = authProvider;
}
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/org/broad/igv/oauth/OAuthURLForm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.broad.igv.oauth;

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class OAuthURLForm extends JDialog {

private static JPanel getPanel(String url) {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setMinimumSize(new Dimension(400, 300));
panel.setPreferredSize(new Dimension(400, 300));
//this.add(panel);

JPanel headerPanel = new JPanel();
headerPanel.setLayout(new FlowLayout());
JLabel label = new JLabel("Copy this authorization URL to your web browser");
headerPanel.add(label);

Button copyButton = new Button("Copy");
copyButton.addActionListener(e -> {
StringSelection selection = new StringSelection(url);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, selection);
});
headerPanel.add(copyButton);
panel.add(headerPanel);

JTextArea textArea = new JTextArea(url);
textArea.setMargin(new Insets(10, 10, 10, 10));
textArea.setLineWrap(true);
panel.add(textArea);

panel.setAlignmentX(Component.LEFT_ALIGNMENT);

return panel;
}

public static void open(Frame owner, String url) {

JPanel panel = getPanel(url);
JOptionPane.showMessageDialog(owner,
panel,
"OAuth Authorization URL",
JOptionPane.PLAIN_MESSAGE);

}


public static void main(String[] args) {

open(null, "https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/uiswing/examples/layout/BoxLayoutDemoProject/src/layout/BoxLayoutDemo.java");
}
}


Loading

0 comments on commit 4994be2

Please sign in to comment.