cancel
Showing results for 
Search instead for 
Did you mean: 

Create content with OpenCMIS using a user added with POST /api/people

juans
Champ on-the-rise
Champ on-the-rise
Hi

I successfully created the user unittestuser1 using this endpoint
Address: http://localhost:9090/alfresco/s/api/people
Http-Method: POST

I successfully created a folder /agencies/agency1 using OpenCMIS with admin user.

But when I tried to create the document test.txt in the folder /agencies/agency1 with OpenCMIS using the user unittestuser1 I get this error:


org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException: Unauthorized
   at org.apache.chemistry.opencmis.client.bindings.spi.atompub.AbstractAtomPubService.convertStatusCode(AbstractAtomPubService.java:466)
   at org.apache.chemistry.opencmis.client.bindings.spi.atompub.AbstractAtomPubService.post(AbstractAtomPubService.java:635)
   at org.apache.chemistry.opencmis.client.bindings.spi.atompub.ObjectServiceImpl.createDocument(ObjectServiceImpl.java:120)
   at org.apache.chemistry.opencmis.client.runtime.SessionImpl.createDocument(SessionImpl.java:1028)
   at org.apache.chemistry.opencmis.client.runtime.FolderImpl.createDocument(FolderImpl.java:75)
   at org.apache.chemistry.opencmis.client.runtime.FolderImpl.createDocument(FolderImpl.java:449)
   at test.documentlibrary.services.impl.DocumentLibraryImpl.createDocument(DocumentLibraryImpl.java:305)
   at test.documentlibrary.services.DocumentLibraryTest.createDocument_Success(DocumentLibraryTest.java:152)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:606)
   at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
   at org.testng.internal.MethodInvocationHelper$1.runTestMethod(MethodInvocationHelper.java:200)
   at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.run(AbstractTestNGSpringContextTests.java:175)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:606)
   at org.testng.internal.MethodInvocationHelper.invokeHookable(MethodInvocationHelper.java:212)
   at org.testng.internal.Invoker.invokeMethod(Invoker.java:707)
   at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
   at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
   at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
   at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
   at org.testng.TestRunner.privateRun(TestRunner.java:767)
   at org.testng.TestRunner.run(TestRunner.java:617)
   at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
   at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
   at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
   at org.testng.SuiteRunner.run(SuiteRunner.java:240)
   at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
   at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
   at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
   at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
   at org.testng.TestNG.run(TestNG.java:1057)
   at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:115)
   at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:207)
   at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:178)




I am creating the document like this:


      String filename = "test.txt";

      Session session = getUserSession(getLoggedUser());
      Folder rootAgency = (Folder) session.getObjectByPath("/agencies/agency1");

      // Create a Map of objects with the props we want to set
      Map <String, Object> properties = new HashMap<String, Object>();
      properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");      
      properties.put(PropertyIds.NAME, filename);
      
      // I am getting variables length, mimeType and inputStream as paramaters
      ContentStream contentStream = session.getObjectFactory().createContentStream(filename, length, mimeType, inputStream);

      Document doc = rootAgency.createDocument(
               properties,
               contentStream,
               VersioningState.MAJOR);





I thought it was because at user creation time I did not send any list of groups, so I deleted the user and created it again with the group Collaborator in the list of groups, something like this:

Address: http://localhost:9090/alfresco/s/api/people
Http-Method: POST
Content-Type: application/json
Payload:

{
"userName":"unittestuser1",
"firstName":"Test User Name",
"lastName":"Last Name for User Test",
"email":"testuser@company.com",
"password":"password",
"disableAccount":false,
"quota":-1,
"groups":["Collaborator"]
}


But, when I try to create the document I get the same error Smiley Sad

And when I try to see the groups of the user, I see he has no groups related:

GET http://localhost:9090/alfresco/s/api/people/unittestuser1?groups=true

