Skip to content

Commit

Permalink
ApiDescriptor rename slash-api to mount #10755
Browse files Browse the repository at this point in the history
  • Loading branch information
anatol-sialitski committed Nov 6, 2024
1 parent 23b49d1 commit 4ff0579
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.enonic.xp.context.Context;
import com.enonic.xp.context.ContextAccessor;
import com.enonic.xp.portal.PortalResponse;
import com.enonic.xp.portal.universalapi.UniversalApiHandler;
import com.enonic.xp.security.PrincipalKey;
import com.enonic.xp.security.auth.AuthenticationInfo;
import com.enonic.xp.server.BuildInfo;
Expand All @@ -19,10 +20,9 @@
import com.enonic.xp.web.HttpStatus;
import com.enonic.xp.web.WebRequest;
import com.enonic.xp.web.WebResponse;
import com.enonic.xp.portal.universalapi.UniversalApiHandler;

@Component(immediate = true, service = UniversalApiHandler.class, property = {"applicationKey=admin", "apiKey=status",
"displayName=Status API"})
"displayName=Status API", "allowedPrincipals=role:system.everyone", "mount=true"})
public class StatusApiHandler
implements UniversalApiHandler
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,20 @@ public final class ApiDescriptor

private final String documentationUrl;

private final boolean slashApi;
private final boolean mount;

private ApiDescriptor( final Builder builder )
{
Preconditions.checkNotNull( builder.key, "key cannot be null" );
Preconditions.checkNotNull( builder.allowedPrincipals, "allowedPrincipals cannot be null" );
Preconditions.checkArgument( !builder.allowedPrincipals.isEmpty(), "allowedPrincipals cannot be empty" );

this.key = builder.key;
this.allowedPrincipals = builder.allowedPrincipals;
this.displayName = builder.displayName;
this.description = builder.description;
this.documentationUrl = builder.documentationUrl;
this.slashApi = Objects.requireNonNullElse( builder.slashApi, true );
this.mount = Objects.requireNonNullElse( builder.mount, false );
}

public DescriptorKey getKey()
Expand Down Expand Up @@ -62,15 +64,14 @@ public String getDocumentationUrl()
return documentationUrl;
}

public Boolean isSlashApi()
public boolean isMount()
{
return slashApi;
return mount;
}

public boolean isAccessAllowed( final PrincipalKeys principalKeys )
{
return allowedPrincipals == null || principalKeys.contains( RoleKeys.ADMIN ) ||
allowedPrincipals.stream().anyMatch( principalKeys::contains );
return principalKeys.contains( RoleKeys.ADMIN ) || allowedPrincipals.stream().anyMatch( principalKeys::contains );
}

public static ResourceKey toResourceKey( final DescriptorKey key, final String extension )
Expand All @@ -95,7 +96,7 @@ public static final class Builder

private String documentationUrl;

private Boolean slashApi;
private Boolean mount;

private Builder()
{
Expand Down Expand Up @@ -131,9 +132,9 @@ public Builder documentationUrl( final String documentationUrl )
return this;
}

