001/*
002 *  Copyright 2016 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.core.ui.right;
017
018import java.util.ArrayList;
019import java.util.Collections;
020import java.util.HashMap;
021import java.util.HashSet;
022import java.util.List;
023import java.util.Map;
024import java.util.Optional;
025import java.util.Set;
026import java.util.stream.Collectors;
027
028import org.apache.avalon.framework.service.ServiceException;
029import org.apache.avalon.framework.service.ServiceManager;
030
031import org.ametys.core.ObservationConstants;
032import org.ametys.core.group.GroupDirectoryDAO;
033import org.ametys.core.group.GroupIdentity;
034import org.ametys.core.group.GroupManager;
035import org.ametys.core.observation.Event;
036import org.ametys.core.observation.ObservationManager;
037import org.ametys.core.right.Profile;
038import org.ametys.core.right.ProfileAssignmentStorage.AnonymousOrAnyConnectedKeys;
039import org.ametys.core.right.ProfileAssignmentStorage.UserOrGroup;
040import org.ametys.core.right.ProfileAssignmentStorageExtensionPoint;
041import org.ametys.core.right.RightAssignmentContext;
042import org.ametys.core.right.RightAssignmentContextExtensionPoint;
043import org.ametys.core.right.RightManager.RightResult;
044import org.ametys.core.right.RightProfilesDAO;
045import org.ametys.core.right.RightsException;
046import org.ametys.core.ui.Callable;
047import org.ametys.core.ui.ClientSideElement;
048import org.ametys.core.ui.ClientSideElementHelper;
049import org.ametys.core.ui.StaticClientSideElement;
050import org.ametys.core.user.UserIdentity;
051import org.ametys.plugins.core.user.UserHelper;
052
053import com.google.common.collect.Sets;
054
055/**
056 * {@link ClientSideElement} for the tool displaying the profile assignments
057 */
058public class ProfileAssignmentsToolClientSideElement extends StaticClientSideElement
059{
060    /** The profile assignment storage component */
061    protected ProfileAssignmentStorageExtensionPoint _profileAssignmentStorageEP;
062    /** The extension point for right assignment contexts */
063    protected RightAssignmentContextExtensionPoint _rightAssignmentContextEP;
064    /** The DAO for group directories */
065    protected GroupDirectoryDAO _groupDirectoryDAO;
066    /** The group manager */
067    protected GroupManager _groupManager;
068    /** The observation manager */
069    protected ObservationManager _observationManager;
070    /** The user helper */
071    protected UserHelper _userHelper;
072    /** The profile DAO */
073    protected RightProfilesDAO _profileDAO;
074    
075    /**
076     * Enumeration of all possible access types
077     */
078    public enum AccessType
079    {
080        /**
081         * Indicates that the access is allowed
082         */
083        ALLOW 
084        {
085            @Override
086            public String toString()
087            {
088                return "allow";
089            }
090        },
091        /**
092         * Indicates that the access is denied
093         */
094        DENY 
095        {
096            @Override
097            public String toString()
098            {
099                return "deny";
100            }
101        },
102        /**
103         * Indicates that the access is allowed by inheritance
104         */
105        INHERITED_ALLOW 
106        {
107            @Override
108            public String toString()
109            {
110                return "inherited_allow";
111            }
112        },
113        /**
114         * Indicates that the access is denied by inheritance
115         */
116        INHERITED_DENY 
117        {
118            @Override
119            public String toString()
120            {
121                return "inherited_deny";
122            }
123        },
124        /**
125         * Indicates that the access can not be determined
126         */
127        UNKNOWN 
128        {
129            @Override
130            public String toString()
131            {
132                return "unknown";
133            }
134        }
135    }
136    
137    /**
138     * Enumeration of all possible target types
139     */
140    public enum TargetType 
141    {
142        /**
143         * Indicates that the target is the anonymous user
144         */
145        ANONYMOUS 
146        {
147            @Override
148            public String toString()
149            {
150                return "anonymous";
151            }
152        },
153        /**
154         * Indicates that the target is the anonymous user
155         */
156        ANYCONNECTED_USER 
157        {
158            @Override
159            public String toString()
160            {
161                return "anyconnected_user";
162            }
163        },
164        /**
165         * Indicates that the target is a user
166         */
167        USER 
168        {
169            @Override
170            public String toString()
171            {
172                return "user";
173            }
174        },
175        /**
176         * Indicates that the target is a group
177         */
178        GROUP 
179        {
180            @Override
181            public String toString()
182            {
183                return "group";
184            }
185        }
186    }
187
188    @Override
189    public void service(ServiceManager smanager) throws ServiceException
190    {
191        super.service(smanager);
192        _profileAssignmentStorageEP = (ProfileAssignmentStorageExtensionPoint) smanager.lookup(ProfileAssignmentStorageExtensionPoint.ROLE);
193        _rightAssignmentContextEP = (RightAssignmentContextExtensionPoint) smanager.lookup(RightAssignmentContextExtensionPoint.ROLE);
194        _groupDirectoryDAO = (GroupDirectoryDAO) smanager.lookup(GroupDirectoryDAO.ROLE);
195        _groupManager = (GroupManager) smanager.lookup(GroupManager.ROLE);
196        _observationManager = (ObservationManager) smanager.lookup(ObservationManager.ROLE);
197        _userHelper = (UserHelper) smanager.lookup(UserHelper.ROLE);
198        _profileDAO = (RightProfilesDAO) smanager.lookup(RightProfilesDAO.ROLE);
199    }
200    
201    @SuppressWarnings("unchecked")
202    @Override
203    public List<Script> getScripts(boolean ignoreRights, Map<String, Object> contextParameters)
204    {
205        List<Script> scripts = super.getScripts(ignoreRights, contextParameters);
206        
207        if (scripts.size() > 0)
208        {
209            Script script = ClientSideElementHelper.cloneScript(scripts.get(0));
210            
211            Map<String, Object> jsClasses = new HashMap<>();
212            script.getParameters().put("classes", jsClasses);
213            
214            boolean excludePrivate = true;
215            Set<String> rightContextIds = _rightAssignmentContextEP.getExtensionsIds();
216            if (script.getParameters().containsKey("right-contexts"))
217            {
218                excludePrivate = false;
219                // Restrict the right contexts to the configured right contexts if exist
220                Object ctxConfig = ((Map<String, Object>) script.getParameters().get("right-contexts")).get("right-context");
221                if (ctxConfig instanceof List)
222                {
223                    rightContextIds = new HashSet<>((List<String>) ctxConfig);
224                }
225                else
226                {
227                    rightContextIds = Sets.newHashSet((String) ctxConfig);
228                }
229            }
230            
231            for (String rightContextId: rightContextIds)
232            {
233                RightAssignmentContext rightAssignmentContext = _rightAssignmentContextEP.getExtension(rightContextId);
234                
235                if (!excludePrivate || !rightAssignmentContext.isPrivate())
236                {
237                    List<Script> rightAssignmentContextScripts = rightAssignmentContext.getScripts(ignoreRights, contextParameters);
238                    int index = 0;
239                    for (Script rightAssignmentContextScript: rightAssignmentContextScripts)
240                    {
241                        Map<String, Object> classInfo = new HashMap<>();
242                        classInfo.put("className", rightAssignmentContextScript.getScriptClassname());
243                        classInfo.put("serverId", rightContextId);
244                        classInfo.put("parameters", rightAssignmentContextScript.getParameters());
245                        jsClasses.put(rightContextId + "-" + index++, classInfo);
246                        
247                        script.getScriptFiles().addAll(rightAssignmentContextScript.getScriptFiles());
248                        script.getCSSFiles().addAll(rightAssignmentContextScript.getCSSFiles());
249                    }
250                }
251                
252            }
253            
254            scripts = new ArrayList<>();
255            scripts.add(script);
256        }
257        
258        return scripts;
259    }
260    
261    /**
262     * Gets the groups of a user as JSON
263     * @param login The login of the user
264     * @param populationId The population of the user
265     * @return the groups of a user as JSON
266     */
267    @Callable
268    public List<Map<String, Object>> getUserGroups(String login, String populationId)
269    {
270        return _groupManager.getUserGroups(new UserIdentity(login, populationId)).stream()
271            .map(this::_groupToJson)
272            .collect(Collectors.toList());
273    }
274    
275    private Map<String, Object> _groupToJson(GroupIdentity groupIdentity)
276    {
277        Map<String, Object> result = new HashMap<>();
278        result.put("groupId", groupIdentity.getId());
279        result.put("groupDirectory", groupIdentity.getDirectoryId());
280        return result;
281    }
282    
283    /**
284     * Save some changes made client-side.
285     * @param rightAssignmentCtxId The id of the right assignment context
286     * @param jsContext The JS object context
287     * @param assignmentsInfo The list of all the changes to make. Each map in the list must contain the following keys:
288     * <ol>
289     * <li><b>profileId</b> for the id of the profile (as a string)</li>
290     * <li><b>assignment</b> for the kind of assignment (can be ACCESS_TYPE_ALLOW, ACCESS_TYPE_DENY...)</li>
291     * <li><b>assignmentType</b> expects one of these four strings: "user", "group", "anonymous", "anyConnectedUser"</li>
292     * <li><b>identity</b> Can be null if assignmentType is "anonymous" or "anyConnectedUser". If "user", must be a map with the keys "login" and "populationId". If "group", must be a map with the keys "groupId" and "groupDirectory"</li>
293     * </ol>
294     * @return a map containing 3 objects :
295     * success : boolean, everything is saved
296     * successInfos : elements from assignmentsInfo that are saved
297     * errorInfos : elements from assignmentsInfo that are not saved
298     */
299    @SuppressWarnings("unchecked")
300    @Callable
301    public Map<String, Object> saveChanges(String rightAssignmentCtxId, Object jsContext, List<Map<String, Object>> assignmentsInfo)
302    {
303        Map<String, Object> result = new HashMap<>();
304        List<Map<String, Object>> successInfos = new ArrayList<>();
305        List<Map<String, Object>> errorInfos = new ArrayList<>();
306        
307        UserIdentity user = _currentUserProvider.getUser();
308        Set<GroupIdentity> groups = _groupManager.getUserGroups(user);
309        
310        if (!hasRight(getRights(Collections.EMPTY_MAP)))
311        {
312            throw new RightsException("The user '" + user + "' try to assign profile without sufficient rights");
313        }
314        
315        boolean hasHandleRight = _rightManager.hasRight(user, "Runtime_Rights_Rights_Handle", "/${WorkspaceName}") == RightResult.RIGHT_ALLOW;
316        
317        Set<String> updatedProfiles = new HashSet<>();
318        RightAssignmentContext rightAssignmentContext = _rightAssignmentContextEP.getExtension(rightAssignmentCtxId);
319        Object context = rightAssignmentContext.convertJSContext(jsContext);
320        String contextIdentifier = rightAssignmentContext.getContextIdentifier(context);
321        for (Map<String, Object> assignmentInfo : assignmentsInfo)
322        {
323            String profileId = (String) assignmentInfo.get("profileId");
324            String assignment = (String) assignmentInfo.get("assignment");
325            String targetType = (String) assignmentInfo.get("targetType");
326
327            Profile profile = _profileDAO.getProfile(profileId);
328            assignmentInfo.put("profileLabel", profile.getLabel());
329            
330            if (hasHandleRight || canDelegateRights(user, groups, profileId, assignment, context))
331            {
332                updatedProfiles.add(profileId);
333                Map<String, String> identity = (Map<String, String>) assignmentInfo.get("identity");
334                _saveChange(context, profileId, assignment, targetType, identity);
335                successInfos.add(assignmentInfo);
336            }
337            else
338            {
339                errorInfos.add(assignmentInfo);
340            }
341        }
342        _notifyObservers(context, contextIdentifier, updatedProfiles);
343
344        result.put("successInfos", successInfos);
345        result.put("errorInfos", errorInfos);
346        result.put("success", errorInfos.isEmpty());
347        
348        return result;
349    }
350    
351    /**
352     * Only allow user with right CMS_Rights_Delegate_Rights to add a profil that this user already have on this context
353     * @param user user that want to de an assignment
354     * @param groups groups of the user
355     * @param profileId profil impacted
356     * @param assignment assignment see {@link AccessType}
357     * @param context context of the assignment
358     * @return <code>true</code> if user can de this assignment
359     */
360    protected boolean canDelegateRights(UserIdentity user, Set<GroupIdentity> groups, String profileId, String assignment , Object context)
361    {
362        AccessType accessType = assignment != null ? AccessType.valueOf(assignment.toUpperCase()) : AccessType.UNKNOWN;
363        return accessType == AccessType.ALLOW
364                && _rightManager.hasRight(user, "CMS_Rights_Delegate_Rights", "/${WorkspaceName}") == RightResult.RIGHT_ALLOW
365                && _profileAssignmentStorageEP.getPermissions(user, groups, Set.of(profileId), context).get(profileId).toRightResult() == RightResult.RIGHT_ALLOW;
366    }
367    
368    /**
369     * Notify observers after modifying profile assignments.
370     * @param context The context
371     * @param contextIdentifier The context identifier
372     * @param profileIds The profiles
373     */
374    protected void _notifyObservers(Object context, String contextIdentifier, Set<String> profileIds)
375    {
376        _observationManager.notify(new Event(ObservationConstants.EVENT_ACL_UPDATED, _currentUserProvider.getUser(), _getEventParams(context, contextIdentifier, profileIds)));
377    }
378    
379    /**
380     * Get the event params for notification.
381     * @param context The context
382     * @param contextIdentifier The context identifier
383     * @param profileIds The profiles
384     * @return the event params
385     */
386    protected Map<String, Object> _getEventParams(Object context, String contextIdentifier, Set<String> profileIds)
387    {
388        Map<String, Object> eventParams = new HashMap<>();
389        eventParams.put(ObservationConstants.ARGS_ACL_CONTEXT, context);
390        eventParams.put(ObservationConstants.ARGS_ACL_CONTEXT_IDENTIFIER, contextIdentifier);
391        eventParams.put(ObservationConstants.ARGS_ACL_PROFILES, profileIds);
392        return eventParams;
393    }
394    
395    /**
396     * Determines if the inheritance of assignments is disallowed on the given context
397     * @param rightAssignmentCtxId The id of the right assignment context
398     * @param jsContext The JS object context
399     * @return <code>true</code> if the inheritance is disallowed.
400     */
401    @Callable
402    public boolean isInheritanceDisallowed(String rightAssignmentCtxId, Object jsContext)
403    {
404        RightAssignmentContext rightCtx = _rightAssignmentContextEP.getExtension(rightAssignmentCtxId);
405        Object context = rightCtx.convertJSContext(jsContext);
406        
407        return _profileAssignmentStorageEP.isInheritanceDisallowed(context);
408    }
409    
410    /**
411     * Allow or disallow the inheritance of assignments on the given context
412     * @param rightAssignmentCtxId The id of the right assignment context
413     * @param jsContext The JS object context
414     * @param disallow true to disallow the inheritance, false to allow.
415     */
416    @Callable
417    public void disallowInheritance(String rightAssignmentCtxId, Object jsContext, boolean disallow)
418    {
419        RightAssignmentContext rightCtx = _rightAssignmentContextEP.getExtension(rightAssignmentCtxId);
420        Object context = rightCtx.convertJSContext(jsContext);
421        String contextIdentifier = rightCtx.getContextIdentifier(context);
422        
423        _profileAssignmentStorageEP.disallowInheritance(context, disallow);
424        
425        // notify observers for all profiles
426        Set<String> profileIds = _profileDAO.getProfiles().stream()
427                .map(Profile::getId)
428                .collect(Collectors.toSet());
429        
430        _notifyObservers(context, contextIdentifier, profileIds);
431    }
432
433    /**
434     * Get the first permission given by inheritance for a object context and profiles
435     * @param rightAssignmentCtxId The id of the right assignment context
436     * @param jsContext The JS object context
437     * @param profileIds The list of profiles
438     * @param targetType The type of target : anonymous, any connected users, a user or a group
439     * @param identity The identity of the target. Can be null if the target is anonymous or any connected users
440     * @return The first access type given by inheritance for each profile
441     */
442    @Callable
443    public Map<String, String> getInheritedAssignments (String rightAssignmentCtxId, Object jsContext, List<String> profileIds, String targetType, Map<String, String> identity)
444    {
445        RightAssignmentContext rightCtx = _rightAssignmentContextEP.getExtension(rightAssignmentCtxId);
446        Object context = rightCtx.convertJSContext(jsContext);
447        
448        if (_profileAssignmentStorageEP.isInheritanceDisallowed(context))
449        {
450            return profileIds.stream()
451                .collect(Collectors.toMap(profileId -> profileId, profileId -> AccessType.UNKNOWN.toString()));
452        }
453        else
454        {
455            return profileIds.stream()
456                    .collect(Collectors.toMap(profileId -> profileId, profileId -> getInheritedAssignment(rightAssignmentCtxId, jsContext, profileId, targetType, identity)));
457        }
458    }
459    
460    /**
461     * Get the first permission given by inheritance for a object context and a specific profile
462     * @param rightAssignmentCtxId The id of the right assignment context
463     * @param jsContext The JS object context
464     * @param profileId The id of profile 
465     * @param targetType The type of target : anonymous, any connected users, a user or a group
466     * @param identity The identity of the target. Can be null if the target is anonymous or any connected users
467     * @return The first access type given by inheritance
468     */
469    @Callable
470    public String getInheritedAssignment (String rightAssignmentCtxId, Object jsContext, String profileId, String targetType, Map<String, String> identity)
471    {
472        RightAssignmentContext rightCtx = _rightAssignmentContextEP.getExtension(rightAssignmentCtxId);
473        Object context = rightCtx.convertJSContext(jsContext);
474        
475        if (_profileAssignmentStorageEP.isInheritanceDisallowed(context))
476        {
477            return AccessType.UNKNOWN.toString();
478        }
479        else
480        {
481            switch (TargetType.valueOf(targetType.toUpperCase()))
482            {
483                case ANONYMOUS:
484                    return _getInheritedAssignmentForAnonymous(rightCtx, context, profileId);
485                case ANYCONNECTED_USER:
486                    return _getInheritedAssignmentForAnyconnected(rightCtx, context, profileId);
487                case USER:
488                    UserIdentity user = _userHelper.json2userIdentity(identity);
489                    return _getInheritedAssignmentForUser(rightCtx, context, profileId, user);
490                case GROUP:
491                    GroupIdentity group = new GroupIdentity(identity.get("groupId"), identity.get("groupDirectory"));
492                    return _getInheritedAssignmentForGroup(rightCtx, context, profileId, group);
493                default:
494                    return AccessType.UNKNOWN.toString();
495            }
496        }
497    }
498    
499    private String _getInheritedAssignmentForAnonymous (RightAssignmentContext extension, Object context, String profileId)
500    {
501        String value = AccessType.UNKNOWN.toString();
502        
503        Set<Object> parentContexts = extension.getParentContexts(context);
504        if (parentContexts != null)
505        {
506            for (Object parentContext : parentContexts)
507            {
508                Map<AnonymousOrAnyConnectedKeys, Set<String>> profilesForAnonymousAndAnyConnectedUser = _profileAssignmentStorageEP.getProfilesForAnonymousAndAnyConnectedUser(parentContexts);
509                
510                Set<String> deniedProfiles = Optional.ofNullable(profilesForAnonymousAndAnyConnectedUser.get(AnonymousOrAnyConnectedKeys.ANONYMOUS_DENIED)).orElse(Set.of());
511                if (deniedProfiles.contains(profileId))
512                {
513                    return AccessType.INHERITED_DENY.toString();
514                }
515                
516                Set<String> allowedProfiles = Optional.ofNullable(profilesForAnonymousAndAnyConnectedUser.get(AnonymousOrAnyConnectedKeys.ANONYMOUS_ALLOWED)).orElse(Set.of());
517                if (allowedProfiles.contains(profileId))
518                {
519                    value = AccessType.INHERITED_ALLOW.toString();
520                }
521    
522                String parentsValue = _getInheritedAssignmentForAnonymous(extension, parentContext, profileId);
523                if (!AccessType.UNKNOWN.toString().equals(parentsValue))
524                {
525                    value = parentsValue;
526                }
527            }
528        }
529        
530        return value;
531    }
532    
533    private String _getInheritedAssignmentForAnyconnected(RightAssignmentContext extension, Object context, String profileId)
534    {
535        String value = AccessType.UNKNOWN.toString();
536        
537        Set<Object> parentContexts = extension.getParentContexts(context);
538        if (parentContexts != null)
539        {
540            for (Object parentContext : parentContexts)
541            {
542                Map<AnonymousOrAnyConnectedKeys, Set<String>> profilesForAnonymousAndAnyConnectedUser = _profileAssignmentStorageEP.getProfilesForAnonymousAndAnyConnectedUser(parentContexts);
543                
544                Set<String> deniedProfiles = Optional.ofNullable(profilesForAnonymousAndAnyConnectedUser.get(AnonymousOrAnyConnectedKeys.ANYCONNECTEDUSER_DENIED)).orElse(Set.of());
545                if (deniedProfiles.contains(profileId))
546                {
547                    return AccessType.INHERITED_DENY.toString();
548                }
549                
550                Set<String> allowedProfiles = Optional.ofNullable(profilesForAnonymousAndAnyConnectedUser.get(AnonymousOrAnyConnectedKeys.ANYCONNECTEDUSER_ALLOWED)).orElse(Set.of());
551                if (allowedProfiles.contains(profileId))
552                {
553                    value = AccessType.INHERITED_ALLOW.toString();
554                }
555    
556                String parentsValue = _getInheritedAssignmentForAnyconnected(extension, parentContext, profileId);
557                if (!AccessType.UNKNOWN.toString().equals(parentsValue))
558                {
559                    value = parentsValue;
560                }
561            }
562        }
563        
564        return value;
565    }
566
567    private String _getInheritedAssignmentForUser(RightAssignmentContext extension, Object context, String profileId, UserIdentity user)
568    {
569        String value = AccessType.UNKNOWN.toString();
570
571        Set<Object> parentContexts = extension.getParentContexts(context);
572        if (parentContexts != null)
573        {
574            for (Object parentContext : parentContexts)
575            {
576                Map<UserIdentity, Map<UserOrGroup, Set<String>>> profilesForUsers = _profileAssignmentStorageEP.getProfilesForUsers(parentContext, user);
577                
578                Set<String> deniedProfiles = Optional.ofNullable(profilesForUsers.get(user)).map(a -> a.get(UserOrGroup.DENIED)).orElse(Set.of());
579                if (deniedProfiles.contains(profileId))
580                {
581                    return AccessType.INHERITED_DENY.toString();
582                }
583                
584                Set<String> allowedProfiles = Optional.ofNullable(profilesForUsers.get(user)).map(a -> a.get(UserOrGroup.ALLOWED)).orElse(Set.of());
585                if (allowedProfiles.contains(profileId))
586                {
587                    value = AccessType.INHERITED_ALLOW.toString();
588                }
589                
590                String parentsValue = _getInheritedAssignmentForUser(extension, parentContext, profileId, user);
591                if (!AccessType.UNKNOWN.toString().equals(parentsValue))
592                {
593                    value = parentsValue;
594                }
595            }
596        }
597        
598        return value;
599    }
600    
601    private String _getInheritedAssignmentForGroup(RightAssignmentContext extension, Object context, String profileId, GroupIdentity group)
602    {
603        String value = AccessType.UNKNOWN.toString();
604
605        Set<Object> parentContexts = extension.getParentContexts(context);
606        if (parentContexts != null)
607        {        
608            for (Object parentContext : parentContexts)
609            {
610                Map<GroupIdentity, Map<UserOrGroup, Set<String>>> profilesForGroups = _profileAssignmentStorageEP.getProfilesForGroups(parentContext, Set.of(group));
611                
612                Set<String> deniedProfiles = Optional.ofNullable(profilesForGroups.get(group)).map(a -> a.get(UserOrGroup.DENIED)).orElse(Set.of());
613                if (deniedProfiles.contains(profileId))
614                {
615                    return AccessType.INHERITED_DENY.toString();
616                }
617                
618                Set<String> allowedProfiles = Optional.ofNullable(profilesForGroups.get(group)).map(a -> a.get(UserOrGroup.ALLOWED)).orElse(Set.of());
619                if (allowedProfiles.contains(profileId))
620                {
621                    value = AccessType.INHERITED_ALLOW.toString();
622                }
623                
624                String parentsValue = _getInheritedAssignmentForGroup(extension, parentContext, profileId, group);
625                if (!AccessType.UNKNOWN.toString().equals(parentsValue))
626                {
627                    value = parentsValue;
628                }
629            }
630        }
631        
632        return value;
633    }
634    
635    private void _saveChange(Object context, String profileId, String assignment, String targetType, Map<String, String> identity)
636    {
637        AccessType accessType = assignment != null ? AccessType.valueOf(assignment.toUpperCase()) : AccessType.UNKNOWN;
638        switch (TargetType.valueOf(targetType.toUpperCase()))
639        {
640            case ANONYMOUS:
641                switch (accessType)
642                {
643                    case ALLOW:
644                        _profileAssignmentStorageEP.removeDeniedProfileFromAnonymous(profileId, context);
645                        _profileAssignmentStorageEP.allowProfileToAnonymous(profileId, context);
646                        break;
647                    case DENY:
648                        _profileAssignmentStorageEP.removeAllowedProfileFromAnonymous(profileId, context);
649                        _profileAssignmentStorageEP.denyProfileToAnonymous(profileId, context);
650                        break;
651                    default:
652                        _profileAssignmentStorageEP.removeAllowedProfileFromAnonymous(profileId, context);
653                        _profileAssignmentStorageEP.removeDeniedProfileFromAnonymous(profileId, context);
654                        break;
655                }
656                break;
657                
658            case ANYCONNECTED_USER:
659                switch (accessType)
660                {
661                    case ALLOW:
662                        _profileAssignmentStorageEP.removeDeniedProfileFromAnyConnectedUser(profileId, context);
663                        _profileAssignmentStorageEP.allowProfileToAnyConnectedUser(profileId, context);
664                        break;
665                    case DENY:
666                        _profileAssignmentStorageEP.removeAllowedProfileFromAnyConnectedUser(profileId, context);
667                        _profileAssignmentStorageEP.denyProfileToAnyConnectedUser(profileId, context);
668                        break;
669                    default:
670                        _profileAssignmentStorageEP.removeAllowedProfileFromAnyConnectedUser(profileId, context);
671                        _profileAssignmentStorageEP.removeDeniedProfileFromAnyConnectedUser(profileId, context);
672                        break;
673                }
674                break;
675                
676            case USER:
677                UserIdentity user = _userHelper.json2userIdentity(identity);
678                switch (accessType)
679                {
680                    case ALLOW:
681                        _profileAssignmentStorageEP.removeDeniedProfileFromUser(user, profileId, context);
682                        _profileAssignmentStorageEP.allowProfileToUser(user, profileId, context);
683                        break;
684                    case DENY:    
685                        _profileAssignmentStorageEP.removeAllowedProfileFromUser(user, profileId, context);
686                        _profileAssignmentStorageEP.denyProfileToUser(user, profileId, context);
687                        break;
688                    default:
689                        _profileAssignmentStorageEP.removeAllowedProfileFromUser(user, profileId, context);
690                        _profileAssignmentStorageEP.removeDeniedProfileFromUser(user, profileId, context);
691                        break;
692                }
693                break;
694                
695            case GROUP:
696                GroupIdentity group = new GroupIdentity(identity.get("groupId"), identity.get("groupDirectory"));
697                switch (accessType)
698                {
699                    case ALLOW:
700                        _profileAssignmentStorageEP.removeDeniedProfileFromGroup(group, profileId, context);
701                        _profileAssignmentStorageEP.allowProfileToGroup(group, profileId, context);
702                        break;
703                    case DENY:  
704                        _profileAssignmentStorageEP.removeAllowedProfileFromGroup(group, profileId, context);
705                        _profileAssignmentStorageEP.denyProfileToGroup(group, profileId, context);
706                        break;
707                    default:
708                        _profileAssignmentStorageEP.removeAllowedProfileFromGroup(group, profileId, context);
709                        _profileAssignmentStorageEP.removeDeniedProfileFromGroup(group, profileId, context);
710                        break;
711                }
712                break;
713            default:
714                break;
715        }
716    }
717    
718    
719}