improvements on security checking and login procedure
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1661 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
		
							parent
							
								
									0c789f3966
								
							
						
					
					
						commit
						49a90d95f2
					
				
					 10 changed files with 55 additions and 34 deletions
				
			
		|  | @ -342,7 +342,7 @@ We first need a view manager: | |||
| 
 | ||||
|   >>> from loops.view import ViewManager, Node | ||||
|   >>> from zope.security.checker import NamesChecker, defineChecker | ||||
|   >>> nodeChecker = NamesChecker(('body',)) | ||||
|   >>> nodeChecker = NamesChecker(('body', 'title',)) | ||||
|   >>> defineChecker(Node, nodeChecker) | ||||
| 
 | ||||
|   >>> views = loopsRoot['views'] = ViewManager() | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ from zope.publisher.interfaces.browser import IBrowserSkinType | |||
| from zope import schema | ||||
| from zope.schema.vocabulary import SimpleTerm | ||||
| from zope.security import canAccess, canWrite, checkPermission | ||||
| from zope.security.interfaces import ForbiddenAttribute | ||||
| from zope.security.proxy import removeSecurityProxy | ||||
| from zope.traversing.browser import absoluteURL | ||||
| from zope.traversing.api import getName | ||||
|  | @ -90,10 +91,15 @@ class EditForm(form.EditForm): | |||
| class BaseView(GenericView): | ||||
| 
 | ||||
|     def __init__(self, context, request): | ||||
|         # TODO: get rid of removeSecurityProxy() call | ||||
|         super(BaseView, self).__init__(context, request) | ||||
|         # TODO: get rid of removeSecurityProxy() call | ||||
|         self.context = removeSecurityProxy(context) | ||||
|         self.setSkin(self.loopsRoot.skinName) | ||||
|         try: | ||||
|             if not canAccess(context, 'title'): | ||||
|                 request.response.redirect('login.html') | ||||
|         except ForbiddenAttribute:  # ignore when testing | ||||
|             pass | ||||
| 
 | ||||
|     def setSkin(self, skinName): | ||||
|         skin = None | ||||
|  | @ -280,8 +286,7 @@ class BaseView(GenericView): | |||
| 
 | ||||
|     def openEditWindow(self, viewName='edit.html'): | ||||
|         if self.editable: | ||||
|             #if self.request.principal.id == 'rootadmin' | ||||
|             if checkPermission('zope.ManageSite', self.context): | ||||
|             if checkPermission('loops.ManageSite', self.context): | ||||
|                 return "openEditWindow('%s/@@%s')" % (self.url, viewName) | ||||
|         return '' | ||||
| 
 | ||||
|  | @ -291,8 +296,7 @@ class BaseView(GenericView): | |||
|         if not ct or ct == 'application/pdf': | ||||
|             return False | ||||
|         if ct.startswith('text/') and ct != 'text/rtf': | ||||
|             return checkPermission('zope.ManageSite', self.context) | ||||
|             #return self.request.principal.id == 'rootadmin' | ||||
|             return checkPermission('loops.ManageSite', self.context) | ||||
|         return canWrite(self.context, 'title') | ||||
| 
 | ||||
|     @Lazy | ||||
|  |  | |||
|  | @ -36,7 +36,7 @@ from zope.contenttype import guess_content_type | |||
| from zope.formlib.form import Form, EditForm, FormFields | ||||
| from zope.publisher.browser import FileUpload | ||||
| from zope.publisher.interfaces import BadRequest | ||||
| from zope.security.proxy import isinstance | ||||
| from zope.security.proxy import isinstance, removeSecurityProxy | ||||
| 
 | ||||
| from cybertools.ajax import innerHtml | ||||
| from cybertools.browser.form import FormController | ||||
|  | @ -211,7 +211,7 @@ class CreateObjectForm(ObjectForm, Form): | |||
|         typeToken = self.request.get('form.type') | ||||
|         if typeToken: | ||||
|             t = self.loopsRoot.loopsTraverse(typeToken) | ||||
|             ifc = ITypeConcept(t).typeInterface | ||||
|             ifc = removeSecurityProxy(ITypeConcept(t).typeInterface) | ||||
|         else: | ||||
|             ifc = INote | ||||
|         self.typeInterface = ifc | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
| 
 | ||||