public Builder slashApi( final Boolean useInSlashApi )
public Builder mount( final Boolean mount )
{
this.slashApi = useInSlashApi;
this.mount = mount;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@
<xs:element minOccurs="0" name="display-name" type="xs:string"/>
<xs:element minOccurs="0" name="description" type="xs:string"/>
<xs:element minOccurs="0" name="documentation-url" type="xs:string"/>
<xs:element minOccurs="0" name="slash-api" type="xs:boolean"/>
<xs:element minOccurs="0" name="mount" type="xs:boolean"/>
<xs:element minOccurs="0" name="allow">
<xs:complexType>
<xs:sequence>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ private ApiDescriptor createDynamicApiDescriptor( final Map<String, ?> propertie
{
builder.documentationUrl( properties.get( "documentationUrl" ).toString() );
}
if ( properties.get( "slashApi" ) != null )
if ( properties.get( "mount" ) != null )
{
builder.slashApi( Boolean.valueOf( properties.get( "slashApi" ).toString() ) );
builder.mount( Boolean.valueOf( properties.get( "mount" ).toString() ) );
}

return builder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public final class XmlApiDescriptorParser

private static final String DOCUMENTATION_URL_TAG_NAME = "documentation-url";

private static final String SLASH_API_TAG_NAME = "slash-api";
private static final String MOUNT_TAG_NAME = "mount";

private final ApiDescriptor.Builder builder;

Expand All @@ -43,10 +43,10 @@ protected void doParse( final DomElement root )
this.builder.description( root.getChildValue( DESCRIPTION_TAG_NAME ) );
this.builder.documentationUrl( root.getChildValueTrimmed( DOCUMENTATION_URL_TAG_NAME ) );

final String useInSlashApi = root.getChildValueTrimmed( SLASH_API_TAG_NAME );
if ( useInSlashApi != null )
final String mount = root.getChildValueTrimmed( MOUNT_TAG_NAME );
if ( mount != null )
{
builder.slashApi( Boolean.valueOf( useInSlashApi ) );
builder.mount( Boolean.valueOf( mount ) );
}

DomElement allowedPrincipals = root.getChild( ALLOW_TAG_NAME );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ private boolean verifyRequestMounted( final ApiDescriptor apiDescriptor, final P

if ( portalRequest.getEndpointPath() == null )
{
return rawPath.startsWith( "/api/" ) && apiDescriptor.isSlashApi();
return rawPath.startsWith( "/api/" ) && apiDescriptor.isMount();
}
else if ( rawPath.startsWith( "/site/" ) || rawPath.startsWith( "/admin/site/" ) )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private Map<String, Object> map( final ApiDescriptor apiDescriptor )
result.put( "displayName", apiDescriptor.getDisplayName() );
result.put( "description", apiDescriptor.getDescription() );
result.put( "documentationUrl", apiDescriptor.getDocumentationUrl() );
result.put( "slashApi", apiDescriptor.isSlashApi() );
result.put( "mount", apiDescriptor.isMount() );

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class XmlApiDescriptorParserTest
Expand Down Expand Up @@ -48,6 +49,16 @@ public void testParseNoNs()
assertResult();
}

@Test
public void testParseInvalid()
throws Exception
{
parse( this.parser, "-invalid.xml" );

IllegalArgumentException exception = assertThrows( IllegalArgumentException.class, () -> this.builder.build() );
assertEquals( "allowedPrincipals cannot be empty", exception.getMessage() );
}

private void assertResult()
{
final ApiDescriptor result = this.builder.build();
Expand All @@ -56,7 +67,7 @@ private void assertResult()
assertEquals( "My API", result.getDisplayName() );
assertEquals( "This is my API", result.getDescription() );
assertEquals( "https://apis.enonic.com", result.getDocumentationUrl() );
assertFalse( result.isSlashApi() );
assertFalse( result.isMount() );

final PrincipalKeys allowedPrincipals = result.getAllowedPrincipals();
assertNotNull( allowedPrincipals );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ void testHandleApi()

ApiDescriptor apiDescriptor = ApiDescriptor.create()
.key( DescriptorKey.from( ApplicationKey.from( "com.enonic.app.myapp" ), "api-key" ) )
.allowedPrincipals( null )
.allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) )
.mount( true )
.build();

when( apiDescriptorService.getByKey( any( DescriptorKey.class ) ) ).thenReturn( apiDescriptor );
Expand All @@ -225,8 +226,8 @@ void testHandleApiWhenApiDisabled()

ApiDescriptor apiDescriptor = ApiDescriptor.create()
.key( DescriptorKey.from( ApplicationKey.from( "com.enonic.app.myapp" ), "api-key" ) )
.allowedPrincipals( null )
.slashApi( false )
.allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) )
.mount( false )
.build();

when( apiDescriptorService.getByKey( any( DescriptorKey.class ) ) ).thenReturn( apiDescriptor );
Expand Down Expand Up @@ -272,7 +273,8 @@ void testHandleApiError()

ApiDescriptor apiDescriptor = ApiDescriptor.create()
.key( DescriptorKey.from( ApplicationKey.from( "com.enonic.app.myapp" ), "api-key" ) )
.allowedPrincipals( null )
.allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) )
.mount( true )
.build();

when( apiDescriptorService.getByKey( any( DescriptorKey.class ) ) ).thenReturn( apiDescriptor );
Expand Down Expand Up @@ -306,7 +308,8 @@ void testSiteMountApplicationDoesNotInstalledToSiteAndProject()

final DescriptorKey descriptorKey = DescriptorKey.from( applicationKey, "api-key" );

final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( descriptorKey ) ) ).thenReturn( apiDescriptor );

Expand Down Expand Up @@ -343,7 +346,8 @@ void testSiteMountSiteDescriptorNotFound()

final DescriptorKey descriptorKey = DescriptorKey.from( applicationKey, "api-key" );

final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( descriptorKey ) ) ).thenReturn( apiDescriptor );

Expand Down Expand Up @@ -375,7 +379,8 @@ void testSiteMountApiDoesNotDefinedIdApis()

final DescriptorKey descriptorKey = DescriptorKey.from( applicationKey, "api-key" );

final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( descriptorKey ) ) ).thenReturn( apiDescriptor );

Expand Down Expand Up @@ -413,7 +418,8 @@ void testSiteMountApiDefinedApis()

final DescriptorKey descriptorKey = DescriptorKey.from( applicationKey, "api-key-1" );

final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( descriptorKey ) ) ).thenReturn( apiDescriptor );

Expand Down Expand Up @@ -451,7 +457,8 @@ void testSiteMountApiDefinedIdApis()

final DescriptorKey descriptorKey = DescriptorKey.from( applicationKey, "api-key-1" );

final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( descriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( descriptorKey ) ) ).thenReturn( apiDescriptor );

Expand Down Expand Up @@ -506,7 +513,8 @@ void testWebappMountExternalAPI()
when( webappService.getDescriptor( eq( webappApplicationKey ) ) ).thenReturn( webappDescriptor );

final DescriptorKey apiDescriptorKey = DescriptorKey.from( apiApplicationKey, "myapi" );
final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( apiDescriptorKey ) ) ).thenReturn( apiDescriptor );

