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

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

Added group service. Tested via the tomcat on loclahots (test URI and postman), old unit tests are adjusted and work well. Todo: retest on localhost tomcat, look at run-time exceptions, add new unit tests, adjust front-end

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