|   <permission | ||||
|       id="loops.xmlrpc.ManageConcepts" | ||||
|       title="[xmlrpc-manage-concepts-permission] Manage Concepts" | ||||
|       title="[loops-xmlrpc-manage-concepts-permission] loops: Manage Concepts (XML-RPC)" | ||||
|       /> | ||||
| 
 | ||||
|   <role | ||||
|  | @ -20,9 +20,22 @@ | |||
|       permission="loops.xmlrpc.ManageConcepts" | ||||
|       role="loops.xmlrpc.ConceptManager" /> | ||||
| 
 | ||||
|   <!--<zope:grant | ||||
|   <permission | ||||
|       id="loops.ManageSite" | ||||
|       title="[loops-manage-site-permission] loops: Manage Site" | ||||
|       /> | ||||
| 
 | ||||
|   <role | ||||
|       id="loops.SiteManager" | ||||
|       title="[loops-manage-site-role] loops: Site Manager" /> | ||||
| 
 | ||||
|   <grant | ||||
|       permission="loops.ManageSite" | ||||
|       role="loops.SiteManager" /> | ||||
| 
 | ||||
|   <grant | ||||
|       permission="loops.xmlrpc.ManageConcepts" | ||||
|       role="zope.ContentManager" />--> | ||||
|       role="loops.SiteManager" /> | ||||
| 
 | ||||
|   <!-- event subscribers --> | ||||
| 
 | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ Type- and Text-based Queries | |||
|   >>> from loops.expert import query | ||||
|   >>> qu = query.Title('ty*') | ||||
|   >>> list(qu.apply()) | ||||
|   [0, 1, 39] | ||||
|   [0, 1, 41] | ||||
| 
 | ||||
|   >>> qu = query.Type('loops:*') | ||||
|   >>> len(list(qu.apply())) | ||||
|  | @ -67,7 +67,7 @@ syntax (that in turn is based on hurry.query). | |||
|   >>> stateNew = concepts['new'] | ||||
|   >>> qu = query.Resources(stateNew) | ||||
|   >>> list(qu.apply()) | ||||
|   [55, 60] | ||||
|   [57, 62] | ||||
| 
 | ||||
| 
 | ||||
| Fin de partie | ||||
|  |  | |||
|  | @ -236,7 +236,7 @@ get a type manager from all loops objects, always with the same context: | |||
| 
 | ||||
|   >>> types = typeManager.types | ||||
|   >>> sorted(t.token for t in types) | ||||
|   ['.loops/concepts/domain', '.loops/concepts/file', | ||||
|   ['.loops/concepts/domain', '.loops/concepts/file', '.loops/concepts/note', | ||||
|    '.loops/concepts/predicate', '.loops/concepts/query', | ||||
|    '.loops/concepts/textdocument', '.loops/concepts/topic', | ||||
|    '.loops/concepts/type'] | ||||
|  | @ -253,7 +253,8 @@ condition: | |||
|    '.loops/concepts/query', '.loops/concepts/topic', '.loops/concepts/type'] | ||||
|   >>> types = typeManager.listTypes(exclude=('concept',)) | ||||
|   >>> sorted(t.token for t in types) | ||||
|   ['.loops/concepts/file', '.loops/concepts/textdocument'] | ||||
|   ['.loops/concepts/file',  '.loops/concepts/note', | ||||
|    '.loops/concepts/textdocument'] | ||||
| 
 | ||||
| 
 | ||||
| Type-based interfaces and adapters | ||||
|  |  | |||
|  | @ -78,7 +78,7 @@ zcml in real life: | |||
| 
 | ||||
|   >>> t = searchView.typesForSearch() | ||||
|   >>> len(t) | ||||
|   8 | ||||
|   9 | ||||
|   >>> t.getTermByToken('loops:resource:*').title | ||||
|   'Any Resource' | ||||
| 
 | ||||
