Changeset 615


Ignore:
Timestamp:
08/09/06 17:09:13 (13 years ago)
Author:
jukka
Message:

Closed #618 and #617. Spent 4h for each. There is some security stuff and permissions.py should be the place for storing permissions that are relevant for LeMill, so that they don't have to be imported from miscallenous sources.

Location:
trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/BlogPost.py

    r539 r615  
    2929from Products.Archetypes.atapi import DisplayList 
    3030from FieldsWidgets import TagsField, TagsWidget 
    31  
     31from permissions import ModerateContent 
    3232 
    3333# Same thing as with MemberFolder but easier: MemberBlogs contain the values of groups itself in indexable storage. 
     
    138138        return True 
    139139 
     140    security.declareProtected(ModerateContent, 'delete_post') 
    140141    def delete_post(self): 
    141142        """ Hide, remove from recent posts and remove from Collaboration proposals """ 
    142143        container=self.getBlog() 
    143144        uid=self.UID() 
    144         self.content_status_modify(workflow_action='hide') 
     145        self.content_status_modify(workflow_action='delete') 
     146        self.reindexObject() 
    145147        if hasattr(container, 'recent_posts'): 
    146148            container.removeRecent_post(self.getId()) 
     
    152154            self.community.addCollaboration_proposal(uid) 
    153155 
     156    security.declareProtected(ModerateContent, 'undelete_post') 
    154157    def undelete_post(self): 
    155158        """ Bring back post but currently doesn't add to collaboration proposals or recent posts """ 
  • trunk/GroupBlog.py

    r599 r615  
    133133            label = 'Ban members', 
    134134            label_msgid = 'label_ban_members', 
    135             description = "If someone repeatedly offends against group, group founder can ban him and prevent from joining the group again. Separate user id's with commas.", 
     135            description = "If someone repeatedly offends against group, group founder can ban him and prevent from joining the group again. Separate user id's with commas. User id's can be found by going to offending members member page and noticing the address in the browser. Id is the last part of address, after /community/.", 
    136136            descriptio_msgid = 'help_ban_members', 
    137137            i18n_domain = "lemill", 
     
    197197        mtool = getToolByName(self, 'portal_membership') 
    198198        memberfolder=mtool.getHomeFolder() 
     199        me = mtool.getAuthenticatedMember() 
    199200        if memberfolder!=None and type(memberfolder)=='MemberFolder': 
    200201            memberfolder.note_action(item.UID(), item.portal_type, 'afterAdd') 
     
    203204            self._setProperty('left_slots', ['here/portlet_%s_actions/macros/portlet' % item.meta_type.lower(),], 'lines') 
    204205 
    205  
    206206    def at_post_edit_script(self): 
    207207        mtool = getToolByName(self, 'portal_membership') 
     
    210210            memberfolder.note_action(self.UID(), self.portal_type, 'post_edit') 
    211211 
    212  
     212    def setMeAsOwner(self): 
     213        mtool = getToolByName(self, 'portal_membership') 
     214        me = mtool.getAuthenticatedMember() 
     215        if [self.getId()] == self.users_with_local_role('Owner'): 
     216            self.manage_setLocalRoles(me.getId(), ['Owner']) 
     217            print self.users_with_local_role('Owner') 
     218             
    213219    def getGroupMaterials(self): 
    214220        portal_catalog = getToolByName(self, 'portal_catalog') 
     
    251257        membertool = getToolByName(self, 'portal_membership') 
    252258        group=grouptool.getGroupById(groupid) 
    253         #return DisplayList(group.getGroupMemberIds()) 
    254259        if no_self: 
    255260            dll = [membertool.getMember(y) for y in group.getGroupMemberIds() if y!=self.Creator()] 
     
    272277        group=grouptool.getGroupById(groupid) 
    273278        return memberid in group.getGroupMemberIds() 
     279 
     280 
     281    def canIModerate(self): 
     282        roles = self.getRoles() 
     283        return 'Manager' in roles or 'Reviewer' in roles 
     284 
     285 
     286    def getRoles(self, memberid=None): 
     287        """Helper method to get roles""" 
     288        if memberid: 
     289            return self.get_local_roles_for_userid(memberid) 
     290        else: 
     291            mtool = getToolByName(self, 'portal_membership') 
     292            user = mtool.getAuthenticatedMember()         
     293            return self.get_local_roles_for_userid(user.getId()) 
    274294         
    275295    def getBlog(self): 
     
    336356        userid = user.getId() 
    337357        groupid = self.getId() 
     358        banned=self.getField('banned').get(self)         
     359        if userid in banned: 
     360            msg= "You have been banned from this group and cannot join anymore." 
     361            url='%s?%s=%s' % (self.community.absolute_url(), 
     362                url_quote('portal_status_message'), 
     363                url_quote(msg)) 
     364            return REQUEST.RESPONSE.redirect(url) 
     365         
    338366        join_res = 0 
    339367        join_res = self.do_joining(userid, groupid) 
     
    398426        cat.set(self, value, **kwargs) 
    399427 
     428 
     429    def setModerators(self, value, **kwargs): 
     430        field=self.getField('moderators') 
     431        old_mods=field.get(self) 
     432        if old_mods==None or old_mods=='' or old_mods==['']: old_mods=[] 
     433        if value==None or value=='' or value==['']: value=[] 
     434        additions= [x for x in value if x not in old_mods] 
     435        for member in additions: 
     436            if member != '': 
     437                self.manage_setLocalRoles(member,['Reviewer']) 
     438        removals= [x for x in old_mods if x not in value] 
     439        for member in removals: 
     440            if 'Owner' not in self.get_local_roles_for_userid(member): 
     441                self.manage_delLocalRoles(member)             
     442        field.set(self, value, **kwargs) 
     443         
     444    def setBanned(self, value, **kwargs): 
     445        field=self.getField('banned') 
     446        banlist= [x.strip() for x in value.split(',')] 
     447        if banlist==['']: banlist=[] 
     448        grouptool = getToolByName(self, 'portal_groups') 
     449        groupid=self.getId() 
     450        group=grouptool.getGroupById(groupid) 
     451        groupmembers= group.getGroupMemberIds() 
     452        those_who_need_a_kick= [x for x in banlist if x in groupmembers] 
     453        for kickee in those_who_need_a_kick:             
     454            if 'Owner' not in self.get_local_roles_for_userid(kickee): # can't kick yourself 
     455                self.manage_delLocalRoles(kickee)                         
     456                self.do_leaving(kickee, groupid) # kick! 
     457        field.set(self, value, **kwargs) 
     458         
     459 
     460 
    400461    # These have to be duplicated since its difficult to base these folderish objects on non-folderish Resources  
    401462 
  • trunk/Resources.py

    r612 r615  
    2727from persistent.list import PersistentList 
    2828from Products.CMFPlone import PloneMessageFactory as PMF 
    29 from Products.CMFCore.permissions import ReviewPortalContent 
     29from permissions import ModerateContent 
    3030 
    3131import copy 
     
    310310 
    311311 
    312     security.declareProtected(ReviewPortalContent, 'deleteResource') 
     312    security.declareProtected(ModerateContent, 'deleteResource') 
    313313    def deleteResource(self, reason=''): 
    314314        """Set reason for deletion, set state to deleted and update catalog""" 
     
    319319         
    320320 
    321     security.declareProtected(ReviewPortalContent, 'rescue') 
     321    security.declareProtected(ModerateContent, 'rescue') 
    322322    def rescue(self): 
    323323        """Undelete a resource """ 
    324324        self.undeleteResource() 
    325325 
    326     security.declareProtected(ReviewPortalContent, 'undeleteResource') 
     326    security.declareProtected(ModerateContent, 'undeleteResource') 
    327327    def undeleteResource(self): 
    328328        f=self.getField('deletionReason') 
     
    469469            has_cover.set(self,False) 
    470470 
    471     def hideContent(self): 
    472         """Hide the content, replacing the delete function. Workflow takes care of security.""" 
    473         if self.portal_type in MATERIAL_TYPES or self.portal_type=='Piece': 
    474             self.content_status_modify(workflow_action='hide') 
    475  
    476     def revealContent(self): 
    477         """Reveal hidden content""" 
    478         if self.portal_type in MATERIAL_TYPES: 
    479             self.content_status_modify(workflow_action='retract') 
    480         if self.portal_type =='Piece': 
    481             self.content_status_modify(workflow_action='publish') 
    482  
    483471    def getGroupsEditing(self): 
    484472        """ return a list of groups that are this editing material """ 
  • trunk/skins/lemill/group_create_edit_script.cpy

    r543 r615  
    4343    blog=context.portal_groups.getGroupareaFolder(groupname) 
    4444    blog.setProperties(processed) 
    45  
     45if addname: 
     46    blog.setMeAsOwner() 
    4647 
    4748# also make these modifications to group blog 
  • trunk/skins/lemill/portlet_groupblog_actions.pt

    r597 r615  
    4040           <a href="" i18n:translate="link_undelete_post" tal:attributes="href string:${here_url}/undelete_post">Undelete post</a> 
    4141        </li> 
    42         <li tal:condition="isOwner"><a i18n:translate="link_manage_members" href="" tal:attributes="href string:$blogurl/base_edit">Manage group</a></li> 
    43         <li tal:condition="python: isOwner or canModerate"><a href="" i18n:translate="link_edit_categories" tal:attributes="href string:$blogurl/base_metadata">Edit categories</a></li> 
    44         <li tal:condition="python: isOwner or canModerate"><a href="" i18n:translate="link_edit_blogroll" tal:attributes="href string:$blogurl/base_metadata">Edit blogroll</a></li> 
     42        <li tal:condition="isOwner"><a i18n:translate="link_manage_members" href="" tal:attributes="href string:$blogurl/edit">Manage group</a></li> 
     43        <li tal:condition="python: isOwner or canModerate"><a href="" i18n:translate="link_edit_categories" tal:attributes="href string:$blogurl/edit_categories">Edit categories</a></li> 
     44        <li tal:condition="python: isOwner or canModerate"><a href="" i18n:translate="link_edit_blogroll" tal:attributes="href string:$blogurl/edit_links">Edit blogroll</a></li> 
    4545        <li><a href="" i18n:translate="link_leave_group" tal:attributes="href string:$blogurl/leave_group">Leave group</a></li> 
    4646    </ul> 
     
    8787        <tal:listing condition="python: n_mem&lt;400" repeat="memberid groupmembers"> 
    8888             <li tal:define="member python:mtool.getHomeFolder(memberid); 
     89                 memberroles python: blogobj.getRoles(memberid); 
    8990                 membername member/NiceName | nothing; 
    90                  member_url member/absolute_url | nothing"> 
     91                 member_url member/absolute_url | nothing; 
     92                 mod_ops python:'Reviewer' in memberroles; 
     93                 own_ops python:'Owner' in memberroles;"> 
    9194                 <a href="#" tal:attributes="href member_url" tal:content="membername">PLACEHOLDER</a> 
     95                 <tal:owner condition='own_ops'>*</tal:owner> 
     96                 <tal:moderator condition='mod_ops'>+</tal:moderator> 
    9297             </li> 
    9398        </tal:listing> 
  • trunk/skins/lemill/portlet_material_actions.pt

    r600 r615  
    7878<div class="tb-portlet" metal:define-macro="view_div"> 
    7979    <ul> 
    80         <li><a i18n:translate="link_fullscreen_view" tal:attributes="href string:${here_url}/fullscreen_view">Fullscreen view</a></li> 
     80        <li><a i18n:translate="link_fullscreen_view" tal:attributes="href string:${here_url}/">Fullscreen view</a></li> 
    8181        <li><a i18n:translate="link_print_view" href="TODO">Print view</a></li> 
    8282    </ul> 
  • trunk/tests/testGroups.py

    r585 r615  
    154154        result = self.publish(ob.absolute_url_path()+'/edit', basic=bauth).getBody() 
    155155        self.failIf(re.search('Unauthorized', result), 'Joined a group but cannot edit material.') 
     156         
     157    def testBanning(self): 
     158        """ test banning and unbanning """ 
     159        self.loginAsPortalOwner() 
     160        self.group = self.newGroup('testgroup') 
     161        self.workspace = self.getGroupBlog('testgroup') 
     162        self.workspace.join_group()        
     163        self.workspace.setBanned('foobar') 
     164        self.addUser('foobar','foobar', ('Member',)) 
     165        self.login('foobar') 
     166        bauth = ':'.join(('foobar', 'foobar')) 
     167        joining = self.publish(self.portal.absolute_url_path()+'/community/testgroup/join_group', basic=bauth).getBody() 
     168        self.failUnless(re.search('been%20banned', joining), 'User should be banned and unable to join. %s' % joining) 
     169        self.loginAsPortalOwner() 
     170        self.workspace.setBanned('') 
     171        self.login('foobar') 
     172        joining = self.publish(self.portal.absolute_url_path()+'/community/testgroup/join_group', basic=bauth).getBody() 
     173        self.failIf(re.search('been%20banned', joining), 'User should be able to join. %s' % joining) 
     174     
     175    def testModerating(self): 
     176        """ test moderation """ 
     177        self.loginAsPortalOwner() 
     178        self.group = self.newGroup('testgroup') 
     179        self.workspace = self.getGroupBlog('testgroup') 
     180        self.workspace.join_group()        
     181        self.addUser('foobar','foobar', ('Member',)) 
     182        self.login('foobar') 
     183        self.workspace.join_group() 
     184        self.loginAsPortalOwner() 
     185        self.workspace.setModerators(('foobar',)) 
     186        bauth = ':'.join(('foobar', 'foobar')) 
     187        cases = [('test1','Firstpost', 'Most inept that ever stepped', 'blog post')] 
     188        for (ID, TITLE, BODY, CATEGORY) in cases: 
     189            ob = self.construct('BlogPost',ID,self.portal.community.testgroup) 
     190            ob.processForm(values={'title':TITLE,'bodyText':BODY, 'category':CATEGORY}) 
     191            ob.at_post_edit_script()            
     192 
     193        self.login('foobar') 
     194        self.failUnless('Reviewer' in self.workspace.getRoles(), 'Member did not get moderator rights %s ' % self.workspace.getRoles()) 
     195        result= self.publish(self.portal.absolute_url_path()+'/community/testgroup/firstpost', basic=bauth).getBody() 
     196        self.failUnless(re.search('firstpost/delete_post', result), "Moderator can't see delete post link %s" % result) 
     197        try: 
     198            self.workspace.firstpost.delete_post() 
     199        except: 
     200            self.fail("Moderator couldn't delete post.")               
     201     
     202 
    156203 
    157204def test_suite(): 
Note: See TracChangeset for help on using the changeset viewer.