source: ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/GroupServiceImpl.java @ 5555

Last change on this file since 5555 was 5555, checked in by olhsha@mpi.nl, 10 years ago

Adding transfer owner ship and fixing the method

  • Property svn:mime-type set to text/plain
File size: 15.0 KB
Line 
1package clarin.cmdi.componentregistry.impl.database;
2
3import clarin.cmdi.componentregistry.ItemNotFoundException;
4import clarin.cmdi.componentregistry.UserUnauthorizedException;
5import java.util.ArrayList;
6import java.util.Collections;
7import java.util.Comparator;
8import java.util.HashSet;
9import java.util.List;
10import java.util.Set;
11
12import org.springframework.beans.factory.annotation.Autowired;
13import org.springframework.jmx.export.annotation.ManagedOperation;
14import org.springframework.jmx.export.annotation.ManagedOperationParameter;
15import org.springframework.jmx.export.annotation.ManagedOperationParameters;
16import org.springframework.jmx.export.annotation.ManagedResource;
17import org.springframework.stereotype.Service;
18import org.springframework.transaction.annotation.Transactional;
19
20import clarin.cmdi.componentregistry.impl.ComponentUtils;
21import clarin.cmdi.componentregistry.model.BaseDescription;
22import clarin.cmdi.componentregistry.model.Group;
23import clarin.cmdi.componentregistry.model.GroupMembership;
24import clarin.cmdi.componentregistry.model.Ownership;
25import clarin.cmdi.componentregistry.model.ProfileDescription;
26import clarin.cmdi.componentregistry.model.RegistryUser;
27import clarin.cmdi.componentregistry.persistence.ComponentDao;
28import clarin.cmdi.componentregistry.persistence.jpa.GroupDao;
29import clarin.cmdi.componentregistry.persistence.jpa.GroupMembershipDao;
30import clarin.cmdi.componentregistry.persistence.jpa.OwnershipDao;
31import clarin.cmdi.componentregistry.persistence.jpa.UserDao;
32
33/**
34 * Service that manages groups, memberships and ownerships. It exposes some
35 * functions over JMX, that's why some methods use human-friendly names (user
36 * principal names, group names) rather than ID arguments.
37 *
38 * @author george.georgovassilis@mpi.nl
39 *
40 */
41@ManagedResource(objectName = "componentregistry:name=GroupService", description = "Operations for managing groups")
42@Service("GroupService")
43@Transactional
44public class GroupServiceImpl implements GroupService {
45
46    @Autowired
47    private GroupDao groupDao;
48    @Autowired
49    private GroupMembershipDao groupMembershipDao;
50    @Autowired
51    private OwnershipDao ownershipDao;
52    @Autowired
53    private ComponentDao componentDao;
54    @Autowired
55    private UserDao userDao;
56
57    public void setGroupDao(GroupDao groupDao) {
58        this.groupDao = groupDao;
59    }
60
61    public void setGroupMembershipDao(GroupMembershipDao groupMembershipDao) {
62        this.groupMembershipDao = groupMembershipDao;
63    }
64
65    public void setOwnershipDao(OwnershipDao ownershipDao) {
66        this.ownershipDao = ownershipDao;
67    }
68
69    @Override
70    public List<Group> getGroupsOwnedByUser(String ownerPrincipalName) {
71        RegistryUser owner = userDao.getByPrincipalName(ownerPrincipalName);
72        return groupDao.findGroupOwnedByUser(owner.getId().longValue());
73    }
74
75    @Override
76    public boolean isUserOwnerOfGroup(String groupName, String ownerPrincipalName) {
77        List<Group> groups = getGroupsOwnedByUser(ownerPrincipalName);
78        for (Group group : groups) {
79            if (group.getName().equals(groupName)) {
80                return true;
81            }
82        }
83
84        return false;
85    }
86
87    private void checkOwnership(Ownership ownership) {
88        if (ownership.getComponentId() == null) {
89            throw new RuntimeException("Ownership needs a componentId");
90        }
91        if (ownership.getUserId() == 0 && ownership.getGroupId() == 0) {
92            throw new RuntimeException("Ownership needs a groupId or userId");
93        }
94        if (ownership.getUserId() != 0 && ownership.getGroupId() != 0) {
95            throw new RuntimeException("Ownership has both a groupId and a userId ");
96        }
97    }
98
99    private void assertOwnershipDoesNotExist(Ownership ownership) {
100        Ownership o = ownershipDao.findOwnershipByGroupAndComponent(ownership.getGroupId(), ownership.getComponentId());
101        if (o != null) {
102            throw new ValidationException("Ownership exists");
103        }
104    }
105
106    @Override
107    public void addOwnership(Ownership ownership) {
108        checkOwnership(ownership);
109        assertOwnershipDoesNotExist(ownership);
110        ownershipDao.save(ownership);
111    }
112
113    @Override
114    public void removeOwnership(Ownership ownership) {
115        throw new RuntimeException("not implemented");
116    }
117
118    protected boolean canUserAccessAbstractDescriptionEitherOnHisOwnOrThroughGroupMembership(RegistryUser user,
119            BaseDescription description) {
120        // TODO make some joins and multi-id queries to speed the entire method
121        // up
122        boolean isProfile = (description instanceof ProfileDescription);
123        long userId = user.getId().longValue();
124        // anyone can access public profile
125        if (componentDao.isPublic(description.getId())) {
126            return true;
127        }
128        // the creator can also access any profile
129        if (description.getUserId().equals(user.getId() + "")) {
130            return true;
131        }
132
133        // a co-ownership on the profile also allows access
134        Ownership ownership = ownershipDao.findOwnershipByUserAndComponent(userId, description.getId());
135        if (ownership != null) {
136            return true;
137        }
138
139        // get a list of groups the user owns and is a member of
140        List<Group> groups = groupDao.findGroupOwnedByUser(userId);
141        Set<Long> groupIds = new HashSet<Long>();
142        for (Group group : groups) {
143            groupIds.add(group.getId());
144        }
145
146        List<GroupMembership> memberships = groupMembershipDao.findGroupsTheUserIsAmemberOf(userId);
147        for (GroupMembership gm : memberships) {
148            groupIds.add(gm.getGroupId());
149        }
150
151        for (Long groupId : groupIds) {
152            ownership = ownershipDao.findOwnershipByGroupAndComponent(groupId, description.getId());
153            if (ownership != null) {
154                return true;
155            }
156        }
157        return false;
158    }
159
160    @Override
161    public boolean canUserAccessComponentEitherOnHisOwnOrThroughGroupMembership(RegistryUser user,
162            BaseDescription baseDescription) {
163        return canUserAccessAbstractDescriptionEitherOnHisOwnOrThroughGroupMembership(user, baseDescription);
164    }
165
166    @Override
167    @ManagedOperation(description = "Make a user member of a group")
168    @ManagedOperationParameters({
169        @ManagedOperationParameter(name = "principalName", description = "Principal name of the user to make a member"),
170        @ManagedOperationParameter(name = "groupName", description = "Name of the group")})
171    public long makeMember(String userPrincipalName, String groupName) throws ItemNotFoundException{
172       
173        RegistryUser user = userDao.getByPrincipalName(userPrincipalName);
174       
175        if (user == null) {
176            throw new ItemNotFoundException("User with the principal name "+userPrincipalName+" is not found.");
177        }
178        Group group = groupDao.findGroupByName(groupName);
179       
180        if (group == null) {
181            throw new ItemNotFoundException("Group with the  name "+groupName+" is not found.");
182        }
183       
184        GroupMembership gm = groupMembershipDao.findMembership(user.getId().longValue(), group.getId());
185        if (gm != null) {
186            return gm.getId();
187        }
188        gm = new GroupMembership();
189        gm.setGroupId(group.getId());
190        gm.setUserId(user.getId().longValue());
191        return groupMembershipDao.save(gm).getId();
192    }
193   
194   
195//    @Override
196//    @ManagedOperation(description = "Remove user member from  a group")
197//    @ManagedOperationParameters({
198//        @ManagedOperationParameter(name = "principalName", description = "Principal name of the user to make a member"),
199//        @ManagedOperationParameter(name = "groupName", description = "Name of the group")})
200//    public long removeMember(String userPrincipalName, String groupName) throws ItemNotFoundException{
201//       
202//        RegistryUser user = userDao.getByPrincipalName(userPrincipalName);
203//       
204//        if (user == null) {
205//            throw new ItemNotFoundException("User the the principal name "+userPrincipalName+" is not found.");
206//        }
207//        Group group = groupDao.findGroupByName(groupName);
208//       
209//        if (group == null) {
210//            throw new ItemNotFoundException("Group with the  name "+groupName+" is not found.");
211//        }
212//       
213//       
214//        return groupMembershipDao.deleteMembership(user.getId(), group.getId());
215//    }
216
217   
218    @ManagedOperation(description = "Create a new group")
219    @ManagedOperationParameters({
220        @ManagedOperationParameter(name = "name", description = "Name of the group, must be unique"),
221        @ManagedOperationParameter(name = "ownerPrincipalName", description = "Principal name of the user")})
222    @Override
223    public long createNewGroup(String name, String ownerPrincipalName) {
224        RegistryUser owner = userDao.getByPrincipalName(ownerPrincipalName);
225        if (owner == null) {
226            throw new ValidationException("No principal '" + ownerPrincipalName + "' found");
227        }
228        Group group = groupDao.findGroupByName(name);
229        if (group != null) {
230            throw new ValidationException("Group '" + name + "' already exists");
231        }
232        group = new Group();
233        group.setName(name);
234        group.setOwnerId(owner.getId().longValue());
235        group = groupDao.save(group);
236        return group.getId();
237    }
238
239    @ManagedOperation(description = "List available groups")
240    @Override
241    public List<String> listGroupNames() {
242        List<String> groupNames = new ArrayList<String>();
243        for (Group group : groupDao.findAll()) {
244            groupNames.add(group.getName());
245        }
246        return groupNames;
247    }
248
249    @Override
250    public List<Group> getGroupsOfWhichUserIsAMember(String principal) {
251        RegistryUser user = userDao.getByPrincipalName(principal);
252        if (user == null || user.getId() == null) {
253            return new ArrayList<Group>();
254        }
255        List<GroupMembership> memberships = groupMembershipDao.findGroupsTheUserIsAmemberOf(user.getId().longValue());
256        List<Group> groups = new ArrayList<Group>();
257        for (GroupMembership m : memberships) {
258            groups.add(groupDao.findOne(m.getGroupId()));
259        }
260        return groups;
261    }
262
263    @Override
264    public List<String> getComponentIdsInGroup(long groupId) {
265        List<Ownership> ownerships = ownershipDao.findOwnershipByGroup(groupId);
266        Set<String> componentIds = new HashSet<String>();
267        for (Ownership o : ownerships) {
268            if (ComponentUtils.isComponentId(o.getComponentId())) {
269                componentIds.add(o.getComponentId());
270            }
271        }
272        List<String> idsList = new ArrayList<String>(componentIds);
273        Collections.sort(idsList);
274        return idsList;
275    }
276
277    @Override
278    public List<String> getProfileIdsInGroup(long groupId) {
279        List<Ownership> ownerships = ownershipDao.findOwnershipByGroup(groupId);
280        Set<String> profileIds = new HashSet<String>();
281        for (Ownership o : ownerships) {
282            if (ComponentUtils.isProfileId(o.getComponentId())) {
283                profileIds.add(o.getComponentId());
284            }
285        }
286        List<String> idsList = new ArrayList<String>(profileIds);
287        Collections.sort(idsList);
288        return idsList;
289    }
290
291    @Override
292    public List<Group> getGroupsTheItemIsAMemberOf(String itemId) {
293        Set<Ownership> ownerships = new HashSet<Ownership>();
294        ownerships.addAll(ownershipDao.findOwnershipByComponentId(itemId));
295        Set<Group> groups = new HashSet<Group>();
296        for (Ownership ownership : ownerships) {
297            groups.add(groupDao.findOne(ownership.getGroupId()));
298        }
299        List<Group> groupList = new ArrayList<Group>(groups);
300        Collections.sort(groupList, new Comparator<Group>() {
301            @Override
302            public int compare(Group g1, Group g2) {
303                return (int) (g1.getId() - g2.getId());
304            }
305        });
306        return groupList;
307    }
308
309    @ManagedOperation(description = "Make a component owned by a group instead of a user")
310    @ManagedOperationParameters({
311        @ManagedOperationParameter(name = "principal", description = "Name of the principal who owns the component"),
312        @ManagedOperationParameter(name = "groupName", description = "Name of the group to move the component to"),
313        @ManagedOperationParameter(name = "componentId", description = "Id of component")})
314    @Override
315    public void transferItemOwnershipFromUserToGroup(String principal, String groupName, String itemId) throws UserUnauthorizedException {
316
317
318        BaseDescription item = null;
319        item = componentDao.getByCmdId(itemId);
320        if (item == null) {
321            throw new ValidationException("No profile or component found with ID " + itemId);
322        }
323        Group group = groupDao.findGroupByName(groupName);
324        if (group == null) {
325            throw new ValidationException("No group found with name " + groupName);
326        }
327
328        if (!this.userGroupMember(principal, String.valueOf(group.getId()))) {
329            throw new UserUnauthorizedException("User " + principal + " is not a member of group " + groupName);
330        }
331
332        long userId = item.getDbUserId();
333        long principalId = userDao.getByPrincipalName(principal).getId();
334        if (userId != principalId) {
335            throw new UserUnauthorizedException("User " + principal + " is not creator of the item  " + item.getName());
336        }
337
338
339        Ownership ownership = null;
340        List<Ownership> oldOwnerships = ownershipDao.findOwnershipByComponentId(itemId);
341        ownershipDao.delete(oldOwnerships);
342        ownership = new Ownership();
343        ownership.setComponentId(itemId);
344        ownership.setGroupId(group.getId());
345        addOwnership(ownership);
346    }
347
348    @Override
349    public void transferItemOwnershipFromUserToGroupId(String principal, long groupId, String componentId) throws UserUnauthorizedException {
350        Group group = groupDao.findOne(groupId);
351        if (group == null) {
352            throw new ValidationException("No group found with id " + groupId);
353        }
354        this.transferItemOwnershipFromUserToGroup(principal, group.getName(), componentId);
355    }
356
357    @Override
358    public boolean userGroupMember(String principalName, String groupId) {
359        RegistryUser user = userDao.getByPrincipalName(principalName);
360        GroupMembership gm = groupMembershipDao.findMembership(user.getId(), Long.parseLong(groupId));
361        return gm != null;
362    }
363   
364    @Override
365    public  Number  getGroupIdByName(String groupName) throws ItemNotFoundException {
366        Group group = groupDao.findGroupByName(groupName);       
367        if (group != null) {
368            return group.getId();
369        } else {
370            throw new ItemNotFoundException("No group with the name "+groupName);
371        }
372    }
373   
374    @Override
375    public  String  getGroupNameById(long groupId) throws ItemNotFoundException {
376        Group group = groupDao.findOne(groupId);       
377        if (group != null) {
378            return group.getName();
379        } else {
380            throw new ItemNotFoundException("No group with the id "+groupId);
381        }
382    }
383}
Note: See TracBrowser for help on using the repository browser.