source: indico/indico/MaKaC/services/implementation/material.py @ ee7a3c

burotelhello-world-walkthroughipv6new-webexv0.97-seriesv0.98-seriesv0.98.2v0.98.3v0.98b1v0.98b2v0.99v1.0v1.1
Last change on this file since ee7a3c was ee7a3c, checked in by Jose Benito <jose.benito.gonzalez@…>, 3 years ago

[FIX] Edition material for categories fails

  • group materials in categories website can be edited properly
  • fix#443
  • Property mode set to 100644
File size: 12.5 KB
Line 
1"""
2Schedule-related services
3"""
4
5import MaKaC.conference as conference
6
7from MaKaC.common.PickleJar import DictPickler
8import MaKaC.webinterface.locators as locators
9from MaKaC.user import AvatarHolder, GroupHolder
10
11from MaKaC.services.interface.rpc.common import ServiceError, ServiceAccessError
12
13from MaKaC.services.implementation.base import ParameterManager
14from MaKaC.services.implementation.base import ProtectedModificationService
15from MaKaC.services.implementation.base import ProtectedDisplayService
16from MaKaC.errors import ModificationError, MaKaCError
17from MaKaC.common.fossilize import fossilize
18
19
20class UserListChange(object):
21
22    def changeUserList(self, object, newList):
23        # clone the list, to avoid problems
24        allowedUsers = object.getAllowedToAccessList()[:]
25
26        # user can be a user or group
27        for user in allowedUsers:
28            if not user.getId() in newList:
29                object.revokeAccess(user)
30            else:
31                del newList[user.getId()]
32
33        for elem in newList:
34            if 'isGroup' in elem and elem['isGroup']:
35                avatar = GroupHolder().getById(elem['id'])
36            else:
37                avatar = AvatarHolder().getById(elem['id'])
38            object.grantAccess(avatar)
39
40
41class MaterialBase(object):
42
43    def _checkParams( self ):
44        try:
45            l = locators.WebLocator()
46
47            self._material = None
48            self._conf = None
49
50            l.setMaterial( self._params, 0 )
51            self._target = l.getObject()
52
53
54            #if isinstance(self._target, conference.Material):
55            self._material = self._target
56            self._conf = self._target.getConference()
57            if self._conf == None:
58                self._categ = self._target
59            else:
60                self._categ = self._conf.getOwner()
61
62            ## TODO: remove this, since material/resource creation
63            ## doesn't come through this method
64
65            ## if isinstance(self._target, conference.Category):
66            ##     self._categ = self._target
67            ## else:
68            ##     self._conf = self._target.getConference()
69
70            ## if self._conf == None:
71            ##     self._categ=self._target.getCategory()
72
73
74        except Exception, e:
75            raise ServiceError("ERR-M0", str(e))
76
77class MaterialDisplayBase(ProtectedDisplayService, MaterialBase):
78
79    def _checkParams(self):
80        MaterialBase._checkParams(self)
81        ProtectedDisplayService._checkParams(self)
82
83class MaterialModifBase(MaterialBase, ProtectedModificationService):
84
85    def _checkParams(self):
86        MaterialBase._checkParams(self)
87        ProtectedModificationService._checkParams(self)
88
89    def _checkProtection(self):
90        owner = self._material.getOwner()
91
92        # There are two exceptions to the normal permission scheme:
93        # (sub-)contribution submitters and session coordinators
94
95        # in case the owner is a (sub-)contribution, we should
96        # allow submitters
97        if isinstance(owner, conference.Contribution) or \
98           isinstance(owner, conference.SubContribution):
99
100            reviewingState = self._material.getReviewingState()
101
102            if (reviewingState < 3 and
103                owner.canUserSubmit(self._aw.getUser())):
104                # Submitters have access
105                return
106            elif owner.getSession() and owner.getSession().canCoordinate(self._aw, "modifContribs"):
107                # Coordinators of the parent session have access
108                return
109
110        # if it's associated with a session, coordinators
111        # should be allowed
112        elif self._material.getSession() != None and \
113            self._material.getSession().canCoordinate(self._aw, "modifContribs"):
114            # Session coordinators have access
115            return
116
117        try:
118            ProtectedModificationService._checkProtection(self)
119        except ModificationError:
120            raise ServiceAccessError("ERR-P5", _("you are not authorised to manage material for this contribution"))
121        except Exception, e:
122            raise e
123
124class ResourceBase(object):
125    """
126    Base class for material resource access
127    """
128
129    def _checkParams(self):
130        """
131        Checks the materialId, and retrieves the material using it
132        """
133
134        self._material = None
135        self._conf = None
136
137        l = locators.WebLocator()
138
139        try:
140
141            l.setResource( self._params, 0 )
142            self._target = l.getObject()
143
144            if isinstance(self._target, conference.Resource):
145                self._resource = self._target
146                self._material = self._target.getOwner()
147
148            if isinstance(self._target, conference.Material):
149                self._material = self._target
150
151            if isinstance(self._target, conference.Category):
152                self._categ = self._target
153            else:
154                self._conf = self._target.getConference()
155
156            if self._conf == None:
157                self._categ=self._target.getCategory()
158
159        except Exception, e:
160            raise ServiceError("ERR-M0", str(e))
161
162
163class ResourceDisplayBase(ProtectedDisplayService, ResourceBase):
164
165    def _checkProtection(self):
166        ProtectedDisplayService._checkParams(self)
167
168    def _checkParams(self):
169        ResourceBase._checkParams(self)
170        ProtectedDisplayService._checkParams(self)
171
172class ResourceModifBase(ResourceBase, MaterialModifBase):
173
174    def _checkParams(self):
175        ResourceBase._checkParams(self)
176
177    #def _checkProtection(self):
178    #    MaterialModifBase._checkProtection(self)
179
180class GetMaterialClassesBase(MaterialDisplayBase):
181    """
182    Base class for obtaining a listing of material classes
183    """
184
185    def _checkParams( self ):
186        l = locators.WebLocator()
187
188        l.setMaterial( self._params, 0 )
189        self._target = l.getObject()
190
191
192    def _getAnswer(self):
193        """
194        Provides the list of material classes, based on the target
195        resource (conference, session, contribution, etc...)
196        """
197        matList = {}
198
199        for mat in self._target.getAllMaterialList():
200            matList[mat.getId()] = DictPickler.pickle(mat)
201
202        return matList
203
204class GetMaterial(MaterialDisplayBase):
205    """
206    Service for obtaining a material by id
207    """
208
209    def _getAnswer(self):
210        """
211        Provides the list of material classes, based on the target
212        resource (conference, session, contribution, etc...)
213        """
214        return DictPickler.pickle(self._material)
215
216
217class GetMaterialAllowedUsers(MaterialModifBase):
218    """
219    Lists the users that allowed to access the material
220    """
221
222    def _checkParams(self):
223        MaterialModifBase._checkParams(self)
224        self._includeFavList = self._params.get("includeFavList", False)
225        self._user = self._getUser() #will be None if user is not authenticated
226
227    def _getAnswer(self):
228        #will use IAvatarFossil or IGroupFossil
229        allowedAccesList = fossilize(self._material.getAllowedToAccessList())
230        if self._includeFavList and self._user:
231            favList = fossilize(self._user.getPersonalInfo().getBasket().getUsers().values())
232            return [allowedAccesList, favList]
233        else:
234            return allowedAccesList
235
236
237class GetMaterialProtection(MaterialModifBase):
238
239    def _getAnswer(self):
240        """
241        Returns the material's protection
242        """
243        try:
244            materialId = self._target.getMaterialById(self._params['matId'])
245        except:
246        #it's not in the material list, we return the parent's level of protection
247        #WATCH OUT! This is the default value to inherit from parent in Editor.js, if that value is changed
248        #for any reason this function may not work properly
249            return 0
250        else:
251            return materialId.getAccessProtectionLevel()
252
253
254class EditMaterialClassBase(MaterialModifBase, UserListChange):
255    """
256    Base class for material class edition
257    """
258
259    def _checkParams(self):
260        """
261        Gets a reference to the material, using the
262        id as the key, and gets the properties to change
263        """
264        MaterialModifBase._checkParams(self)
265
266        matId = self._params.get("materialId",None)
267        self._newProperties = self._params.get("materialInfo",None)
268        self._newUserList = self._newProperties['userList']
269
270        materialPM = ParameterManager(self._newProperties)
271
272        self._title = materialPM.extract('title', pType=str, allowEmpty=True, defaultValue="NO TITLE ASSIGNED")
273        self._description = materialPM.extract('description', pType=str, allowEmpty=True)
274        self._protection = materialPM.extract('protection', pType=int)
275        self._hidden = materialPM.extract('hidden', pType=int)
276        self._accessKey = materialPM.extract('accessKey', pType=str, allowEmpty=True)
277
278    def _getAnswer(self):
279        """
280        Updates the material with the new properties
281        """
282
283        self.changeUserList(self._material, self._newUserList)
284
285        self._material.setTitle(self._title);
286        self._material.setDescription(self._description);
287        self._material.setProtection(self._protection);
288        self._material.setHidden(self._hidden);
289        self._material.setAccessKey(self._accessKey);
290
291        event = self._material.getOwner()
292        materialRegistry = event.getMaterialRegistry()
293
294        return {
295            'material': DictPickler.pickle(self._material),
296            'newMaterialTypes': materialRegistry.getMaterialList(event)
297            }
298
299class DeleteMaterialClassBase(MaterialModifBase):
300
301    def _getAnswer(self):
302        materialId = self._material.getId()
303        event = self._material.getOwner()
304
305        # actually delete it
306        self._target.getOwner().removeMaterial(self._material)
307
308        materialRegistry = event.getMaterialRegistry()
309
310        return {
311            'deletedMaterialId': materialId,
312            'newMaterialTypes': materialRegistry.getMaterialList(event)
313            }
314
315class GetResourcesBase(ResourceDisplayBase):
316
317    def _getAnswer(self):
318        resList = {}
319
320        for resource in self._material.getResourceList():
321            resList[resource.getId()] = DictPickler.pickle(resource)
322        return resList
323
324class EditResourceBase(ResourceModifBase, UserListChange):
325
326    def _checkParams(self):
327        ResourceModifBase._checkParams(self)
328
329        resId = self._params.get("resourceId",None)
330        self._newProperties = self._params.get("resourceInfo",None)
331        self._newUserList = self._newProperties['userList']
332
333    def _getAnswer(self):
334
335        self.changeUserList(self._resource, self._newUserList)
336
337        DictPickler.update(self._resource, self._newProperties)
338        return DictPickler.pickle(self._resource)
339
340class GetResourceAllowedUsers(ResourceModifBase):
341    """
342    Lists the users that allowed to access the resource
343    """
344
345    def _checkParams(self):
346        ResourceModifBase._checkParams(self)
347        self._includeFavList = self._params.get("includeFavList", False)
348        self._user = self._getUser() #will be None if user is not authenticated
349
350    def _getAnswer(self):
351        #will use IAvatarFossil or IGroupFossil
352        allowedAccesList = fossilize(self._resource.getAllowedToAccessList())
353        if self._includeFavList and self._user:
354            favList = fossilize(self._user.getPersonalInfo().getBasket().getUsers().values())
355            return [allowedAccesList, favList]
356        else:
357            return allowedAccesList
358
359
360class DeleteResourceBase(ResourceModifBase):
361
362    def _getAnswer(self):
363        resourceId = self._resource.getId()
364
365        # remove the resource
366        self._material.removeResource(self._resource)
367        event = self._material.getOwner()
368
369        # if there are no resources left inside the material,
370        # just delete it
371        if len(self._material.getResourceList()) == 0:
372            event.removeMaterial(self._material)
373
374        newMaterialTypes = event.getMaterialRegistry().getMaterialList(event)
375
376        return {
377            'deletedResourceId': resourceId,
378            'newMaterialTypes': newMaterialTypes
379            }
380
381
382
383methodMap = {
384
385    "list": GetMaterialClassesBase,
386    "listAllowedUsers": GetMaterialAllowedUsers,
387    "get": GetMaterial,
388    "edit": EditMaterialClassBase,
389    "delete": DeleteMaterialClassBase,
390    "getProtection": GetMaterialProtection,
391
392    # Resource add is quite hacky, and uses a normal RH, because of file upload
393    # So, you won't find it here...
394    "resources.listAllowedUsers": GetResourceAllowedUsers,
395    "resources.list": GetResourcesBase,
396    "resources.edit": EditResourceBase,
397    "resources.delete": DeleteResourceBase
398    }
399
Note: See TracBrowser for help on using the repository browser.