{
   "url": "\/alfresco\/s\/api\/people\/unittestuser1",
   "userName": "unittestuser1",
   "enabled": true,
   "firstName": "Test User Name",
   "lastName": "Last Name for User Test",
   "jobtitle": null,
   "organization": null,
   "organizationId": null,
   "location": null,
   "telephone": null,
   "mobile": null,
   "email": "testuser@company.com",
   "companyaddress1": null,
   "companyaddress2": null,
   "companyaddress3": null,
   "companypostcode": null,
   "companytelephone": null,
   "companyfax": null,
   "companyemail": null,
   "skype": null,
   "instantmsg": null,
   "userStatus": null,
   "userStatusTime": null,
   "googleusername": null,
   "quota": -1,
   "sizeCurrent": 0,
   "emailFeedDisabled": false,
   "persondescription": null,
   "authorizationStatus": null,
   "isDeleted": false,
   "isAdminAuthority": false
,
   "capabilities":
   {
      "isAdmin":
      false
            ,"isMutable":
      true
            ,"isGuest":
      false
         },
   "groups": [
],
   "immutability":
   {
   }
}




I want the user to be able to create new content, delete content, edit existing content in that folder. And that is the definition of the Collaborator group right ?
What am I missing ?

1 ACCEPTED ANSWER

juans
Champ on-the-rise
Champ on-the-rise
I think I figured it out the questions I asked.

This is how I did it.

I created a group:

POST http://localhost:9090/alfresco/s/api/rootgroups/NewGroup
Payload
{"authority":"Group","shortName":"NewGroup"}

The response was something like this:

HTTP/1.1 201 Created
{
   "data":{
         "authorityType": "GROUP",
         "shortName": "NewGroup",
         "fullName": "GROUP_NewGroup",
         "displayName": "NewGroup",
         "url": "/api/groups/NewGroup"
           ,"zones":
           [
              "APP.DEFAULT",
              "AUTH.ALF"
           ]
}

}



I related the newly created user to this group like this:

Address: http://localhost:9090/alfresco/s/api/people
Http-Method: POST
Content-Type: application/json
Payload:

{
"userName":"unittestuser1",
"firstName":"Test User Name",
"lastName":"Last Name for User Test",
"email":"testuser@company.com",
"password":"password",
"disableAccount":false,
"quota":-1,
"groups":["GROUP_NewGroup"]
}


Now when I look for the user: http://localhost:9090/alfresco/s/api/people/unittestuser1?groups=true I get this part of the data populated:

"groups": [
   {
      "itemName": "GROUP_NewGroup",
      "displayName": "NewGroup"
   }],


And then I add a new ACL to the folder agency1 using this code:
<java>
   public Folder createFolder(String newFolderName, String baseFolderPath, Session session) {
      Folder root = (Folder) session.getObjectByPath(baseFolderPath);

      // Create a Map of objects with the props we want to set
      Map <String, Object> properties = new HashMap<String, Object>();

      properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");      
      properties.put(PropertyIds.NAME, newFolderName);

      Folder folderCreated = root.createFolder(properties);
      logger.info("Folder created, folderId: " + folderCreated.getId() + ", in path: " + folderCreated.getPath());

      String id = folderCreated.getId();
      OperationContext operationContext = new OperationContextImpl();
        operationContext.setIncludeAcls(true);
      // SHOW THE ACLS FOR THE CURRENT object
      printAcl(id, session, operationContext);
       
       
        // ADDING A NEW ACL
        String principal = "GROUP_NewGroup";
        RepositoryInfo repositoryInfo = session.getRepositoryInfo();
        AclCapabilities aclCapabilities = repositoryInfo.getAclCapabilities();

        Map<String, PermissionMapping> permissionMappings = aclCapabilities.getPermissionMapping();
       
        // I think this is the key part here. I am relating the permission CAN_CREATE_DOCUMENT_FOLDER to the
        // principal GROUP_NewGroup to the object with id: id (which is the folder I just created)
        PermissionMapping permissionMapping = permissionMappings.get(PermissionMapping.CAN_CREATE_DOCUMENT_FOLDER);

        List<String> permissions = permissionMapping.getPermissions();
        Ace addAce = session.getObjectFactory().createAce(principal, permissions);

        List<Ace> addAces = new LinkedList<Ace>();
        addAces.add(addAce);
       
        CmisObject obj = session.getObject(id, operationContext);
        obj.addAcl(addAces, AclPropagation.PROPAGATE);
       
       
        System.out.println("With newly added Acl");
        printAcl(id, session, operationContext);
      
      return folderCreated;
   }

   private void printAcl(String id, Session session,
         OperationContext operationContext) {
      CmisObject obj = session.getObject(id, operationContext);

        System.out.println("Acl for " + obj.getName() + ": ");

        Acl acl = obj.getAcl();
        for (Ace ace : acl.getAces()) {
            System.out.println(ace);
        }
        System.out.println("END Acl for " + obj.getName() + ".");
   }

