Github user snoopdave commented on a diff in the pull request:

    https://github.com/apache/incubator-usergrid/pull/224#discussion_r28521613
  
    --- Diff: 
stack/rest/src/main/java/org/apache/usergrid/rest/management/ManagementResource.java
 ---
    @@ -441,6 +464,229 @@ public Viewable handleAuthorizeForm( @Context UriInfo 
ui, @FormParam( "response_
         }
     
     
    +    /**
    +     * <p>
    +     * Allows call to validateExternalToken() (see below) with a POST of a 
JSON object.
    +     * </p>
    +     *
    +     * @param ui             Information about calling URI.
    +     * @param json           JSON object with fields: ext_access_token, ttl
    +     * @param callback       For JSONP support.
    +     * @return               Returns JSON object with access_token field.
    +     * @throws Exception     Returns 401 if access token cannot be 
validated
    +     */
    +    @POST
    +    @Path( "/externaltoken" )
    +    public Response validateExternalToken(
    +            @Context UriInfo ui,
    +            Map<String, Object> json,
    +            @QueryParam( "callback" ) @DefaultValue( "" ) String callback 
)  throws Exception {
    +
    +        if ( StringUtils.isEmpty( properties.getProperty( 
USERGRID_CENTRAL_URL ))) {
    +            throw new NotImplementedException( "External Token Validation 
Service is not configured" );
    +        }
    +
    +        Object extAccessTokenObj = json.get( "ext_access_token" );
    +        if ( extAccessTokenObj == null ) {
    +            throw new IllegalArgumentException("ext_access_token must be 
specified");
    +        }
    +        String extAccessToken = json.get("ext_access_token").toString();
    +
    +        Object ttlObj = json.get("ttl");
    +        if ( ttlObj == null ) {
    +            throw new IllegalArgumentException("ttl must be specified");
    +        }
    +        long ttl;
    +        try {
    +            ttl = Long.parseLong(ttlObj.toString());
    +        } catch ( NumberFormatException e ) {
    +            throw new IllegalArgumentException("ttl must be specified as a 
long");
    +        }
    +
    +        return validateExternalToken( ui, extAccessToken, ttl, callback );
    +    }
    +
    +
    +    /**
    +     * <p>
    +     * Validates access token from other or "external" Usergrid system.
    +     * Calls other system's /management/me endpoint to get the User
    +     * associated with the access token. If user does not exist locally,
    +     * then user and organizations will be created. If no user is returned
    +     * from the other cluster, then this endpoint will return 401.
    +     * </p>
    +     *
    +     * <p> Part of Usergrid Central SSO feature.
    +     * See <a 
href="https://issues.apache.org/jira/browse/USERGRID-567";>USERGRID-567</a>
    +     * for details about Usergrid Central SSO.
    +     * </p>
    +     *
    +     * @param ui             Information about calling URI.
    +     * @param extAccessToken Access token from external Usergrid system.
    +     * @param ttl            Time to live for token.
    +     * @param callback       For JSONP support.
    +     * @return               Returns JSON object with access_token field.
    +     * @throws Exception     Returns 401 if access token cannot be 
validated
    +     */
    +    @GET
    +    @Path( "/externaltoken" )
    +    public Response validateExternalToken(
    +                                @Context UriInfo ui,
    +                                @QueryParam( "ext_access_token" ) String 
extAccessToken,
    +                                @QueryParam( "ttl" ) @DefaultValue("-1") 
long ttl,
    +                                @QueryParam( "callback" ) @DefaultValue( 
"" ) String callback )
    +            throws Exception {
    +
    +
    +        if ( StringUtils.isEmpty( properties.getProperty( 
USERGRID_CENTRAL_URL ))) {
    +            throw new NotImplementedException( "External Token Validation 
Service is not configured" );
    +        }
    +
    +        if ( extAccessToken == null ) {
    +            throw new IllegalArgumentException("ext_access_token must be 
specified");
    +        }
    +
    +        if ( ttl == -1 ) {
    +            throw new IllegalArgumentException("ttl must be specified");
    +        }
    +        AccessInfo accessInfo = null;
    +
    +        try {
    +            // look up user via UG Central's /management/me endpoint.
    +
    +            JsonNode accessInfoNode = getMeFromUgCentral( extAccessToken );
    +
    +            JsonNode userNode = accessInfoNode.get( "user" );
    +            String username = userNode.get( "username" ).getTextValue();
    +
    +            // if user does not exist locally then we need to fix that
    +
    +            UserInfo userInfo = management.getAdminUserByUsername( 
username );
    +            UUID userId = userInfo == null ? null : userInfo.getUuid();
    +
    +            if ( userId == null ) {
    +
    +                // create local user and and organizations they have on 
the central Usergrid instance
    +
    +                String name  = userNode.get( "name" ).getTextValue();
    +                String email = userNode.get( "email" ).getTextValue();
    +                String dummyPassword = 
RandomStringUtils.randomAlphanumeric( 40 );
    +
    +                JsonNode orgsNode = userNode.get( "organizations" );
    +                final Iterator<String> fieldNames = 
orgsNode.getFieldNames();
    +
    +                // create user and any organizations that user is supposed 
to have
    +
    +                while ( fieldNames.hasNext() ) {
    +
    +                    String orgName = fieldNames.next();
    +
    +                    if ( userId == null ) {
    +
    +                        // haven't created user yet so do that now
    +                        OrganizationOwnerInfo ownerOrgInfo = 
management.createOwnerAndOrganization(
    +                                orgName, username, name, email, 
dummyPassword, true, true );
    +
    +                        management.activateOrganization( 
ownerOrgInfo.getOrganization() ); // redundant?
    +                        applicationCreator.createSampleFor( 
ownerOrgInfo.getOrganization() );
    +
    +                        userId = ownerOrgInfo.getOwner().getUuid();
    +                        userInfo = ownerOrgInfo.getOwner();
    +
    +                    } else {
    +
    +                        // already created user, so just create an org
    +                        final OrganizationInfo organization = 
management.createOrganization( orgName, userInfo, true );
    +
    +                        management.activateOrganization( organization ); 
// redundant?
    +                        applicationCreator.createSampleFor( organization );
    +                    }
    +                }
    +
    +            }
    +
    +            // store the external access_token as if it were one of our own
    +            management.importTokenForAdminUser( userId, extAccessToken, 
ttl );
    +
    +            // success! return JSON object with access_token field
    +            accessInfo = new AccessInfo()
    +                    .withExpiresIn( tokens.getMaxTokenAgeInSeconds( 
extAccessToken ) )
    +                    .withAccessToken( extAccessToken );
    +
    +        } catch (Exception e) {
    +            logger.debug("Error validating external token", e);
    +            throw e;
    +        }
    +
    +        return Response.status( SC_OK ).type( jsonMediaType( callback ) 
).entity( accessInfo ).build();
    +    }
    +
    +
    +    /**
    +     * Look up Admin User via UG Central's /management/me endpoint.
    +     *
    +     * @param extAccessToken Access token issued by UG Central of Admin 
User
    +     * @return JsonNode representation of AccessInfo object for Admin User
    +     * @throws EntityNotFoundException if access_token is not valid.
    +     */
    +    private JsonNode getMeFromUgCentral( String extAccessToken )  throws 
EntityNotFoundException {
    +
    +        // create URL of central Usergrid's /management/me endpoint
    +
    +        String externalUrl = properties.getProperty( USERGRID_CENTRAL_URL 
).trim();
    +
    +        // be lenient about trailing slash
    +        externalUrl = !externalUrl.endsWith( "/" ) ? externalUrl + "/" : 
externalUrl;
    +        String me = externalUrl + "management/me?access_token=" + 
extAccessToken;
    +
    +        // use our favorite HTTP client to GET /management/me
    +
    +        ClientConfig clientConfig = new DefaultClientConfig();
    +        clientConfig.getFeatures().put( 
JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
    +        Client client = Client.create(clientConfig);
    +        final JsonNode accessInfoNode;
    +        try {
    +            accessInfoNode = client.resource( me )
    +                    .type( MediaType.APPLICATION_JSON_TYPE)
    +                    .get(JsonNode.class);
    +
    +        } catch ( Exception e ) {
    +            // user not found 404
    +            String msg = "Cannot find Admin User associated with " + 
extAccessToken;
    +            throw new EntityNotFoundException( msg, e );
    +        }
    +        return accessInfoNode;
    +    }
    +
    +
    +    /**
    --- End diff --
    
    I moved the "superuser-only login when external token validation enabled" 
logic in the below new method:


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---

Reply via email to