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

Add SSO feature for Store application #4316

Merged
merged 23 commits into from
Jul 31, 2017
Merged

Add SSO feature for Store application #4316

merged 23 commits into from
Jul 31, 2017

Conversation

npamudika
Copy link
Contributor

Proposed changes in this pull request

  • SSO implementation for Store application
  • Unit tests for AuthenticatorService class

When should this PR be merged

ASAP

Follow up actions

[List any possible follow-up actions here; for instance, testing data
migrations, software that we need to install on staging and production
environments.]

Checklist (for reviewing)

General

  • Is this PR explained thoroughly? All code changes must be accounted for in the PR description.
  • Is the PR labeled correctly?

Functionality

  • Are all requirements met? Compare implemented functionality with the requirements specification.
  • Does the UI work as expected? There should be no Javascript errors in the console; all resources should load. There should be no unexpected errors. Deliberately try to break the feature to find out if there are corner cases that are not handled.

Code

  • Do you fully understand the introduced changes to the code? If not ask for clarification, it might uncover ways to solve a problem in a more elegant and efficient way.
  • Does the PR introduce any inefficient database requests? Use the debug server to check for duplicate requests.
  • Are all necessary strings marked for translation? All strings that are exposed to users via the UI must be marked for translation.

Tests

  • Are there sufficient test cases? Ensure that all components are tested individually; models, forms, and serializers should be tested in isolation even if a test for a view covers these components.
  • If this is a bug fix, are tests for the issue in place? There must be a test case for the bug to ensure the issue won’t regress. Make sure that the tests break without the new code to fix the issue.
  • If this is a new feature or a significant change to an existing feature? has the manual testing spreadsheet been updated with instructions for manual testing?

Security

  • Confirm this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.
  • Are all UI and API inputs run through forms or serializers?
  • Are all external inputs validated and sanitized appropriately?
  • Does all branching logic have a default case?
  • Does this solution handle outliers and edge cases gracefully?
  • Are all external communications secured and restricted to SSL?

Documentation

  • Are changes to the UI documented in the platform docs? If this PR introduces new platform site functionality or changes existing ones, the changes should be documented.
  • Are changes to the API documented in the API docs? If this PR introduces new API functionality or changes existing ones, the changes must be documented.
  • Are reusable components documented? If this PR introduces components that are relevant to other developers (for instance a mixin for a view or a generic form) they should be documented in the Wiki.

