Skip to content

Commit

Permalink
fixes #47 - changes ApplicationUser#getTenancy to #getAtPath (ditto f…
Browse files Browse the repository at this point in the history
…or the example TenantedEntity entity); renames WithApplicationTenancy to WithAtPath.
  • Loading branch information
danhaywood committed Dec 5, 2016
1 parent 5bea074 commit 69d7e0e
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.apache.isis.applib.annotation.SemanticsOf;
import org.apache.isis.applib.annotation.Title;
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.services.factory.FactoryService;
import org.apache.isis.applib.util.ObjectContracts;

import org.isisaddons.module.security.SecurityModule;
Expand Down Expand Up @@ -171,7 +172,6 @@ public static class PathDomainEvent extends PropertyDomainEvent<String> {}

public static class UsersDomainEvent extends CollectionDomainEvent<ApplicationUser> {}

@javax.jdo.annotations.Persistent(mappedBy = "tenancy")
@Collection(
domainEvent = UsersDomainEvent.class,
editing = Editing.DISABLED
Expand All @@ -180,17 +180,17 @@ public static class UsersDomainEvent extends CollectionDomainEvent<ApplicationUs
render = RenderType.EAGERLY
)
@MemberOrder(sequence = "10")
@Getter @Setter
private SortedSet<ApplicationUser> users = new TreeSet<>();

public List<ApplicationUser> getUsers() {
return applicationUserRepository.findByAtPath(getPath());
}

// necessary for integration tests
public void addToUsers(final ApplicationUser applicationUser) {
getUsers().add(applicationUser);
applicationUser.setAtPath(getPath());
}
// necessary for integration tests
public void removeFromUsers(final ApplicationUser applicationUser) {
getUsers().remove(applicationUser);
applicationUser.setAtPath(null);
}
//endregion

Expand All @@ -207,7 +207,7 @@ public static class AddUserDomainEvent extends ActionDomainEvent {}
)
@MemberOrder(name="Users", sequence = "1")
public ApplicationTenancy addUser(final ApplicationUser applicationUser) {
applicationUser.setTenancy(this);
applicationUser.setAtPath(this.getPath());
// no need to add to users set, since will be done by JDO/DN.
return this;
}
Expand All @@ -219,6 +219,8 @@ public List<ApplicationUser> autoComplete0AddUser(final String search) {
return list;
}



//endregion

