Jazz Forum Welcome to the Jazz Community Forum Connect and collaborate with IBM Engineering experts and users

Prevent changes on certain folders - by certain users

Hi All,
            I want to restrict access on certain folders to particular users alone. I am doing a server plugin for this. I need the below:
1. Stream name - to which deliver is happening
2. Folder name - Lowest-level and the parent folders involved + filename
3. contributor name 

How to get the path and stream details using server plugin? i tried using com.ibm.team.filesystem - but fails as its related to client plugin only...

Please advise and share any relevant codes or ideas that you have

Thanks..

0 votes

Comments

Are you trying to limit read access or write access to those folders? I am guessing write access, that you want to prevent users from delivering changes to those folders. But your question isn't clear about that.

Hi David,
                 I am trying to restrict write access to the folders.

My requirement is that i should restrict add operations on a particular path for certain users.

Thanks.



3 answers

Permanent link
I think you are talking about an advisor on the delivery operation.
In this case the operation.getOperationData() is an instance of DeliverOperationData. With this object you can retrieve the source and the target workspaces or streams (which are the same type of object) and the change-set.

Then, for every change-set, you can get the single change. The path is more difficult to be obtained, but you can get it using IScmService.configurationLocateAncestors method and then cycling through the tree path.

Michele.


1 vote

Comments

Hi Michele,
                    My Code looks like this: - The problem that i have is FileItem - can be used only in clinet plugin i think and hence am unable to retrive the item details - folders and files here. Please suggest an alternative for server-side plugin

DeliverOperationData data = (DeliverOperationData) operationData;
        List<IChangeSetHandle> changeSetHandles = data.getChangeSetHandles();
        IRepositoryItemService itemService = getService(IRepositoryItemService.class);
        IScmService scmService = getService(IScmService.class);
        IItemServiceIterator changeSetIterator = ItemServiceIteratorFactory.INSTANCE.createFetchItemsIterator(itemService, changeSetHandles.toArray(new IItemHandle[changeSetHandles.size()]), IRepositoryItemService.COMPLETE);
       
        while (changeSetIterator.hasNext()) {
            IChangeSet changeSet = (IChangeSet) changeSetIterator.next();
            if (changeSet == null) {
                             continue;
            }           
            for (IChange change : (List<IChange>) changeSet.changes()) {
               
                if (change.kind() == IChange.ADD || change.kind() == IChange.MODIFY || change.kind() == IChange.DELETE)
                {
                     IVersionableHandle versionableHandle = change.beforeState();
                    ServiceConfigurationProvider configProvider = ServiceConfigurationProvider.FACTORY.create(
                            data.getDestWorkspace(), changeSet.getComponent());
                    IVersionable item = (IVersionable) scmService.fetchState(versionableHandle, null, null);
                    if(item instanceof IFolder)
                    {
                        String path = "\"+((IFolder)item).getName();
                       IVersionableHandle parent  = ((IFolder)item).getParent();
                       System.out.println(" Folder names is" + path);
                       System.out.println(" Folder parent names is" + parent);
                    }
                    else if(item instanceof IFileItem)
                    {
                        String path = "\"+((IFileItem)item).getName();
                        IVersionableHandle parent = ((IFileItem)item).getParent();
                       System.out.println(" File names is" + path);
                       System.out.println(" File parent names is" + parent);
                    }

                    IAncestorReport reports[] = scmService.configurationLocateAncestors(
                            configProvider, new IVersionableHandle[] {versionableHandle}, null, null);
                    IAdvisorInfo info = collector.createProblemInfo(
                            "Deliver of deleted files is prohibited",
                            "The file " + toFullPath(item, reports[0].getNameItemPairs()) + " is not allowed to be deleted.",
                            "error");
                    collector.addInfo(info);                                       
                }

}

        }
   
    }
}
    private String toFullPath(IVersionable versionable, List<INameItemPair> segments) {
        StringBuffer path = new StringBuffer();
        if(segments.isEmpty()) {
            return versionable.getName();
        }
        for (INameItemPair nameItemPair : segments) {
            if(path.length() != 0) {
                path.append(Path.SEPARATOR);
            }
            // ignore the root folder which doesn't have a name
            if(nameItemPair.getName() != null)
                path.append(nameItemPair.getName());
        }
        return path.toString();
    }
}

Thanks.

I use both com.ibm.team.filesystem.common.IFileItem and com.ibm.team.scm.common.IFolderHandle on my server side script. I don't know of any limitation between client and server in this case.

Hi Michele,
                    Then could it be a problem with my pre-requisites? Because i got errors when using these methods in my server side plugin.

Could you put your associated plugin.xml code here?

Thanks.

Where do you have the errors? And which exceptions do you have?

My plugin.xml is quite simple, for example:

<extension
         point="com.ibm.team.process.service.operationParticipants">
      <operationParticipant
            class="it.nexen.server.postop.delivery.CheckWASProperties"
            id="it.nexen.server.postop.delivery.CheckWASProperties"
            name="Check WAS Properties"
            operationId="com.ibm.team.scm.server.deliver"
            schema="schema/checkWASProperties.xsd">
         <description>
            Verifica che le properties versionate per il deploy automatico non contengano valori non ammessi.
         </description>
         <extensionService
               componentId="it.nexen.server.postop.delivery.CheckWASProperties"
               implementationClass="it.nexen.server.postop.delivery.CheckWASProperties">
            <prerequisites>
            <requiredService interface="com.ibm.team.repository.service.IContentService"/>
            <requiredService interface="com.ibm.team.repository.service.IRepositoryItemService"/>
            <requiredService interface="com.ibm.team.scm.common.IScmService"/>
            <requiredService interface="com.ibm.team.scm.service.IServerSideVersionedContentService"/>
            <requiredService interface="com.ibm.team.workitem.service.IWorkItemServer"/>
            <requiredService interface="com.ibm.team.links.common.service.ILinkService"/>
            <requiredService interface="com.ibm.team.repository.service.IServerDescriptionService"/>
            </prerequisites>
         </extensionService>
      </operationParticipant>
   </extension>

Sorry, made it an advisor and i think thats the reason...I will modify it and check.

Do you have the code snippet for the Stream name, Filename and folder details retrieval?

Thanks.

For stream name once you've the IWorkspaceHandle (from data.getDestWorkspace()) you can easily get the IWorkspace object (using IRepositoryItemService) and then use .getName() method.


FileName and path is quite complex but your snippet on previous answer seems correct at first view.

showing 5 of 6 show 1 more comments

Permanent link
You shouldn't use the stream name to check if the stream is what you want. You should use the stream's UUID. You can get that using IWorkspace.getItemId(). This prevents your advisor from misbehaving when the stream's name changes or another stream is created with the same name. To set the UUID properly, you should create an aspect editor that allows clients to configure the advisor.

You should be running on the "com.ibm.team.scm.service.changehistory.modification" operation. That's "Deliver (phase 2)" which is more appropriate to what you're trying to do. You can walk over the changes by looking at the update report: 

<pre>public void run(AdvisableOperation operation, IProcessConfigurationElement advisorConfiguration, IAdvisorInfoCollector collector, IProgressMonitor monitor) throws TeamRepositoryException {
   IScmDeltaSource deltaSource = (IScmDeltaSource) operationData;
   IScmItemService scmItemService = getService(IScmItemService.class);

   for (IChangeHistoryModificationDelta mod : deltaSource.getDeltas(IChangeHistoryModificationDelta.class)) {
      IUpdateReport updateReport = mod.getUpdateReport();
         for (IComponentHandle comp : updateReport.getAffectedComponents()) {
            Collection<IItemUpdateReport> updatesForComponent = updateReport.getUpdatesForComponent(comp);
//...</pre>

To check the location of the versionable in the hierarchy, you should query the IScmService.configurationLocateAncestors() for each of the changed items (listed in the IUpdateReport) to see if they are descendants of the versionables you care about. Note that new items won't exist in the configuration, and that items that have been moved may have been moved under newly created items.

0 votes


Permanent link
Hi All,
            I have implemented this plugin and it works fine for modify/delete as there is a before and an after state. sample code that i used to get the path is as below:
for (IChange change : (List<IChange>) changeSet.changes()) {
                    ServiceConfigurationProvider configProvider = ServiceConfigurationProvider.FACTORY.create(data.getDestWorkspace(), changeSet.getComponent());
IVersionableHandle versionableHandle = change.beforeState();
IVersionable item =  (IVersionable) scmService.fetchState(versionableHandle, null, null);
                    IAncestorReport reports[] = scmService.configurationLocateAncestors(
                            configProvider, new IVersionableHandle[] {versionableHandle}, null, null);
                    String Path = toFullPath(item, reports[0].getNameItemPairs());

but in case of add operation, the value of versionableHandle is null and so the above code does not work. Could you please suggest how this can be achieved for an add operation?

M

0 votes

Comments

The handle is null because of the configuration provider you've selected. In case of an add operation the element is not already present in the target stream so you have to use data.getSourceWorkspace() in order to have the object.

Thanks Michelle. Could you please provide a sample code for the add operation?
Versionable handle looks to be retrieving a null value (or) is it the problem only because of config provider?

Your snippet seems to be ok, in case of add operation (you can obtain change kind by IChange.getKind() and compare it with IChange.ADD) you have to select a different config provider.

Hi Michele,
                    The plugin works fine now. But at times, it fails to run giving the following error:
 http-9443-Processor44]  WARN com.ibm.team.filesystem                             - Unhandled Exception
java.io.IOException: Stream closed

And when i restart the system(local machine - where my JTS resides), it starts working again. there is no problem with plugin activation, but it fails at times - i can say after 2 or 3 runs.

Please advise.

Thanks.

Your answer

Register or log in to post your answer.

Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.

Search context
Follow this question

By Email: 

Once you sign in you will be able to subscribe for any updates here.

By RSS:

Answers
Answers and Comments
Question details
× 10,938

Question asked: Jun 21 '12, 11:39 a.m.

Question was seen: 5,207 times

Last updated: Mar 26 '13, 10:43 a.m.

Confirmation Cancel Confirm