</java>

Now the user can create documents in this folder. yey!!!! (I am so happy Smiley Very Happy !)

I have a question though. This user was able as well to create folders inside the folder, even though I did not assign the PermissionMapping.CAN_CREATE_FOLDER_FOLDER, why is that ? is there any way to allow the user to only create documents ? not folders ?

View answer in original post

5 REPLIES 5

jpotts
World-Class Innovator
World-Class Innovator
By default, objects inherit their permissions from their parent. The default permissions on the root folder is for everyone to have Consumer access. When you created agencies/agency1 you probably did not assign a group or a user to be a Collaborator on either of those folders. So when you try to create objects in those folders as "unittestuser1" it only has Consumer access.

You can check this programatically either by reading the ACE's of the folder object or asking the folder for the allowable actions and checking to see if create object is listed.

You could also log in to Alfresco using the test user you created and see that it cannot create anything in that folder.

To fix this, you could create a group and then assign that group to the agencies or agency1 folder. You can make the group assignment through CMIS, but you'll have to use an Alfresco REST API to create the group if you want to do that with code.

Also, note that adding a group name to the groups array when you create a person only works if that group already exists.

Jeff

juans
Champ on-the-rise
Champ on-the-rise
I am trying to create a Group with the Alfresco REST API, but I think I am looking in the wrong place:

In the list of webscripts: http://127.0.0.1:9090/alfresco/s/index/uri/ I only find these two endpoints that might allow me to create groups:
/api/groups
/api/groups/{shortName}/children/{fullAuthorityName}
/api/rootgroups
/api/rootgroups/{shortName}

In the documentation the only that allows me to create something is /api/groups/{shortName}/children/{fullAuthorityName} but it says that it is for add a group or user to a group.

So there should be some group already created.



Documentation for /api/groups/{shortName}/children/{fullAuthorityName}
http://127.0.0.1:9090/alfresco/s/index/uri/api/groups/%7BshortName%7D/children/%7BfullAuthorityName%...

Add group or user to a group
POST /alfresco/s/api/groups/{shortName}/children/{fullAuthorityName}
Description:   Adds a group or user to a group. The webscript will create a sub group if one does not already exist, with the fullAuthorityName.
You must have "administrator" privileges to modify groups.
If the authority is for a group and doe not exist then it is created.
The webscript returns Status_Created if a new group is created, otherwise it returns Status_OK. If Status_Created returns the new sub group, otherwise returns the group.


I went on and try to use the previous service, to see what happens, so I looked in the list of groups using http://127.0.0.1:9090/alfresco/s/api/groups to get the shortName of any of those.
What I see here is
1. some out-of-the-box groups like these ones:

{
   "data": [
{
         "authorityType": "GROUP",
         "shortName": "ALFRESCO_ADMINISTRATORS",
         "fullName": "GROUP_ALFRESCO_ADMINISTRATORS",
         "displayName": "ALFRESCO_ADMINISTRATORS",
         "url": "/api/groups/ALFRESCO_ADMINISTRATORS"
           ,"zones":
           [
              "APP.DEFAULT",
              "AUTH.ALF"
           ]
}
         ,
{
         "authorityType": "GROUP",
         "shortName": "ALFRESCO_MODEL_ADMINISTRATORS",
         "fullName": "GROUP_ALFRESCO_MODEL_ADMINISTRATORS",
         "displayName": "ALFRESCO_MODEL_ADMINISTRATORS",
         "url": "/api/groups/ALFRESCO_MODEL_ADMINISTRATORS"
           ,"zones":
           [
              "APP.DEFAULT",
              "AUTH.ALF"
           ]
}
         ,
{
         "authorityType": "GROUP",
         "shortName": "ALFRESCO_SEARCH_ADMINISTRATORS",
         "fullName": "GROUP_ALFRESCO_SEARCH_ADMINISTRATORS",
         "displayName": "ALFRESCO_SEARCH_ADMINISTRATORS",
         "url": "/api/groups/ALFRESCO_SEARCH_ADMINISTRATORS"
           ,"zones":
           [
              "APP.DEFAULT",
              "AUTH.ALF"
           ]
}
         ,
{
         "authorityType": "GROUP",
         "shortName": "EMAIL_CONTRIBUTORS",
         "fullName": "GROUP_EMAIL_CONTRIBUTORS",
         "displayName": "EMAIL_CONTRIBUTORS",
         "url": "/api/groups/EMAIL_CONTRIBUTORS"
           ,"zones":
           [
              "APP.DEFAULT",
              "AUTH.ALF"
           ]
}
         ,
{
         "authorityType": "GROUP",
         "shortName": "SITE_ADMINISTRATORS",
         "fullName": "GROUP_SITE_ADMINISTRATORS",
         "displayName": "SITE_ADMINISTRATORS",
         "url": "/api/groups/SITE_ADMINISTRATORS"
           ,"zones":
           [
              "APP.DEFAULT",
              "AUTH.ALF"
           ]
}


2. Other groups related with test sites I created in Share (and a ReadOnlyRole (site_sitetest1_{http:\/\/www.alfresco.org\/model\/site\/1.0}site.ReadOnlyRole) I was playing with creating new Roles (but actually I still do not know how to use it), but this is not part of this question)

{
         "authorityType": "GROUP",
         "shortName": "site_sitetest1",
         "fullName": "GROUP_site_sitetest1",
         "displayName": "site_sitetest1",
         "url": "/api/groups/site_sitetest1"
           ,"zones":
           [
              "APP.SHARE",
              "AUTH.ALF"
           ]
}
         ,
{
         "authorityType": "GROUP",
         "shortName": "site_sitetest1_{http:\/\/www.alfresco.org\/model\/site\/1.0}site.ReadOnlyRole",
         "fullName": "GROUP_site_sitetest1_{http:\/\/www.alfresco.org\/model\/site\/1.0}site.ReadOnlyRole",
         "displayName": "site_sitetest1_{http:\/\/www.alfresco.org\/model\/site\/1.0}site.ReadOnlyRole",
         "url": "/api/groups/site_sitetest1_%7Bhttp%3A%2F%2Fwww.alfresco.org%2Fmodel%2Fsite%2F1.0%7Dsite.ReadOnlyRole"
           ,"zones":
           [
              "APP.SHARE",
              "AUTH.ALF"
           ]
}
         ,
{
         "authorityType": "GROUP",
         "shortName": "site_sitetest1_SiteCollaborator",
         "fullName": "GROUP_site_sitetest1_SiteCollaborator",
         "displayName": "site_sitetest1_SiteCollaborator",
         "url": "/api/groups/site_sitetest1_SiteCollaborator"
           ,"zones":
           [
              "APP.SHARE",
              "AUTH.ALF"
           ]
}
         ,
{
         "authorityType": "GROUP",
         "shortName": "site_sitetest1_SiteConsumer",
         "fullName": "GROUP_site_sitetest1_SiteConsumer",
         "displayName": "site_sitetest1_SiteConsumer",
         "url": "/api/groups/site_sitetest1_SiteConsumer"
           ,"zones":
           [
              "APP.SHARE",
              "AUTH.ALF"
           ]
}
         ,
{
         "authorityType": "GROUP",
         "shortName": "site_sitetest1_SiteContributor",
         "fullName": "GROUP_site_sitetest1_SiteContributor",
         "displayName": "site_sitetest1_SiteContributor",
         "url": "/api/groups/site_sitetest1_SiteContributor"
           ,"zones":
           [
              "APP.SHARE",
              "AUTH.ALF"
           ]
}
         ,
{
         "authorityType": "GROUP",
         "shortName": "site_sitetest1_SiteManager",
         "fullName": "GROUP_site_sitetest1_SiteManager",
         "displayName": "site_sitetest1_SiteManager",
         "url": "/api/groups/site_sitetest1_SiteManager"
           ,"zones":
           [
              "APP.SHARE",
              "AUTH.ALF"
           ]
}



3. And a group I created manually in Share (and the paging object)

{
         "authorityType": "GROUP",
         "shortName": "TestJuanSanin",
         "fullName": "GROUP_TestJuanSanin",
         "displayName": "TestJuanSanin",
         "url": "/api/groups/TestJuanSanin"
           ,"zones":
           [
              "APP.DEFAULT",
              "AUTH.ALF"
           ]
}
         
   ]

  ,
    "paging":
    {
      "maxItems": 2147483647,
      "skipCount": 0,
      "totalItems": 27,
      "totalItemsRangeEnd": null,
      "confidence": "exact"
    }
}



I took site_sitetest1_SiteCollaborator group and made a POST call to http://localhost:9090/alfresco/s/api/groups/site_sitetest1_SiteCollaborator/children/NewGroup

But I got a

Method failed: HTTP/1.1 500 Internal Server Error
{
   "data":  { }
}


This is the java code I used:
<java>
      HttpClient client = new HttpClient();
      client.getState().setCredentials(
            new AuthScope("localhost", 9090, "Alfresco"),
            new UsernamePasswordCredentials("admin", "password"));
      

      String apiurl = "http://localhost:9090/alfresco/s/api/groups/site_sitetest1_SiteCollaborator/children/NewGroup";
      
      PostMethod post = new PostMethod(apiurl);
      try {

         post.setDoAuthentication(true);
         post.setRequestHeader("Content-Type", "application/json");

         int status = client.executeMethod(post);
         if (status != HttpStatus.SC_OK) {
            System.err.println("Method failed: " + post.getStatusLine());
         }
         String resultString = post.getResponseBodyAsString();
         System.out.println(resultString);
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         post.releaseConnection();
      }

</java>



So I guess this is not the service I should be looking at, right ?

1. Could you point me to the service to create new Groups ?
2. How do I tell this newly created group that it has a "Collaborator" permissionGroup ?

      <!– A collaborator can do anything that an editor and a contributor can do –>
      <permissionGroup name="Collaborator" allowFullControl="false" expose="true">
         <includePermissionGroup permissionGroup="Editor" type="cm:cmobject" />
         <includePermissionGroup permissionGroup="Contributor" type="cm:cmobject" />
      </permissionGroup>


juans
Champ on-the-rise
Champ on-the-rise
Hi, I was able to create a group using as reference this other thread https://forums.alfresco.com/forum/end-user-discussions/alfresco-share/how-create-root-group-using-re...

And I actually found the documentation for creating new groups: http://127.0.0.1:9090/alfresco/s/index/uri/api/rootgroups/{shortName}

Now I am going to try to relate the user to this group. I will be back in a minute

juans
Champ on-the-rise
Champ on-the-rise
I think I figured it out the questions I asked.

This is how I did it.

I created a group:

POST http://localhost:9090/alfresco/s/api/rootgroups/NewGroup
Payload
{"authority":"Group","shortName":"NewGroup"}