//region > removeUser (action)
Expand All @@ -234,7 +236,7 @@ public static class RemoveUserDomainEvent extends ActionDomainEvent {}
)
@MemberOrder(name="Users", sequence = "2")
public ApplicationTenancy removeUser(final ApplicationUser applicationUser) {
applicationUser.setTenancy(null);
applicationUser.setAtPath(null);
// no need to add to users set, since will be done by JDO/DN.
return this;
}
Expand Down Expand Up @@ -369,7 +371,7 @@ public static class DeleteDomainEvent extends ActionDomainEvent {}
@MemberOrder(sequence = "1")
public List<ApplicationTenancy> delete() {
for (final ApplicationUser user : getUsers()) {
user.updateTenancy(null);
user.updateAtPath(null);
}
container.removeIfNotAlready(this);
container.flush();
Expand Down Expand Up @@ -397,6 +399,8 @@ public int compareTo(final ApplicationTenancy o) {
@javax.inject.Inject
ApplicationTenancyRepository applicationTenancyRepository;
@javax.inject.Inject
FactoryService factoryService;
@javax.inject.Inject
DomainObjectContainer container;
//endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@
package org.isisaddons.module.security.dom.tenancy;

/**
* Role interface for domain objects to implement, indicating whether they are logically &quot;owned&quot; by a
* particular {@link org.isisaddons.module.security.dom.tenancy.ApplicationTenancy}.
* Role interface for domain objects to implement, indicating that these are characteristics of the entity that
* can be used to determine its visibility/editability.
*
* <p>
* The intention here is that the security module can implement instance-based security according to the following table:
* Previously the <code>atPath</code> would have corresponded to the unique path of some particular
* {@link org.isisaddons.module.security.dom.tenancy.ApplicationTenancy} instance. However, this has now been
* generalized; the atPath is simply a string whose interpretation is application-specific (in particular by
* the {@link ApplicationTenancyEvaluator} SPI).
* </p>
*
* <p>
* For applications that still wish to follow the original more specific design (that the <code>atPath</code>
* corresponds to a single {@link ApplicationTenancy}), then the path can be interpreted according to the following
* table:
* </p>
* <table border="1">
* <tr>
Expand Down Expand Up @@ -88,11 +97,11 @@
* <td>/it/car</td><td>null</td><td>not visible</td>
* </tr>
* </table>
* <p>any object that is not tenanted (that is, its class does not implement {@link org.isisaddons.module.security.dom.tenancy.WithApplicationTenancy the WithApplicationTenancy interface} is accessible by any user (usual permission rules apply).
* <p>any object that is not tenanted (that is, its class does not implement {@link WithAtPath the WithApplicationTenancy interface} is accessible by any user (usual permission rules apply).
* </p>
*/
public interface WithApplicationTenancy {
public interface WithAtPath {

ApplicationTenancy getApplicationTenancy();
String getAtPath();

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.InheritanceStrategy;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.VersionStrategy;

import com.google.common.base.Strings;
Expand All @@ -40,7 +39,6 @@
import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.applib.annotation.DomainObjectLayout;
import org.apache.isis.applib.annotation.Editing;
import org.apache.isis.applib.annotation.LabelPosition;
import org.apache.isis.applib.annotation.MemberGroupLayout;
import org.apache.isis.applib.annotation.MemberOrder;
import org.apache.isis.applib.annotation.Optionality;
Expand All @@ -57,16 +55,17 @@
import org.apache.isis.applib.services.HasUsername;
import org.apache.isis.applib.util.ObjectContracts;
import org.apache.isis.applib.value.Password;
import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;

import org.isisaddons.module.security.SecurityModule;
import org.isisaddons.module.security.dom.password.PasswordEncryptionService;
import org.isisaddons.module.security.dom.permission.ApplicationPermission;
import org.isisaddons.module.security.dom.permission.ApplicationPermissionMode;
import org.isisaddons.module.security.dom.permission.ApplicationPermissionRepository;
import org.isisaddons.module.security.dom.permission.ApplicationPermissionValueSet;
import org.isisaddons.module.security.dom.permission.PermissionsEvaluationService;
import org.isisaddons.module.security.dom.role.ApplicationRole;
import org.isisaddons.module.security.dom.role.ApplicationRoleRepository;
import org.isisaddons.module.security.dom.tenancy.ApplicationTenancy;
import org.isisaddons.module.security.seed.scripts.IsisModuleSecurityAdminRoleAndPermissions;
import org.isisaddons.module.security.seed.scripts.IsisModuleSecurityAdminUser;

Expand Down Expand Up @@ -99,6 +98,11 @@
value = "SELECT "
+ "FROM org.isisaddons.module.security.dom.user.ApplicationUser "
+ "WHERE emailAddress == :emailAddress"),
@javax.jdo.annotations.Query(
name = "findByAtPath", language = "JDOQL",
value = "SELECT "
+ "FROM org.isisaddons.module.security.dom.user.ApplicationUser "
+ "WHERE atPath == :atPath"),
@javax.jdo.annotations.Query(
name = "findByName", language = "JDOQL",
value = "SELECT "
Expand Down Expand Up @@ -128,7 +132,7 @@
@MemberGroupLayout(columnSpans = {4,4,4,12},
left = {"Id", "Name", "Metadata"},
middle= {"Contact Details"},
right= {"Status", "Tenancy"}
right= {"Status", "AtPath"}
)
public class ApplicationUser implements Comparable<ApplicationUser>, HasUsername {

Expand Down Expand Up @@ -473,40 +477,41 @@ public String disableUpdateFaxNumber(final String faxNumber) {

//endregion

//region > tenancy (property)
//region > atPath (property)

public static class TenancyDomainEvent extends PropertyDomainEvent<ApplicationTenancy> {}
public static class AtPathDomainEvent extends PropertyDomainEvent<String> {}


@javax.jdo.annotations.Column(name = "atPath", allowsNull="true")
@Property(
domainEvent = TenancyDomainEvent.class,
domainEvent = AtPathDomainEvent.class,
editing = Editing.DISABLED
)
@MemberOrder(name="Tenancy", sequence = "3.4")
@MemberOrder(name="atPath", sequence = "3.4")
@Getter @Setter
private ApplicationTenancy tenancy;
private String atPath;

//endregion

//region > updateTenancy (action)
//region > updateAtPath (action)

public static class UpdateTenancyDomainEvent extends ActionDomainEvent {}
public static class UpdateAtPathDomainEvent extends ActionDomainEvent {}

@Action(
domainEvent = UpdateTenancyDomainEvent.class,
domainEvent = UpdateAtPathDomainEvent.class,
semantics = SemanticsOf.IDEMPOTENT
)
@MemberOrder(name="tenancy", sequence = "1")
public ApplicationUser updateTenancy(
@MemberOrder(name="atPath", sequence = "1")
public ApplicationUser updateAtPath(
@Parameter(optionality = Optionality.OPTIONAL)
final ApplicationTenancy tenancy) {
setTenancy(tenancy);
@ParameterLayout(named = "AtPath")
final String atPath) {
setAtPath(atPath);
return this;
}

public ApplicationTenancy default0UpdateTenancy() {
return getTenancy();
public String default0UpdateAtPath() {
return getAtPath();
}
//endregion

Expand Down Expand Up @@ -977,7 +982,7 @@ public String toString() {

/**
* Optional service, if configured then is used to evaluate permissions within
* {@link org.isisaddons.module.security.dom.permission.ApplicationPermissionValueSet#evaluate(ApplicationFeatureId, org.isisaddons.module.security.dom.permission.ApplicationPermissionMode)},
* {@link org.isisaddons.module.security.dom.permission.ApplicationPermissionValueSet#evaluate(ApplicationFeatureId, ApplicationPermissionMode)}
* else will fallback to a {@link org.isisaddons.module.security.dom.permission.PermissionsEvaluationService#DEFAULT default}
* implementation.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,19 @@ public ApplicationUser newLocalUserBasedOn(
}
//endregion


//region > allUsers

@Programmatic
public List<ApplicationUser> findByAtPath(final String atPath) {
return container.allMatches(new QueryDefault<>(
ApplicationUser.class,
"findByAtPath", "atPath", atPath));
}

//endregion


//region > allUsers

@Programmatic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
*/
package org.isisaddons.module.security.facets;

import java.util.concurrent.Callable;

import javax.inject.Inject;

import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
import org.isisaddons.module.security.dom.tenancy.ApplicationTenancy;

import org.isisaddons.module.security.dom.tenancy.ApplicationTenancyEvaluator;
import org.isisaddons.module.security.dom.tenancy.ApplicationTenancyPathEvaluator;
import org.isisaddons.module.security.dom.user.ApplicationUser;

import javax.inject.Inject;
import java.util.concurrent.Callable;

class ApplicationTenancyEvaluatorUsingPaths implements ApplicationTenancyEvaluator {

private final ApplicationTenancyPathEvaluator evaluator;
Expand Down Expand Up @@ -138,11 +139,7 @@ protected String userTenancyPathFor(final ApplicationUser applicationUser) {
if (evaluator.handles(applicationUser.getClass())) {
return evaluator.applicationTenancyPathFor(applicationUser);
}
final ApplicationTenancy userTenancy = applicationUser.getTenancy();
if (userTenancy == null) {
return null;
}
return userTenancy.getPath();
return applicationUser.getAtPath();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@
import org.isisaddons.module.security.dom.tenancy.ApplicationTenancy;
import org.isisaddons.module.security.dom.tenancy.ApplicationTenancyEvaluator;
import org.isisaddons.module.security.dom.tenancy.ApplicationTenancyPathEvaluator;
import org.isisaddons.module.security.dom.tenancy.WithApplicationTenancy;
import org.isisaddons.module.security.dom.tenancy.WithAtPath;
import org.isisaddons.module.security.dom.user.ApplicationUserRepository;

import javax.annotation.Nullable;
import java.util.List;
import java.util.stream.Collectors;

public class TenantedAuthorizationFacetFactory extends FacetFactoryAbstract implements ServicesInjectorAware {

Expand Down Expand Up @@ -119,16 +117,14 @@ static class ApplicationTenancyPathEvaluatorDefault implements ApplicationTenanc

@Override
public boolean handles(final Class<?> cls) {
return WithApplicationTenancy.class.isAssignableFrom(cls);
return WithAtPath.class.isAssignableFrom(cls);
}

public String applicationTenancyPathFor(final Object domainObject) {
// always safe, facet factory only installs facet for classes implementing WithApplicationTenancy
final WithApplicationTenancy tenantedObject = (WithApplicationTenancy) domainObject;
final WithAtPath tenantedObject = (WithAtPath) domainObject;

final ApplicationTenancy objectTenancy = tenantedObject.getApplicationTenancy();
final String objectTenancyPath = objectTenancy == null ? null : objectTenancy.getPath();
return objectTenancyPath;
return tenantedObject.getAtPath();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
import org.isisaddons.module.security.dom.password.PasswordEncryptionService;
import org.isisaddons.module.security.dom.role.ApplicationRole;
import org.isisaddons.module.security.dom.role.ApplicationRoleRepository;
import org.isisaddons.module.security.dom.tenancy.ApplicationTenancy;
import org.isisaddons.module.security.dom.tenancy.ApplicationTenancyRepository;
import org.isisaddons.module.security.dom.user.AccountType;
import org.isisaddons.module.security.dom.user.ApplicationUser;
import org.isisaddons.module.security.dom.user.ApplicationUserRepository;
Expand Down Expand Up @@ -84,8 +82,7 @@ protected void execute(final ExecutionContext executionContext) {
}

// update tenancy (repository checks for null)
final ApplicationTenancy applicationTenancy = applicationTenancyRepository.findByPath(tenancyPath);
applicationUser.setTenancy(applicationTenancy);
applicationUser.setAtPath(tenancyPath);

for (final String roleName : roleNames) {
final ApplicationRole securityRole = applicationRoleRepository.findByName(roleName);
Expand All @@ -108,10 +105,6 @@ public ApplicationUser getApplicationUser() {
ApplicationUserRepository applicationUserRepository;
@Inject
ApplicationRoleRepository applicationRoleRepository;
@Inject
ApplicationTenancyRepository applicationTenancyRepository;
@Inject
PasswordEncryptionService passwordEncryptionService;
//endregion

}
Loading

0 comments on commit 69d7e0e

Please sign in to comment.