In runtime this code works:
// Service class
class UserService {
ApiClient api
User create(User user) throws EmailTakenException, UsernameTakenException {
User savedUser
try {
savedUser = api.users.create user
setEnabled savedUser.id, true
return savedUser
}
catch(ApiException ex) {
switch(ex.subStatus) {
case SubStatus.USERS_EMAIL_TAKEN:
throw new EmailTakenException()
break
case SubStatus.USERS_USERNAME_TAKEN:
throw new UsernameTakenException()
break
}
}
}
}
called from a controller:
// Controller class, an action
def create(CreateCommand cmd) {
if(request.get) {
render view: 'create'
return
}
if(!cmd.validate()) {
flash.model = cmd
redirect action: 'create'
return
}
def user = new User()
bindData user, params
try {
userService.create user
flash.success = 'ui.save.success'
}
catch(EmailTakenException ex) {
flash.model = cmd
flash.error = 'ui.email.taken'
}
catch(UsernameTakenException ex) {
flash.model = cmd
flash.error = 'ui.username.taken'
}
redirect action: 'create'
}
The "User", "SubStatus", and "ApiException" class comes from a jar library dependency. The ApiClient throws an ApiException when something goes wrong.
In runtime this code works perfectly, but when I write a Spec for this, it throws an UndeclaredThrowableException. Here's the Spock Specification:
ApiClient api
UsersApi apiUsers
void setup() {
api = Mock()
apiUsers = Mock()
api.users >> apiUsers
service.api = api
}
def "create: it should be able to throw an exception when email is already taken"() {
setup:
def user = new User(email: 'foo#cod.com', username: 'foo', name: 'Bar Foo')
def exception = Mock(ApiException)
exception.subStatus >> SubStatus.USERS_EMAIL_TAKEN
when:
service.create user
then:
thrown(EmailTakenException) // GrailsException is runtime
1 * apiUsers.create(_ as User) >> { throw new ApiException(400, SubStatus.USERS_EMAIL_TAKEN, null) }
}
Maybe you could rewrite your test using the #FailsWith annotation?
http://code.google.com/p/spock/wiki/SpockBasics#Extensions
Related
I have a SQL table user with 2 roles: ADMIN and USER.
I'm trying to use Java Authentication and Authorization Service(jaas) to make user with ADMIN role can read and modify other tables while USER role can read only.
I create a custom class extent java.security.Permission and a custom class extend
Policy class but I can't find any way to check permission with SecurityManager
PolicyImpl policy = new PolicyImpl();
Policy.setPolicy(policy);
Subject subject = loginContext.getSubject();
try {
Subject.doAsPrivileged(subject, (PrivilegedAction) () -> {
SecurityManager sm = System.getSecurityManager();
sm.checkSecurityAccess();
if (sm != null) {
sm.checkPermission(); // I don't know how to make this function check for
// SQL permission based on custom policy
}
return null;
}, null);
My Policy class
public class PolicyImpl extends Policy {
#Override
public PermissionCollection getPermissions(ProtectionDomain domain) {
List<Principal> principals = Arrays.asList(domain.getPrincipals());
if (principals.isEmpty()) {
return null;
}
BasicPermission basicPermission = null;
try {
for (Principal principal : principals) {
basicPermission = (BasicPermission) AccessController
.doPrivileged((PrivilegedExceptionAction) () -> Controller.getRoles(principal.getName()));
}
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
return basicPermission.newPermissionCollection();
}
}
It seems that java.security.FilePermission is the most suitable one since this permission has read and write property but I don't know how can I use this class for SQL Server.
I'm having some issues with Spring LocaleContextHolder.
I have the following code:
public void sendPasswordRecoverySmsAsync(String phone) {
CompletableFuture.runAsync(() -> {
sendPasswordRecoverySmsSync(phone);
});
}
public void sendPasswordRecoverySmsSync(String phone) {
User user = userDao.findByPhone(phone, User.class).orElseThrow(() -> new UserNotFoundException(phone));
log.info("User found, recovering password");
user.setUpdateTime(LocalDateTime.now());
userDao.save(user);
int otp = codesGenerator.generateOtp(user.getUpdateTime());
// Sends the SMS.
Locale locale = LocaleContextHolder.getLocale();
System.out.println("locale " + locale);
String appName = messageSource.getMessage("app.name", null, locale);
String smsContent = messageSource.getMessage("sms.password.recovery", new Object[] { otp }, locale);
Message message = new TextMessage(appName, phone, smsContent);
try {
smsClient.submitMessage(message);
} catch (NexmoClientException | IOException e) {
log.error("Error while sending recovery password message to phone number [{}]", phone, e);
throw new UserActivationException("Error while recovering password for user with phone: " + phone, e);
}
}
and this test:
#Before
public void setup() {
LocaleContextHolder.resetLocaleContext();
Mockito.when(tokenGenerator.generateOtp(Mockito.any())).thenReturn(14);
}
#Test(timeout = 3000)
public void testSendPasswordRecoverySmsAsyncError() throws Exception {
// Mocks.
LocaleContextHolder.setLocale(Locale.ENGLISH, true);
String mockPhone = "333";
User mockUser = mockModelBuilder.user(true, true);
Mockito.when(userDao.findByPhone(mockPhone, User.class)).then(r -> {
// TODO
return Optional.of(mockUser);
});
CountDownLatch latch = new CountDownLatch(1);
ArgumentCaptor<TextMessage> messageCaptor = ArgumentCaptor.forClass(TextMessage.class);
Mockito.when(smsClient.submitMessage(messageCaptor.capture())).then(r -> {
latch.countDown();
throw new NexmoClientException();
});
// Test.
service.sendPasswordRecoverySmsAsync(mockPhone);
latch.await();
// Assertions.
Assert.assertTrue(true);
TextMessage actualMessage = messageCaptor.getValue();
Assert.assertEquals("myApp", actualMessage.getFrom());
Assert.assertEquals(mockPhone, actualMessage.getTo());
Assert.assertEquals("Your password recovery code for myApp app is 14", actualMessage.getMessageBody());
}
I would expect the ouput of my test being "en" and this works properly if I launch only this one. However, when I run all my tests, the ouput is "it". This is probably either because in other tests I set an ITALIAN locale or because it's getting the system default.
But why is it getting the wrong one even when I'm resetting it explicitly?
For solely the purpose of testing such localization cases, you might just need to add the following on your test method. This will essentially mark the context Dirty and recreate it, depending on whether you mention as the context being Dirty either before or After the test execution.
#DirtiesContext(methodMode = MethodMode.AFTER_METHOD)
#Test(timeout = 3000)
public void testSendPasswordRecoverySmsAsyncError() throws Exception {...
Please refer the documentation here
Hope this helps, as it resolved a similar problem for me.
Quick background, our company connects to an ERP system (Sage) via web services for some functions. We have both c# (.net) and java code that performs calls to the Web Service (WS). Recently Sage introduced Basic Authentication into their WS.
Please note: This is a JAVA question, but I'll show an example in C# first to explain.
In the c# program, I first would create an object that is for accessing the WS:
var sageService = new CAdxWebServiceXmlCCServiceBasicAuth();
I then set up credential information:
var sageServiceCallContext = SageFactory.Instance.GetCallContext();
sageService.Credentials = new NetworkCredential(SageUser, SagePwd);
sageService.PreAuthenticate = true;
then finally the call to the specific web service method:
sageCustomerSvcResponse = sageService.run(sageServiceCallContext, "YTDPROF", sageCustomerRequestInXml);
When I set up the service object I use a custom class that looks like this:
public class CAdxWebServiceXmlCCServiceBasicAuth : CAdxWebServiceXmlCCService
{
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest webRequest = (HttpWebRequest)base.GetWebRequest(uri);
NetworkCredential credentials = Credentials as NetworkCredential;
if (credentials != null)
{
string authInfo = "";
if (credentials.Domain != null && credentials.Domain.Length > 0)
{
authInfo = string.Format(#"{0}\{1}:{2}", credentials.Domain, credentials.UserName, credentials.Password);
}
else
{
authInfo = string.Format(#"{0}:{1}", credentials.UserName, credentials.Password);
};
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
webRequest.Headers["Authorization"] = "Basic " + authInfo;
}
return webRequest;
}
}
What happens is that now, when I perform any call to the web service methods, the GetWebRequest from the class is invoked every time. This is how we implemented basis authentication in c#.
How do I do this in Java?
In the java code currently, I create the service object (that which accesses the web services) this way:
WebServiceInvoker service = new WebServiceInvoker(SageWSURL,"");
and the WebServiceInvoker looks like this (truncated for brevity):
public WebServiceInvoker(String url, String dummy) throws ServiceException, IOException {
serviceLocator = new CAdxWebServiceXmlCCServiceLocator();
service = serviceLocator.getCAdxWebServiceXmlCC(url);
cc = new CAdxCallContext();
cc.setCodeLang("ENG");
cc.setCodeUser("USER");
cc.setPassword("PAWWORD");
cc.setPoolAlias("POOL");
cc.setRequestConfig("adxwss.trace.on=on&adxwss.trace.size=16384&adonix.trace.on=on&adonix.trace.level=3&adonix.trace.size=8");
log = new PrintWriter(new BufferedWriter(new FileWriter("C:/Kalio/service/orders/log.txt")));
}
the webservice locator looks like this:
public class CAdxWebServiceXmlCCServiceLocator extends org.apache.axis.client.Service implements com.adonix.www.WSS.CAdxWebServiceXmlCCService {
public CAdxWebServiceXmlCCServiceLocator() {
}
public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC() throws javax.xml.rpc.ServiceException {
java.net.URL endpoint;
System.out.println("using local Sage Web Servivce URL:" + CAdxWebServiceXmlCC_address);
try {
endpoint = new java.net.URL(CAdxWebServiceXmlCC_address);
}
catch (java.net.MalformedURLException e) {
throw new javax.xml.rpc.ServiceException(e);
}
return getCAdxWebServiceXmlCC(endpoint);
}
public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
try {
com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub _stub = new com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub(portAddress, this);
_stub.setPortName(getCAdxWebServiceXmlCCWSDDServiceName());
return _stub;
}
catch (org.apache.axis.AxisFault e) {
return null;
}
}
and the specific method within that class is this:
public String getCustomer(String constructedXML) throws RemoteException {
**CAdxResultXml result = service.run(cc, "XTDPROF", constructedXML);**
CAdxMessage[] messages = result.getMessages();
for (int i = 0; i<messages.length; i++) {
CAdxMessage message = messages[i];
log.println("X3 get customer message: " + message.getMessage());
log.println("X3 get customer message type: " + message.getType());
}
return result.getResultXml();
}
So my questions is, how to I emulate that override that I see in the .net program in Java? It seems like it would be somewhere in either the service locator or invoker, but the program does not use standard http classes, but this adxwss stuff. I tried a straight c# to java conversion and that way didn't help. I have seen examples where basicAuth is implemented, but not against web service calls.
The c# is pretty clear cut, because once I create the service object using the basicAuth override, every web service calls goes through the orderride. How does that happen in Java?
I'll be happy to provide more info if needed and I'll continue to look/experiment, but at the moment I'm treading water.
Adding:
In tracing through the java code I found the specific web service call (run) where an apache "call" object is created. Is this where basicauth can be added?
public com.adonix.www.WSS.CAdxResultXml run(com.adonix.www.WSS.CAdxCallContext callContext, java.lang.String publicName, java.lang.String inputXml) throws java.rmi.RemoteException {
if (super.cachedEndpoint == null) {
throw new org.apache.axis.NoEndPointException();
}
org.apache.axis.client.Call _call = createCall();
_call.setOperation(_operations[0]);
_call.setUseSOAPAction(true);
_call.setSOAPActionURI("");
_call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
_call.setOperationName(new javax.xml.namespace.QName("http://www.adonix.com/WSS", "run"));
setRequestHeaders(_call);
setAttachments(_call);
try { java.lang.Object _resp = _call.invoke(new java.lang.Object[] {callContext, publicName, inputXml});
if (_resp instanceof java.rmi.RemoteException) {
throw (java.rmi.RemoteException)_resp;
}
else {
extractAttachments(_call);
try {
return (com.adonix.www.WSS.CAdxResultXml) _resp;
} catch (java.lang.Exception _exception) {
return (com.adonix.www.WSS.CAdxResultXml) org.apache.axis.utils.JavaUtils.convert(_resp, com.adonix.www.WSS.CAdxResultXml.class);
}
}
} catch (org.apache.axis.AxisFault axisFaultException) {
throw axisFaultException;
}
}
The solution I came up with is not elegant, but then I'm not a guru in Java, just know enough to be given these tasks.
Our company uses Sage as our ERP system and Sage has a WSDL to define the basic web services it provides.
Sage Web Servicew WSDL
In their latest version of Sage they went with basic authentication, but did not build it into the new WSDL. Since I could not seem to extend the class (CAdxWebServiceXmlCCService), I just copied/pasted a new class called CAdxWebServiceXmlCCServiceBasicAuth. The full code is shown below if anyone ever has need to deal with something like this in a web service.
The key point where BaiscAuth set set up is in the getCAdxWebServiceXmlCC method. I added setPassword and setUserName to the stub that is returned. What this accomplishes is that every time I perform a webservice method call, that stub is now part of the header.
package com.adonix.www.WSS;
import java.net.URL;
import java.util.Base64;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import javax.xml.rpc.ServiceException;
public class CAdxWebServiceXmlCCServiceBasicAuth extends org.apache.axis.client.Service implements com.adonix.www.WSS.CAdxWebServiceXmlCCService {
public CAdxWebServiceXmlCCServiceBasicAuth() {
}
public CAdxWebServiceXmlCCServiceBasicAuth(org.apache.axis.EngineConfiguration config) {
super(config);
}
public CAdxWebServiceXmlCCServiceBasicAuth(java.lang.String wsdlLoc, javax.xml.namespace.QName sName) throws javax.xml.rpc.ServiceException {
super(wsdlLoc, sName);
}
// Use to get a proxy class for CAdxWebServiceXmlCC
private java.lang.String CAdxWebServiceXmlCC_address = "http://10.28.0.7:8124/soap-generic/syracuse/collaboration/syracuse/CAdxWebServiceXmlCC";
public java.lang.String getCAdxWebServiceXmlCCAddress() {
return CAdxWebServiceXmlCC_address;
}
// The WSDD service name defaults to the port name.
private java.lang.String CAdxWebServiceXmlCCWSDDServiceName = "CAdxWebServiceXmlCC";
public java.lang.String getCAdxWebServiceXmlCCWSDDServiceName() {
return CAdxWebServiceXmlCCWSDDServiceName;
}
public void setCAdxWebServiceXmlCCWSDDServiceName(java.lang.String name) {
CAdxWebServiceXmlCCWSDDServiceName = name;
}
public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC(String userName,String password) throws javax.xml.rpc.ServiceException {
java.net.URL endpoint;
try {
endpoint = new java.net.URL(CAdxWebServiceXmlCC_address);
}
catch (java.net.MalformedURLException e) {
throw new javax.xml.rpc.ServiceException(e);
}
return getCAdxWebServiceXmlCC(endpoint,userName,password);
}
public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC(java.net.URL portAddress,String userName,String password) throws javax.xml.rpc.ServiceException {
try {
com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub _stub = new com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub(portAddress, this);
_stub.setPortName(getCAdxWebServiceXmlCCWSDDServiceName());
_stub.setPassword(password);
_stub.setUsername(userName);
return _stub;
}
catch (org.apache.axis.AxisFault e) {
return null;
}
}
public void setCAdxWebServiceXmlCCEndpointAddress(java.lang.String address) {
CAdxWebServiceXmlCC_address = address;
}
/**
* For the given interface, get the stub implementation.
* If this service has no port for the given interface,
* then ServiceException is thrown.
*/
public java.rmi.Remote getPort(Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
try {
if (com.adonix.www.WSS.CAdxWebServiceXmlCC.class.isAssignableFrom(serviceEndpointInterface)) {
com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub _stub = new com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub(new java.net.URL(CAdxWebServiceXmlCC_address), this);
_stub.setPortName(getCAdxWebServiceXmlCCWSDDServiceName());
return _stub;
}
}
catch (java.lang.Throwable t) {
throw new javax.xml.rpc.ServiceException(t);
}
throw new javax.xml.rpc.ServiceException("There is no stub implementation for the interface: " + (serviceEndpointInterface == null ? "null" : serviceEndpointInterface.getName()));
}
/**
* For the given interface, get the stub implementation.
* If this service has no port for the given interface,
* then ServiceException is thrown.
*/
public java.rmi.Remote getPort(javax.xml.namespace.QName portName, Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
if (portName == null) {
return getPort(serviceEndpointInterface);
}
java.lang.String inputPortName = portName.getLocalPart();
if ("CAdxWebServiceXmlCC".equals(inputPortName)) {
return getCAdxWebServiceXmlCC();
}
else {
java.rmi.Remote _stub = getPort(serviceEndpointInterface);
((org.apache.axis.client.Stub) _stub).setPortName(portName);
return _stub;
}
}
public javax.xml.namespace.QName getServiceName() {
return new javax.xml.namespace.QName("http://www.adonix.com/WSS", "CAdxWebServiceXmlCCService");
}
private java.util.HashSet ports = null;
public java.util.Iterator getPorts() {
if (ports == null) {
ports = new java.util.HashSet();
ports.add(new javax.xml.namespace.QName("http://www.adonix.com/WSS", "CAdxWebServiceXmlCC"));
}
return ports.iterator();
}
/**
* Set the endpoint address for the specified port name.
*/
public void setEndpointAddress(java.lang.String portName, java.lang.String address) throws javax.xml.rpc.ServiceException {
if ("CAdxWebServiceXmlCC".equals(portName)) {
setCAdxWebServiceXmlCCEndpointAddress(address);
}
else
{ // Unknown Port Name
throw new javax.xml.rpc.ServiceException(" Cannot set Endpoint Address for Unknown Port" + portName);
}
}
/**
* Set the endpoint address for the specified port name.
*/
public void setEndpointAddress(javax.xml.namespace.QName portName, java.lang.String address) throws javax.xml.rpc.ServiceException {
setEndpointAddress(portName.getLocalPart(), address);
}
#Override
public CAdxWebServiceXmlCC getCAdxWebServiceXmlCC() throws ServiceException {
// TODO Auto-generated method stub
return null;
}
#Override
public CAdxWebServiceXmlCC getCAdxWebServiceXmlCC(URL portAddress) throws ServiceException {
// TODO Auto-generated method stub
return null;
}
}
Hi All I am doing Junit testing on Spring MVC project. Here the following code
Method to be tested
public UserDetails getUserInfo(String userID) {
Session session = sessionFactory.getCurrentSession();
UserDetails userDetails = new UserDetails();
Query query = null;
try {
query = session.createQuery("From UserDetails where user_Id=:userID").setParameter("userID", userID);
List < UserDetails > list = query.list();
if (CollectionUtils.isNotEmpty(list)) {
userDetails = list.get(0);
} else {
throw new RuntimeException("No identifier found on our records! for '" + userID + "'");
}
} catch (Exception e) {
throw e;
}
return userDetails; }
I am testing it for both positive and negative cases.
Here is my negative testcase
#Autowired
DaoLayer layer;
#Rule
public ExpectedException thrown = ExpectedException.none();
#Test
#Transactional
public void getUserInfoNegative() throws Exception
{
String[] inputs={"W12348","ABCDEF","123456"};
for(int i=0;i<inputs.length;i++)
{
System.out.println("/****** Invoking getUserInfo with Input "+inputs[i]+" *********/");
String msg="No identifier found on our records! for '"+inputs[i]+"'";
thrown.expect(RuntimeException.class);
thrown.expectMessage(msg);
layer.getUserInfo(input);
}
}
Here I am trying to input wrong userID's and expecting runtime exception to be thrown. The code works fine it throws the expection along with the message. But the issue is it is invoking only one time for the first input, other input values are not executed. How Can I make it to work in loop??
Note: Junit testcase passed and shows green bar.
I have altered the code but that too doesnot work for loop. Where I am doing wrong??
#Test
#Transactional
public void getUserInfoNegative() throws Exception
{
String[] inputs={"W12348","ABCDEF","123456"};
for(int i=0;i<inputs.length;i++)
{
System.out.println("/****** Invoking getUserInfo with Input "+inputs[i]+" *********/");
String msg="No identifier found on our records! for '"+inputs[i]+"'";
getUser(msg,inputs[i]);
}
}
public void getUser(String msg,String input)
{
thrown.expect(RuntimeException.class);
thrown.expectMessage(msg);
layer.getUserInfo(input);
}
Is it possible to create Group and User in AEM6.2 by using Jackrabbit User Manager API with permissions.
I have just followed below URL's but the code is throwing some exception :
https://helpx.adobe.com/experience-manager/using/jackrabbit-users.html
https://stackoverflow.com/questions/38259047/how-to-give-permission-all-in-aem-through-programatically
ResourceResolverFactory getServiceResourceResolver throws Exception in AEM 6.1
As getAdministrativeResourceResolver(Map) method is deprecated then how can we use getServiceResourceResolver(Map) method instead.
Sharing my solution which will be helpful for others.
Following is the code using getServiceResourceResolver(Map) method for creating Group first and then User and then add user into group with ACL privileges and permission:
public void createGroupUser(SlingHttpServletRequest request) {
String userName = request.getParameter("userName");
String password = request.getParameter("password");
String groupName = request.getParameter("groupName");
Session session = null;
ResourceResolver resourceResolver = null;
try {
Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, "datawrite");
resourceResolver = resourceResolverFactory.getServiceResourceResolver(param);
session = resourceResolver.adaptTo(Session.class);
// Create UserManager Object
final UserManager userManager = AccessControlUtil.getUserManager(session);
// Create a Group
Group group = null;
if (userManager.getAuthorizable(groupName) == null) {
group = userManager.createGroup(groupName);
ValueFactory valueFactory = session.getValueFactory();
Value groupNameValue = valueFactory.createValue(groupName, PropertyType.STRING);
group.setProperty("./profile/givenName", groupNameValue);
session.save();
log.info("---> {} Group successfully created.", group.getID());
} else {
log.info("---> Group already exist..");
}
// Create a User
User user = null;
if (userManager.getAuthorizable(userName) == null) {
user = userManager.createUser(userName, password);
ValueFactory valueFactory = session.getValueFactory();
Value firstNameValue = valueFactory.createValue("Arpit", PropertyType.STRING);
user.setProperty("./profile/givenName", firstNameValue);
Value lastNameValue = valueFactory.createValue("Bora", PropertyType.STRING);
user.setProperty("./profile/familyName", lastNameValue);
Value emailValue = valueFactory.createValue("arpit.p.bora#gmail.com", PropertyType.STRING);
user.setProperty("./profile/email", emailValue);
session.save();
// Add User to Group
Group addUserToGroup = (Group) (userManager.getAuthorizable(groupName));
addUserToGroup.addMember(userManager.getAuthorizable(userName));
session.save();
// set Resource-based ACLs
String nodePath = user.getPath();
setAclPrivileges(nodePath, session);
log.info("---> {} User successfully created and added into group.", user.getID());
} else {
log.info("---> User already exist..");
}
} catch (Exception e) {
log.info("---> Not able to perform User Management..");
log.info("---> Exception.." + e.getMessage());
} finally {
if (session != null && session.isLive()) {
session.logout();
}
if (resourceResolver != null)
resourceResolver.close();
}
}
public static void setAclPrivileges(String path, Session session) {
try {
AccessControlManager aMgr = session.getAccessControlManager();
// create a privilege set
Privilege[] privileges = new Privilege[] {
aMgr.privilegeFromName(Privilege.JCR_VERSION_MANAGEMENT),
aMgr.privilegeFromName(Privilege.JCR_MODIFY_PROPERTIES),
aMgr.privilegeFromName(Privilege.JCR_ADD_CHILD_NODES),
aMgr.privilegeFromName(Privilege.JCR_LOCK_MANAGEMENT),
aMgr.privilegeFromName(Privilege.JCR_NODE_TYPE_MANAGEMENT),
aMgr.privilegeFromName(Replicator.REPLICATE_PRIVILEGE) };
AccessControlList acl;
try {
// get first applicable policy (for nodes w/o a policy)
acl = (AccessControlList) aMgr.getApplicablePolicies(path).nextAccessControlPolicy();
} catch (NoSuchElementException e) {
// else node already has a policy, get that one
acl = (AccessControlList) aMgr.getPolicies(path)[0];
}
// remove all existing entries
for (AccessControlEntry e : acl.getAccessControlEntries()) {
acl.removeAccessControlEntry(e);
}
// add a new one for the special "everyone" principal
acl.addAccessControlEntry(EveryonePrincipal.getInstance(), privileges);
// the policy must be re-set
aMgr.setPolicy(path, acl);
// and the session must be saved for the changes to be applied
session.save();
} catch (Exception e) {
log.info("---> Not able to perform ACL Privileges..");
log.info("---> Exception.." + e.getMessage());
}
}
In code "datawrite" is a service mapping which is mapped with system user in "Apache Sling Service User Mapper Service" which is configurable in the OSGI configuration admin interface.
For more detail about system user check link - How to Create System User in AEM?
I am providing this code direcly from a training of an official Adobe channel, and it is based on AEM 6.1. So I assume this might be the best practice.
private void modifyPermissions() {
Session adminSession = null;
try{
adminSession = repository.loginService(null, repository.getDefaultWorkspace());
UserManager userMgr= ((org.apache.jackrabbit.api.JackrabbitSession)adminSession).getUserManager();
AccessControlManager accessControlManager = adminSession.getAccessControlManager();
Authorizable denyAccess = userMgr.getAuthorizable("deny-access");
AccessControlPolicyIterator policyIterator =
accessControlManager.getApplicablePolicies(CONTENT_GEOMETRIXX_FR);
AccessControlList acl;
try{
acl=(JackrabbitAccessControlList) policyIterator.nextAccessControlPolicy();
}catch(NoSuchElementException nse){
acl=(JackrabbitAccessControlList) accessControlManager.getPolicies(CONTENT_GEOMETRIXX_FR)[0];
}
Privilege[] privileges = {accessControlManager.privilegeFromName(Privilege.JCR_READ)};
acl.addAccessControlEntry(denyAccess.getPrincipal(), privileges);
accessControlManager.setPolicy(CONTENT_GEOMETRIXX_FR, acl);
adminSession.save();
}catch (RepositoryException e){
LOGGER.error("**************************Repo Exception", e);
}finally{
if (adminSession != null)
adminSession.logout();
}