@@ -124,7 +124,7 @@ private static void executeSQL(String sql, Connection connection) {

String q = "select index_name,index_type,status,domidx_status,domidx_opstatus from user_indexes "
+ "where index_type like '%DOMAIN%' and (domidx_status <> 'VALID' or domidx_opstatus <> 'VALID')";
try (Statement statement = connection.createStatement(); ResultSet rs = statement.executeQuery(q);) {
try (Statement statement = connection.createStatement(); ResultSet rs = statement.executeQuery(q)) {
while (rs.next()) {
if (rs.getString("index_name").equals("API_INDEX")) { // re build index if it has failed.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the equals other way around to avoid null pointer exception. i.e "API_INDEX".equals(rs.getString("index_name")). Check equals operations in other places as well.

return true;
}
return false;
return hostname.equals("localhost");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the equals should be otherway around "localhost".equals(hostname)

if (configProvider != null) {
config = configProvider.getConfigurationObject(APIMStoreConfigurations.class);
} else {
log.error("Configuration provider is null");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this actually an error?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because configiProvider null means config is becoming null which you then set the default configurationss

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here configProvider is getting null due to an osgi error.
Default configurations has set in line 61.

log.debug("Received consumer key & secret for " + appName + " application.");
}
try {
if (grantType.equals(KeyManagerConstants.AUTHORIZATION_CODE_GRANT_TYPE)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

equals should be otherwaround

String errorMsg = "No Authorization Code available.";
log.error(errorMsg, ExceptionCodes.ACCESS_TOKEN_GENERATION_FAILED);
}
} else if (grantType.equals(KeyManagerConstants.PASSWORD_GRANT_TYPE)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

.createAccessTokenRequest(userName, password, grantType, refreshToken,
null, validityPeriod, scopes,
consumerKeySecretMap.get("CONSUMER_KEY"), consumerKeySecretMap.get("CONSUMER_SECRET"));
accessTokenInfo = getKeyManager().getNewAccessToken(accessTokenRequest);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we dont have a else statement is there any possibility that it can effect the follow because accessTokenInfo is getting null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When accessTokenInfo is null, it will be handled when calling getTokens() method at AuthenticatorAPI class.

* Represents Payload of JWT.
*/
private class JWTTokenPayload {
private String sub;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need inner class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github issue created at,
#4324 [C5][Authenticator] Handle JWT

// for the oAuthAppRequest constructor argument.
// This value is not related to DCR application creation.
OAuthAppRequest oAuthAppRequest = new OAuthAppRequest(clientName,
callBackURL, "Application", grantTypes);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Application to a constant?

oAuthData.addProperty(KeyManagerConstants.TOKEN_SCOPES, scopes);
oAuthData.addProperty(KeyManagerConstants.AUTHORIZATION_ENDPOINT,
storeConfigs.getAuthorizationEndpoint());
oAuthData.addProperty("is_sso_enabled", storeConfigs.isSsoEnabled());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this ti a constant?

storeConfigs.getAuthorizationEndpoint());
oAuthData.addProperty("is_sso_enabled", storeConfigs.isSsoEnabled());
} else {
String errorMsg = "No information available in OAuth application.";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to throw a exception here?

} else {
restAPIContext = AuthenticatorConstants.REST_CONTEXT + appContext;
}
String requestURL = (String) request.getProperty("REQUEST_URL");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to a constant

oAuthData.addProperty(KeyManagerConstants.TOKEN_SCOPES, scopes);
oAuthData.addProperty(KeyManagerConstants.AUTHORIZATION_ENDPOINT,
storeConfigs.getAuthorizationEndpoint());
oAuthData.addProperty("is_sso_enabled", storeConfigs.isSsoEnabled());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move 'is_sso_enabled' to a constant.

AuthResponseBean authResponseBean = new AuthResponseBean();
String appContext = AuthUtil.getAppContext(request);
String restAPIContext;
if (appContext.contains("editor") || request.getUri().contains("publisher")) {
restAPIContext = AuthenticatorConstants.REST_CONTEXT + "/publisher";
if (appContext.contains(AuthenticatorConstants.EDITOR_APPLICATION) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can compare application contexts in this manner since they can change. Please create a Github issue for this, we need to fix it properly in all places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github issue created at,
#4319 [C5][Authenticator] Compare application contexts

if (log.isDebugEnabled()) {
log.debug("Set scopes for " + appName + " application using swagger definition.");
}
// TODO: Get Consumer Key & Secret without creating a new app, from the IS side
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create Github issues for TODOs, we'll forget them for sure otherwise :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github issue created at,
#4299 [C5][Authenticator] Getting details of an already existing DCR application

private String getUsernameFromJWT(String jwt) throws KeyManagementException {
if (jwt != null && jwt.contains(".")) {
String[] jwtParts = jwt.split("\\.");
JWTTokenPayload jwtHeader = new Gson().fromJson(new String(Base64.getDecoder().decode(jwtParts[1]),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we use a standard JWT library like Nimbus to handle JWT? If its hard to incorporate along with this feature please create a Github issue so that it doesn't get forgotten.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github issue created at,
#4324 [C5][Authenticator] Handle JWT

@@ -56,7 +56,7 @@ public static String getHttpOnlyCookieHeader(Cookie cookie) {

public static String getAppContext(Request request) {
//TODO this method should provide uuf app context. Consider the scenarios of reverse proxy as well.
return "/" + request.getProperty("REQUEST_URL").toString().split("/")[1];
return "/" + request.getProperty("REQUEST_URL").toString().split("/")[3];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this code will work when you reverse proxy the application. If you have a custom URL this logic will fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to the Github issue at,
#4319 [C5][Authenticator] Compare application contexts

return true;
}
return false;
return username.equals(password);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this? Do we have an idea to implement this? If so please create relevant GitHub issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we need to implement the authentication logic when the user name and password are provided.
Need to check for an API from IS.
Issue created. #4323

@harsha89 harsha89 merged commit e353b6a into wso2:master Jul 31, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants