Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions jans-config-api/plugins/admin-ui-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>2.9.2</version>
</dependency>

<!-- Testing -->
<dependency>
Expand Down Expand Up @@ -83,6 +88,17 @@
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<!-- Binary fixtures must not be filtered as text -->
<excludes>
<exclude>**/*.cjar</exclude>
</excludes>
</testResource>
<testResource>
<directory>src/test/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.cjar</include>
</includes>
</testResource>
</testResources>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>distribution</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<includes>
<include>org.apache.tika:tika-core</include>
</includes>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/classes</directory>
Expand All @@ -15,4 +26,4 @@
</includes>
</fileSet>
</fileSets>
</assembly>
</assembly>
Original file line number Diff line number Diff line change
@@ -1,74 +1,147 @@
package io.jans.ca.plugin.adminui.model.adminui;

import io.jans.service.document.store.model.Document;
import com.fasterxml.jackson.annotation.JsonView;
import io.jans.ca.plugin.adminui.model.adminui.PolicyStoreViews.Create;
import io.jans.ca.plugin.adminui.model.adminui.PolicyStoreViews.Edit;
import io.jans.orm.annotation.AttributeName;
import io.jans.orm.annotation.DN;
import io.jans.orm.annotation.DataEntry;
import io.jans.orm.annotation.ObjectClass;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.core.MediaType;
import org.jboss.resteasy.annotations.providers.multipart.PartType;
import java.io.InputStream;

public class AdminUIPolicyStore {

@NotNull
@Valid
@FormParam("document")
@PartType(MediaType.APPLICATION_JSON)
private Document document;

@NotNull
@FormParam("policyStore")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@Schema(implementation = String.class, format="binary")
private InputStream policyStore;

/**
* Retrieve the uploaded policy store binary stream.
*
* @return the `policyStore` InputStream containing the binary content submitted via the multipart form field "policyStore"
*/
public InputStream getPolicyStore() {
return policyStore;
}
import java.util.Date;

/**
* Assigns the input stream that contains the binary policy store.
*
* @param policyStore the input stream for the policy store data
*/
public void setPolicyStore(InputStream policyStore) {
this.policyStore = policyStore;
}
@DataEntry(sortBy = {"jansStatus"})
@ObjectClass(value = "adminUIPolicyStore")
public class AdminUIPolicyStore {
// Read-only on edit: settable only when creating the policy store.
@DN
@JsonView(Create.class)
@Schema(description = "Distinguished Name (DN) of the policy store entry. Server-generated on create; read-only and ignored on edit.", accessMode = Schema.AccessMode.READ_ONLY, example = "inum=e1a2b3c4-1234-5678-9abc-def012345678,ou=policy-stores,ou=admin-ui,o=jans")
private String dn;
@AttributeName(
ignoreDuringUpdate = true
)
@JsonView(Create.class)
@Schema(description = "Unique identifier (inum) of the policy store. Server-generated on create; read-only and ignored on edit.", accessMode = Schema.AccessMode.READ_ONLY, example = "e1a2b3c4-1234-5678-9abc-def012345678")
private String inum;
// Editable metadata: writable on both create and edit.
@AttributeName(name = "displayname")
@JsonView({Create.class, Edit.class})
@Schema(description = "Human-readable display name of the policy store.", example = "Admin UI Cedarling Policy Store")
private String displayname;
@AttributeName(name = "description")
@JsonView({Create.class, Edit.class})
@Schema(description = "Free-text description of the policy store and its purpose.", example = "Cedarling policy store used to derive Admin UI role-to-scope mappings")
private String description;
// Read-only on edit: the policy store document itself is immutable once uploaded.
@AttributeName(name = "document")
@JsonView(Create.class)
@Schema(description = "Base64-encoded Cedar policy store archive (.cjar zip). Required on create; immutable and ignored on edit.", example = "UEsDBBQACAgIAABb...==")
private String policyStore;
// Read-only on edit: owner cannot be reassigned via edit.
@AttributeName(name = "jansUsrDN")
@JsonView(Create.class)
@Schema(description = "DN of the user who owns the policy store. Set at create time; cannot be reassigned via edit.", example = "inum=abc123,ou=people,o=jans")
private String jansUsrDN;
// Editable: status may be changed on both create and edit.
@AttributeName(name = "jansStatus")
@JsonView({Create.class, Edit.class})
@Schema(description = "Status of the policy store. Only one store should be 'active' at a time; newly created stores default to 'inactive'.", allowableValues = {"active", "inactive"}, example = "active")
private String jansStatus;
// Read-only on edit: creation timestamp is fixed at create time.
@AttributeName(name = "creationDate")
@JsonView(Create.class)
@Schema(description = "Timestamp when the policy store was created. Server-managed and fixed at create time.", accessMode = Schema.AccessMode.READ_ONLY, example = "2026-07-14T10:15:30.000Z")
private Date creationDate = new Date();
// Server-managed: overwritten on every create/edit, so any client-supplied value is ignored.
@AttributeName(name = "jansLastUpd")
@Schema(description = "Timestamp of the last update. Server-managed and overwritten on every create/edit; any client-supplied value is ignored.", accessMode = Schema.AccessMode.READ_ONLY, example = "2026-07-14T11:20:45.000Z")
private Date jansLastUpd;

/**
* Retrieves the JSON `Document` supplied in the multipart form field named "document".
*
* @return the `Document` parsed from the multipart "document" field
*/
public Document getDocument() {
return document;
}
public String getDn() {
return dn;
}

/**
* Assigns the JSON document corresponding to the multipart form field named "document".
*
* @param document the JSON `Document` bound from the multipart form part named "document"
*/
public void setDocument(Document document) {
this.document = document;
}
public void setDn(String dn) {
this.dn = dn;
}

public String getInum() {
return inum;
}

public void setInum(String inum) {
this.inum = inum;
}

public String getDisplayname() {
return displayname;
}

public void setDisplayname(String displayname) {
this.displayname = displayname;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public String getPolicyStore() {
return policyStore;
}

public void setPolicyStore(String policyStore) {
this.policyStore = policyStore;
}

public String getJansUsrDN() {
return jansUsrDN;
}

public void setJansUsrDN(String jansUsrDN) {
this.jansUsrDN = jansUsrDN;
}

public String getJansStatus() {
return jansStatus;
}

public void setJansStatus(String jansStatus) {
this.jansStatus = jansStatus;
}

public Date getCreationDate() {
return creationDate;
}

public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}

public Date getJansLastUpd() {
return jansLastUpd;
}

public void setJansLastUpd(Date jansLastUpd) {
this.jansLastUpd = jansLastUpd;
}

/**
* Produce a string representation of this AdminUIPolicyStore that includes the `policyStore` field.
*
* @return a string containing the class name and the `policyStore` value
*/
@Override
public String toString() {
return "AdminUIPolicyStore{" +
"document=" + document +
", policyStore=" + policyStore +
'}';
@Override
public String toString() {
return "AdminUIPolicyStore{" +
"dn='" + dn + '\'' +
", inum='" + inum + '\'' +
", displayname='" + displayname + '\'' +
", description='" + description + '\'' +
", policyStore='" + policyStore + '\'' +
", jansUsrDN='" + jansUsrDN + '\'' +
", jansStatus='" + jansStatus + '\'' +
", creationDate=" + creationDate +
", jansLastUpd=" + jansLastUpd +
'}';
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.jans.ca.plugin.adminui.model.adminui;

/**
* Jackson {@code @JsonView} marker interfaces used to control which
* {@link AdminUIPolicyStore} fields may be supplied by clients on different
* REST operations.
*
* <ul>
* <li>{@link Create} - fields writable on POST (create).</li>
* <li>{@link Edit} - fields writable on PUT (edit). Read-only fields
* (e.g. {@code inum}, {@code dn}, {@code creationDate},
* {@code jansUsrDN}, {@code policyStore}) are intentionally excluded
* from this view so they cannot be modified once created.</li>
* </ul>
*/
public final class PolicyStoreViews {

private PolicyStoreViews() {
}

/** Fields accepted when creating a policy store (POST). */
public interface Create {
}

/** Fields accepted when editing an existing policy store (PUT). */
public interface Edit {
}
}
Loading
Loading