|  | @ -103,7 +103,7 @@ a controller attribute for the search view. | |||
| 
 | ||||
|   >>> searchView.submitReplacing('1.results', '1.search.form', pageView) | ||||
|   'return submitReplacing("1.results", "1.search.form", | ||||
|        "http://127.0.0.1/loops/views/page/.target9/@@searchresults.html")' | ||||
|        "http://127.0.0.1/loops/views/page/.target10/@@searchresults.html")' | ||||
| 
 | ||||
| Basic (text/title) search | ||||
| ------------------------- | ||||
|  | @ -202,7 +202,7 @@ of the concepts' titles: | |||
|   >>> request = TestRequest(form=form) | ||||
|   >>> view = Search(page, request) | ||||
|   >>> view.listConcepts() | ||||
|   "[['Zope (Topic)', '11']]" | ||||
|   "[['Zope (Topic)', '12']]" | ||||
| 
 | ||||
| Preset Concept Types on Search Forms | ||||
| ------------------------------------ | ||||
|  | @ -243,12 +243,12 @@ and thus include the customer type in the preset search types. | |||
| 
 | ||||
|   >>> searchView.conceptsForType('loops:concept:customer') | ||||
|   [{'token': 'none', 'title': u'not selected'}, | ||||
|    {'token': '17', 'title': u'Zope Corporation'}, | ||||
|    {'token': '18', 'title': u'cyberconcepts'}] | ||||
|    {'token': '18', 'title': u'Zope Corporation'}, | ||||
|    {'token': '19', 'title': u'cyberconcepts'}] | ||||
| 
 | ||||
| Let's use this new search option for querying: | ||||
| 
 | ||||
|   >>> form = {'search.4.text_selected': u'17'} | ||||
|   >>> form = {'search.4.text_selected': u'18'} | ||||
|   >>> resultsView = SearchResults(page, TestRequest(form=form)) | ||||
|   >>> results = list(resultsView.results) | ||||
|   >>> results[0].title | ||||
|  |  | |||
							
								
								
									
										2
									
								
								setup.py
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								setup.py
									
										
									
									
									
								
							|  | @ -82,7 +82,7 @@ class SetupManager(object): | |||
|         textdocument = self.addObject(conceptManager, Concept, | ||||
|                                       'textdocument', title=u'Text') | ||||
|         note = self.addObject(conceptManager, Concept, 'note', title=u'Note') | ||||
|         for c in (typeConcept, domain, query, file, textdocument, predicate): | ||||
|         for c in (typeConcept, domain, query, note, file, textdocument, predicate): | ||||
|             c.conceptType = typeConcept | ||||
|         ITypeConcept(typeConcept).typeInterface = ITypeConcept | ||||
|         ITypeConcept(query).typeInterface = IQueryConcept | ||||
|  |  | |||
							
								
								
									
										2
									
								
								type.py
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								type.py
									
										
									
									
									
								
							|  | @ -264,7 +264,7 @@ class TypeConcept(AdapterBase): | |||
|             conceptType = self.context | ||||
|             if conceptType == conceptType.getLoopsRoot().getConceptManager().getTypeConcept(): | ||||
|                 return ITypeConcept | ||||
|         return ti | ||||
|         return removeSecurityProxy(ti) | ||||
|     def setTypeInterface(self, ifc): | ||||
|         self.context._typeInterface = ifc | ||||
|     typeInterface = property(getTypeInterface, setTypeInterface) | ||||
|  |  | |||
|  | @ -48,15 +48,15 @@ Now let's add a few more concepts: | |||
| 
 | ||||
|   >>> topic = concepts[u'topic'] = Concept(u'Topic') | ||||
|   >>> intIds.register(topic) | ||||
|   9 | ||||
|   10 | ||||
|   >>> zope = concepts[u'zope'] = Concept(u'Zope') | ||||
|   >>> zope.conceptType = topic | ||||
|   >>> intIds.register(zope) | ||||
|   10 | ||||
|   11 | ||||
|   >>> zope3 = concepts[u'zope3'] = Concept(u'Zope 3') | ||||
|   >>> zope3.conceptType = topic | ||||
|   >>> intIds.register(zope3) | ||||
|   11 | ||||
|   12 | ||||
| 
 | ||||
