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