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

    https://github.com/apache/incubator-usergrid/pull/221#discussion_r28356858
  
    --- Diff: 
stack/rest/src/main/java/org/apache/usergrid/rest/management/ManagementResource.java
 ---
    @@ -441,6 +451,181 @@ public Viewable handleAuthorizeForm( @Context UriInfo 
ui, @FormParam( "response_
         }
     
     
    +    /**
    +     * <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 organization with the 
same name of user is created.
    +     * If no user is returned from the other cluster, then this endpoint 
will return 401.
    +     * <p>
    +     *
    +     * <p>
    +     * 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 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 organization with the 
same name of user is 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");
    +        }
    +
    +        // 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();
    +        String name     = userNode.get( "name" ).getTextValue();
    +        String email    = userNode.get( "email" ).getTextValue();
    +
    +        // set dummy password to random string that nobody can guess, in 
SSO setup
    +        // admin users should never be able to login directly to this 
Usergrid system
    +        String dummyPassword = RandomStringUtils.randomAlphanumeric( 40 );
    +
    +        // if user does not exist locally then we need to fix that
    +
    +        final UUID userId;
    +        final OrganizationInfo organizationInfo = 
management.getOrganizationByName(username);
    +
    +        if ( organizationInfo == null ) {
    +
    +            // create local user and personal organization, activate user.
    +
    +            OrganizationOwnerInfo ownerOrgInfo = 
management.createOwnerAndOrganization(
    +                    username, username, name, email, dummyPassword, true, 
true );
    +            userId = ownerOrgInfo.getOwner().getUuid();
    +
    +            management.activateOrganization( 
ownerOrgInfo.getOrganization() );
    +
    +            applicationCreator.createSampleFor( 
ownerOrgInfo.getOrganization() );
    +
    +        } else {
    +            userId = management.getAdminUserByUsername( username 
).getUuid();
    +        }
    +
    +        // 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 accessInfo = new AccessInfo()
    +                .withExpiresIn( 
tokens.getMaxTokenAgeInSeconds(extAccessToken ) )
    +                .withAccessToken( extAccessToken );
    +
    +        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 ) {
    --- End diff --
    
    can we expose more specific error information, and throw different 
exceptions, here based on what comes back from the request?


---
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