| Navigation typically starts at a start object, which by default ist the | ||||
| domain concept (if present, otherwise the top-level type concept): | ||||
|  | @ -74,10 +74,10 @@ There are a few standard objects we can retrieve directly: | |||
| 
 | ||||
|   >>> defaultPred = xrf.getDefaultPredicate() | ||||
|   >>> defaultPred['id'], defaultPred['name'] | ||||
|   ('7', u'standard') | ||||
|   ('8', u'standard') | ||||
|   >>> typePred = xrf.getTypePredicate() | ||||
|   >>> typePred['id'], typePred['name'] | ||||
|   ('6', u'hasType') | ||||
|   ('7', u'hasType') | ||||
|   >>> typeConcept = xrf.getTypeConcept() | ||||
|   >>> typeConcept['id'], typeConcept['name'] | ||||
|   ('0', u'type') | ||||
|  | @ -85,7 +85,8 @@ There are a few standard objects we can retrieve directly: | |||
| In addition we can get a list of all types and all predicates available: | ||||
| 
 | ||||
|   >>> sorted(t['name'] for t in xrf.getConceptTypes()) | ||||
|   [u'domain', u'file', u'person', u'predicate', u'query', u'textdocument', u'type'] | ||||
|   [u'domain', u'file', u'note', u'person', u'predicate', u'query', | ||||
|    u'textdocument', u'type'] | ||||
|   >>> sorted(t['name'] for t in xrf.getPredicates()) | ||||
|   [u'hasType', u'standard'] | ||||
| 
 | ||||
|  | @ -96,7 +97,7 @@ We can also retrieve a certain object by its id or its name: | |||
|   ('2', u'query') | ||||
|   >>> textdoc = xrf.getObjectByName(u'textdocument') | ||||
|   >>> textdoc['id'], textdoc['name'] | ||||
|   ('4', u'textdocument') | ||||
|   ('5', u'textdocument') | ||||
| 
 | ||||
| All methods that retrieve one object also returns its children and parents: | ||||
| 
 | ||||
|  | @ -106,7 +107,8 @@ All methods that retrieve one object also returns its children and parents: | |||
|   >>> ch[0]['name'] | ||||
|   u'hasType' | ||||
|   >>> sorted(c['name'] for c in ch[0]['objects']) | ||||
|   [u'domain', u'file', u'person', u'predicate', u'query', u'textdocument', u'type'] | ||||
|   [u'domain', u'file', u'note', u'person', u'predicate', u'query', | ||||
|    u'textdocument', u'type'] | ||||
| 
 | ||||
|   >>> pa = defaultPred['parents'] | ||||
|   >>> len(pa) | ||||
|  | @ -124,9 +126,10 @@ We can also retrieve children and parents explicitely: | |||
|   >>> ch[0]['name'] | ||||
|   u'hasType' | ||||
|   >>> sorted(c['name'] for c in ch[0]['objects']) | ||||
|   [u'domain', u'file', u'person', u'predicate', u'query', u'textdocument', u'type'] | ||||
|   [u'domain', u'file', u'note', u'person', u'predicate', u'query', | ||||
|    u'textdocument', u'type'] | ||||
| 
 | ||||
|   >>> pa = xrf.getParents('6') | ||||
|   >>> pa = xrf.getParents('7') | ||||
|   >>> len(pa) | ||||
|   1 | ||||
|   >>> pa[0]['name'] | ||||
|  | @ -175,7 +178,7 @@ Updating the concept map | |||
| 
 | ||||
|   >>> topicId = xrf.getObjectByName('topic')['id'] | ||||
|   >>> xrf.createConcept(topicId, u'zope2', u'Zope 2') | ||||
|   {'description': u'', 'title': u'Zope 2', 'type': '9', 'id': '15', | ||||
|   {'description': u'', 'title': u'Zope 2', 'type': '10', 'id': '16', | ||||
|    'name': u'zope2'} | ||||
| 
 | ||||
| Changing the attributes of a concept | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 helmutm
						helmutm