The response was something like this:

HTTP/1.1 201 Created
{
   "data":{
         "authorityType": "GROUP",
         "shortName": "NewGroup",
         "fullName": "GROUP_NewGroup",
         "displayName": "NewGroup",
         "url": "/api/groups/NewGroup"
           ,"zones":
           [
              "APP.DEFAULT",
              "AUTH.ALF"
           ]
}

}



I related the newly created user to this group like this:

Address: http://localhost:9090/alfresco/s/api/people
Http-Method: POST
Content-Type: application/json
Payload:

{
"userName":"unittestuser1",
"firstName":"Test User Name",
"lastName":"Last Name for User Test",
"email":"testuser@company.com",
"password":"password",
"disableAccount":false,
"quota":-1,
"groups":["GROUP_NewGroup"]
}


Now when I look for the user: http://localhost:9090/alfresco/s/api/people/unittestuser1?groups=true I get this part of the data populated:

"groups": [
   {
      "itemName": "GROUP_NewGroup",
      "displayName": "NewGroup"
   }],


And then I add a new ACL to the folder agency1 using this code:
<java>
   public Folder createFolder(String newFolderName, String baseFolderPath, Session session) {
      Folder root = (Folder) session.getObjectByPath(baseFolderPath);

      // Create a Map of objects with the props we want to set
      Map <String, Object> properties = new HashMap<String, Object>();

      properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");      
      properties.put(PropertyIds.NAME, newFolderName);

      Folder folderCreated = root.createFolder(properties);
      logger.info("Folder created, folderId: " + folderCreated.getId() + ", in path: " + folderCreated.getPath());

      String id = folderCreated.getId();
      OperationContext operationContext = new OperationContextImpl();
        operationContext.setIncludeAcls(true);
      // SHOW THE ACLS FOR THE CURRENT object
      printAcl(id, session, operationContext);
       
       
        // ADDING A NEW ACL
        String principal = "GROUP_NewGroup";
        RepositoryInfo repositoryInfo = session.getRepositoryInfo();
        AclCapabilities aclCapabilities = repositoryInfo.getAclCapabilities();

        Map<String, PermissionMapping> permissionMappings = aclCapabilities.getPermissionMapping();
       
        // I think this is the key part here. I am relating the permission CAN_CREATE_DOCUMENT_FOLDER to the
        // principal GROUP_NewGroup to the object with id: id (which is the folder I just created)
        PermissionMapping permissionMapping = permissionMappings.get(PermissionMapping.CAN_CREATE_DOCUMENT_FOLDER);

        List<String> permissions = permissionMapping.getPermissions();
        Ace addAce = session.getObjectFactory().createAce(principal, permissions);

        List<Ace> addAces = new LinkedList<Ace>();
        addAces.add(addAce);
       
        CmisObject obj = session.getObject(id, operationContext);
        obj.addAcl(addAces, AclPropagation.PROPAGATE);
       
       
        System.out.println("With newly added Acl");
        printAcl(id, session, operationContext);
      
      return folderCreated;
   }

   private void printAcl(String id, Session session,
         OperationContext operationContext) {
      CmisObject obj = session.getObject(id, operationContext);

        System.out.println("Acl for " + obj.getName() + ": ");

        Acl acl = obj.getAcl();
        for (Ace ace : acl.getAces()) {
            System.out.println(ace);
        }
        System.out.println("END Acl for " + obj.getName() + ".");
   }

</java>

Now the user can create documents in this folder. yey!!!! (I am so happy Smiley Very Happy !)

I have a question though. This user was able as well to create folders inside the folder, even though I did not assign the PermissionMapping.CAN_CREATE_FOLDER_FOLDER, why is that ? is there any way to allow the user to only create documents ? not folders ?

jpotts
World-Class Innovator
World-Class Innovator
Glad you got it working. No, I don't think there is an out-of-the-box permission that restricts people to creating documents but not folders.

Jeff