/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.usergrid.rest.management.organizations; import com.fasterxml.jackson.jaxrs.json.annotation.JSONP; import com.google.common.base.Preconditions; import org.apache.commons.lang.StringUtils; import org.apache.usergrid.management.ApplicationCreator; import org.apache.usergrid.management.OrganizationInfo; import org.apache.usergrid.management.OrganizationOwnerInfo; import org.apache.usergrid.management.exceptions.ManagementException; import org.apache.usergrid.persistence.*; import org.apache.usergrid.rest.AbstractContextResource; import org.apache.usergrid.rest.ApiResponse; import org.apache.usergrid.rest.RootResource; import org.apache.usergrid.rest.security.annotations.RequireSystemAccess; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; import java.util.*; import static org.apache.commons.lang.StringUtils.isNotEmpty; import static org.apache.usergrid.persistence.Schema.PROPERTY_PATH; @Component( "org.apache.usergrid.rest.management.organizations.OrganizationsResource" ) @Scope( "prototype" ) @Produces( { MediaType.APPLICATION_JSON, "application/javascript", "application/x-javascript", "text/ecmascript", "application/ecmascript", "text/jscript" } ) public class OrganizationsResource extends AbstractContextResource { private static final Logger logger = LoggerFactory.getLogger( OrganizationsResource.class ); public static final String ORGANIZATION_PROPERTIES = "properties"; public static final String ORGANIZATION_CONFIGURATION = "configuration"; public static final String USERGRID_SYSADMIN_LOGIN_NAME = "usergrid.sysadmin.login.name"; public static final String USERGRID_SUPERUSER_ADDORG_ENABLED ="usergrid.superuser.addorg.enable"; @Autowired private ApplicationCreator applicationCreator; public OrganizationsResource() { } @GET @RequireSystemAccess @Produces(MediaType.APPLICATION_JSON) public ApiResponse getAllOrganizations(@Context UriInfo ui) throws Exception{ ApiResponse response = createApiResponse(); String cursor = ui.getQueryParameters().getFirst("cursor"); String limitString = ui.getQueryParameters().getFirst("limit"); int limit = 10; if( isNotEmpty(limitString)){ try { limit = Integer.valueOf(limitString); }catch (NumberFormatException e){ // do nothing let it be default } } if (limit < 1) { limit = 1; } else if (limit > 1000) { limit = 1000; } EntityManager em = emf.getManagementEntityManager(); Query query = new Query(); query.setCursor(cursor); query.setLimit(limit); Results results = em.searchCollection(em.getApplicationRef(), Schema.COLLECTION_GROUPS, query); List<OrganizationInfo> orgs = new ArrayList<>( results.size() ); OrganizationInfo orgInfo; for ( Entity entity : results.getEntities() ) { String path = ( String ) entity.getProperty( PROPERTY_PATH ); orgInfo = new OrganizationInfo( entity.getUuid(), path ); orgs.add( orgInfo ); } List<Object> jsonOrgList = new ArrayList<>(); for(OrganizationInfo org: orgs){ Map<String, Object> jsonOrg = new HashMap<>(); Map<String, UUID> apps = management.getApplicationsForOrganization(org.getUuid()).inverse(); jsonOrg.put("name", org.getName()); jsonOrg.put("uuid", org.getUuid()); jsonOrg.put("properties", org.getProperties()); jsonOrg.put("applications", apps); jsonOrgList.add(jsonOrg); } response.setProperty("organizations", jsonOrgList); response.setCount(orgs.size()); response.setCursor(results.getCursor()); return response; } @Path(RootResource.ORGANIZATION_ID_PATH) public OrganizationResource getOrganizationById( @Context UriInfo ui, @PathParam( "organizationId" ) String organizationIdStr ) throws Exception { OrganizationInfo organization = management.getOrganizationByUuid( UUID.fromString( organizationIdStr ) ); if ( organization == null ) { throw new ManagementException( "Could not find organization for ID: " + organizationIdStr ); } return getSubResource( OrganizationResource.class ).init( organization ); } @Path( "{organizationName}" ) public OrganizationResource getOrganizationByName( @Context UriInfo ui, @PathParam( "organizationName" ) String organizationName ) throws Exception { OrganizationInfo organization = management.getOrganizationByName(organizationName); if ( organization == null ) { throw new ManagementException( "Could not find organization for name: " + organizationName ); } return getSubResource( OrganizationResource.class ).init(organization); } @POST @Consumes( MediaType.APPLICATION_JSON ) @JSONP @Produces({MediaType.APPLICATION_JSON, "application/javascript"}) public ApiResponse newOrganization( @Context UriInfo ui, Map<String, Object> json, @QueryParam( "callback" ) @DefaultValue( "" ) String callback ) throws Exception { if (logger.isTraceEnabled()) { logger.trace("newOrganization"); } ApiResponse response = createApiResponse(); response.setAction( "new organization" ); if(json==null){ throw new IllegalArgumentException("missing json post data"); } String organizationName = ( String ) json.remove( "organization" ); String username = ( String ) json.remove( "username" ); String name = ( String ) json.remove( "name" ); String email = ( String ) json.remove( "email" ); String password = ( String ) json.remove( "password" ); Map<String, Object> orgProperties = ( Map<String, Object> ) json.remove( ORGANIZATION_PROPERTIES ); return newOrganization( ui, organizationName, username, name, email, password, json, orgProperties, callback ); } @POST @Consumes( MediaType.APPLICATION_FORM_URLENCODED ) @JSONP @Produces({MediaType.APPLICATION_JSON, "application/javascript"}) public ApiResponse newOrganizationFromForm( @Context UriInfo ui, @FormParam( "organization" ) String organizationNameForm, @QueryParam( "organization" ) String organizationNameQuery, @FormParam( "username" ) String usernameForm, @QueryParam( "username" ) String usernameQuery, @FormParam( "name" ) String nameForm, @QueryParam( "name" ) String nameQuery, @FormParam( "email" ) String emailForm, @QueryParam( "email" ) String emailQuery, @FormParam( "password" ) String passwordForm, @QueryParam( "password" ) String passwordQuery, @QueryParam( "callback" ) @DefaultValue( "" ) String callback ) throws Exception { if (logger.isTraceEnabled()) { logger.trace("New organization: {}", organizationNameForm); } String organizationName = organizationNameForm != null ? organizationNameForm : organizationNameQuery; String username = usernameForm != null ? usernameForm : usernameQuery; String name = nameForm != null ? nameForm : nameQuery; String email = emailForm != null ? emailForm : emailQuery; String password = passwordForm != null ? passwordForm : passwordQuery; return newOrganization( ui, organizationName, username, name, email, password, null, null, callback ); } /** Create a new organization */ @JSONP @Produces({MediaType.APPLICATION_JSON, "application/javascript"}) private ApiResponse newOrganization( @Context UriInfo ui, String organizationName, String username, String name, String email, String password, Map<String, Object> userProperties, Map<String, Object> orgProperties, String callback ) throws Exception { /* Providing no password in this request signifies that an existing admin users should be associated to the newly requested organization. */ // Always let the sysadmin create an org, but otherwise follow the behavior specified with // the property 'usergrid.management.allow-public-registration' if ( ( System.getProperty("usergrid.management.allow-public-registration") != null && !Boolean.valueOf(System.getProperty("usergrid.management.allow-public-registration")) && !userServiceAdmin(null) ) ) { throw new IllegalArgumentException("Public organization registration is disabled"); } Preconditions .checkArgument( StringUtils.isNotBlank( organizationName ), "The organization parameter was missing" ); Preconditions.checkArgument( StringUtils.isNotBlank( organizationName ), "The organization parameter was missing" ); if (logger.isDebugEnabled()) { logger.debug("New organization: {}", organizationName); } ApiResponse response = createApiResponse(); response.setAction( "new organization" ); OrganizationOwnerInfo organizationOwner = management .createOwnerAndOrganization( organizationName, username, name, email, password, false, false, userProperties, orgProperties ); if ( organizationOwner == null ) { logger.info( "organizationOwner is null, returning. organization: {}", organizationName ); return null; } applicationCreator.createSampleFor( organizationOwner.getOrganization() ); // ( DO NOT REMOVE ) Execute any post processing which may be overridden by external classes using UG as // a dependency management.createAdminUserPostProcessing(organizationOwner.getOwner(), null); management.createOrganizationPostProcessing(organizationOwner.getOrganization(), null); management.addUserToOrganizationPostProcessing(organizationOwner.getOwner(), organizationName, null); response.setData( organizationOwner ); response.setSuccess(); logger.info( "New organization complete: {}", organizationName ); return response; } }