Defining permissions was your first step; now you’re ready to register the permissions you’ve defined. You must register your entities both in the database and in the permissions service running in the OSGi container.
Registering Permissions Resources in the Database
All this takes is a call to Liferay’s resource service in your service layer. If you’re using Service Builder, this is very easy to do.
-
Open your
-LocalServiceImpl
class. -
In your method that adds an entity, add a call to add a resource with the entity. For example, Liferay’s Blogs application adds resources this way:
resourceLocalService.addResources( entry.getCompanyId(), entry.getGroupId(), entry.getUserId(), BlogsEntry.class.getName(), entry.getEntryId(), false, addGroupPermissions, addGuestPermissions);
This method requires passing in the company ID, the group ID, the user ID, the entity’s class name, the entity’s primary key, and some boolean settings. In order, these settings define
- Whether the permission is a portlet resource
- Whether the default group permissions defined in
default.xml
should be added - Whether the default guest permissions defined in
default.xml
should be added
Note that the resource local service is injected automatically into your Service Builder-generated service.
If you’re not using Service Builder, but you are using OSGi modules for your
application, you should be able to inject the resource service with an
@Reference
annotation. If you’re building a WAR-style plugin, you need
a service tracker to
gain access to the service. Note that your model classes must also implement
Liferay’s ClassedModel
interface.
Similarly, when you delete an entity, you should also delete its associated
resource. Here’s how the Blogs application does it in its deleteEntry()
method:
resourceLocalService.deleteResource(
entry.getCompanyId(), BlogsEntry.class.getName(),
ResourceConstants.SCOPE_INDIVIDUAL, entry.getEntryId());
As with adding resources, the method needs to know the entity’s company ID, class, and primary key. Most of the time, its scope is an individual entity of your own choosing. Other scopes available as constants are for company, group, or group template (site template). These are used internally for those objects, so you’d only use them if you were customizing functionality for creating and deleting them.
Now you’re ready to register your entities with the permissions service.
Registering Entities to the Permissions Service
The permissions service that’s running must know about your entities and how to check permissions for them. This requires creating a permissions registrar class.
-
In your service bundle, create a package that by convention ends in
internal.security.permission.resource
. For example, the Blogs application’s package is namedcom.liferay.blogs.internal.security.permission.resource
. -
Create a class in this package called
[Entity Name]ModelResourcePermissionRegistrar
. For example, the Blogs application’s class is namedBlogsEntryModelResourcePermissionRegistrar
. -
This class is a component class that requires overriding the
activate
method to register the permissions logic you want for your entities. For example, this is how the Blogs application registers its permissions:@Component(immediate = true) public class BlogsEntryModelResourcePermissionRegistrar { @Activate public void activate(BundleContext bundleContext) { Dictionary<String, Object> properties = new HashMapDictionary<>(); properties.put("model.class.name", BlogsEntry.class.getName()); _serviceRegistration = bundleContext.registerService( ModelResourcePermission.class, ModelResourcePermissionFactory.create( BlogsEntry.class, BlogsEntry::getEntryId, _blogsEntryLocalService::getEntry, _portletResourcePermission, (modelResourcePermission, consumer) -> { consumer.accept( new StagedModelPermissionLogic<>( _stagingPermission, BlogsPortletKeys.BLOGS, BlogsEntry::getEntryId)); consumer.accept( new WorkflowedModelPermissionLogic<>( _workflowPermission, modelResourcePermission, BlogsEntry::getEntryId)); }), properties); } @Deactivate public void deactivate() { _serviceRegistration.unregister(); } @Reference private BlogsEntryLocalService _blogsEntryLocalService; @Reference(target = "(resource.name=" + BlogsConstants.RESOURCE_NAME + ")") private PortletResourcePermission _portletResourcePermission; private ServiceRegistration<ModelResourcePermission> _serviceRegistration; @Reference private StagingPermission _stagingPermission; @Reference private WorkflowPermission _workflowPermission; }
We call these types of classes Registrars because the classes’ job is to configure,
register and unregister the ModelResourcePermission
.
-
The
model.class.name
is set in the properties so that other modules’ service trackers can find this model resource permission by its type when it’s needed. Liferay has several service trackers checking for model resource permissions. Theservice.ranking
property can also be set to a value greater than zero to override other module’s model resource permissions. -
This registrar uses two portal-kernel permission logic classes for Staging and Workflow. Custom logic classes can be reused or composed inline since
ModelResourcePermissionLogic
is a@FunctionalInterface
. Permission logic classes are executed in order of when they are accepted in theConsumer
. -
ModelResourcePermissionLogic
classes returntrue
when users have permission for the action,false
when they are denied permission for the action, andnull
when wanting to delegate responsibility to the next permission logic. If all permission logics return null then thePermissionChecker.hasPermission
method is called to determine if the action is allowed for the user.
This class uses an @Reference
with the target filter to inject the appropriate
PortletResourcePermission
. BlogsConstants.RESOURCE_NAME
evaluates to
com.liferay.blogs
, which is defined in the default.xml
you created earlier.
If you were to reference this ModelResourcePermission
, you’d use a target filter
matching the model.class.name
property set in the activate
method.
Note that you specify your entity’s class, primary key, and the entity itself for the factory so it can create permission objects specific to your entity.
Great! You’ve now completed step 2 in DRAC by registering your permissions. Now you’re ready to provide users the interface to associate permissions with resources.