Expand Down Expand Up @@ -536,7 +544,8 @@ void testWebappMountExternalApiIsNotMountedToWebapp()
when( webappService.getDescriptor( eq( webappApplicationKey ) ) ).thenReturn( webappDescriptor );

final DescriptorKey apiDescriptorKey = DescriptorKey.from( apiApplicationKey, "myapi" );
final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( apiDescriptorKey ) ) ).thenReturn( apiDescriptor );

Expand All @@ -556,7 +565,8 @@ void testWebappMountNoWebappDescriptor()
when( webappService.getDescriptor( eq( webappApplicationKey ) ) ).thenReturn( null );

final DescriptorKey apiDescriptorKey = DescriptorKey.from( apiApplicationKey, "myapi" );
final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( apiDescriptorKey ) ) ).thenReturn( apiDescriptor );

Expand All @@ -571,7 +581,8 @@ void testWebappMountNoWebappDescriptor()
void testWebappMountInvalidUrl()
{
final DescriptorKey apiDescriptorKey = DescriptorKey.from( ApplicationKey.from( "com.enonic.app.myapp" ), "myapi" );
final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( apiDescriptorKey ) ) ).thenReturn( apiDescriptor );
request.setEndpointPath( "/_/com.enonic.app.myapp:myapi" );
Expand All @@ -587,7 +598,8 @@ void testAdminMount()
{
final ApplicationKey apiApplicationKey = ApplicationKey.from( "com.enonic.app.external.app" );
final DescriptorKey apiDescriptorKey = DescriptorKey.from( apiApplicationKey, "myapi" );
final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( apiDescriptorKey ) ) ).thenReturn( apiDescriptor );

Expand All @@ -614,7 +626,8 @@ void testAdminMountApiDoesNotMount()
{
final ApplicationKey apiApplicationKey = ApplicationKey.from( "com.enonic.app.external.app" );
final DescriptorKey apiDescriptorKey = DescriptorKey.from( apiApplicationKey, "myapi" );
final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( apiDescriptorKey ) ) ).thenReturn( apiDescriptor );

Expand All @@ -637,7 +650,8 @@ void testAdminMountToolDescriptorDoesNotExists()
{
final ApplicationKey apiApplicationKey = ApplicationKey.from( "com.enonic.app.external.app" );
final DescriptorKey apiDescriptorKey = DescriptorKey.from( apiApplicationKey, "myapi" );
final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( apiDescriptorKey ) ) ).thenReturn( apiDescriptor );

Expand All @@ -657,7 +671,8 @@ void testAdminMountInvalidUrlPattern()
{
final ApplicationKey apiApplicationKey = ApplicationKey.from( "com.enonic.app.external.app" );
final DescriptorKey apiDescriptorKey = DescriptorKey.from( apiApplicationKey, "myapi" );
final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( apiDescriptorKey ) ) ).thenReturn( apiDescriptor );

Expand All @@ -673,7 +688,8 @@ void testUnsupportedUrl()
{
final ApplicationKey apiApplicationKey = ApplicationKey.from( "com.enonic.app.external.app" );
final DescriptorKey apiDescriptorKey = DescriptorKey.from( apiApplicationKey, "myapi" );
final ApiDescriptor apiDescriptor = ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( null ).build();
final ApiDescriptor apiDescriptor =
ApiDescriptor.create().key( apiDescriptorKey ).allowedPrincipals( PrincipalKeys.from( RoleKeys.EVERYONE ) ).build();

when( apiDescriptorService.getByKey( eq( apiDescriptorKey ) ) ).thenReturn( apiDescriptor );

Expand All @@ -690,7 +706,8 @@ void testAddAndRemoveDynamicApiHandler()
{
final MyUniversalApiHandler myUniversalApiHandler = new MyUniversalApiHandler();
universalApiHandlerRegistry.addApiHandler( myUniversalApiHandler,
Map.of( "applicationKey", "com.enonic.app.external.app", "apiKey", "myapi" ) );
Map.of( "applicationKey", "com.enonic.app.external.app", "apiKey", "myapi",
"allowedPrincipals", RoleKeys.EVERYONE.toString() ) );

final ApplicationKey apiApplicationKey = ApplicationKey.from( "com.enonic.app.external.app" );

Expand Down Expand Up @@ -720,7 +737,8 @@ void testHandleDynamicApiHandlerWhichDoesNotMountToAPI()
{
final MyUniversalApiHandler myUniversalApiHandler = new MyUniversalApiHandler();
universalApiHandlerRegistry.addApiHandler( myUniversalApiHandler,
Map.of( "applicationKey", "com.enonic.app.external.app", "apiKey", "myapi" ) );
Map.of( "applicationKey", "com.enonic.app.external.app", "apiKey", "myapi",
"allowedPrincipals", RoleKeys.EVERYONE.toString() ) );

final ApplicationKey applicationKey = ApplicationKey.from( "com.enonic.app.myapp" );
final DescriptorKey descriptorKey = DescriptorKey.from( applicationKey, "mytool" );
Expand Down
Loading

0 comments on commit 4ff0579

Please sign in to comment.