def upgrade(): from depot.manager import DepotManager from depot.fields.upload import UploadedFile from depot.fields.sqlalchemy import UploadedFileField from kotti import DBSession, metadata from kotti.resources import File t = sa.Table('files', metadata) t.c.data.type = sa.LargeBinary() dn = DepotManager.get_default() update = t.update() conn = DBSession.connection() for obj in DBSession.query(File): uploaded_file = UploadedFile({'depot_name': dn, 'files': []}) uploaded_file._thaw() uploaded_file.process_content(obj.data, filename=obj.filename, content_type=obj.mimetype) stored_file = DepotManager.get().get(uploaded_file['file_id']) stmt = update.where(t.c.id == obj.id).values( data=uploaded_file.encode()) res = conn.execute(stmt) assert res.rowcount == 1 stored_file.last_modified = obj.modification_date log.info("Migrated {} bytes for File with pk {} to {}/{}".format( len(obj.data), obj.id, dn, uploaded_file['file_id'])) DBSession.flush() if DBSession.get_bind().name != 'sqlite': # not supported by sqlite op.alter_column('files', 'data', type_=UploadedFileField())
def create_fruit(self, request): data = ast.literal_eval(request.body) fruit_category = \ DBSession.query(FruitCategory).filter_by( id=data['fruit_category']).first() name = str(uuid.uuid4()) fruit = Fruit(parent=fruit_category) fruit.__acl__ = SITE_ACL session = DBSession() session.add(fruit) workflow = get_workflow(fruit) if workflow: session.flush() workflow.transition_to_state(fruit, None, u'public') else: print '################ NO WORKFLOW for ', fruit.title session.flush() transaction.commit() fruit = DBSession.query(Fruit).filter_by(name=name).first() return {u'id': fruit.id, u'title': fruit.title, u'fruit_category': fruit.__parent__.id}
def create_fruit_category(self, request): data = ast.literal_eval(request.body) # Assume only one fruit_categories folder. fruit_categories_folder = \ DBSession.query(FruitCategoriesFolder).first() name = str(uuid.uuid4()) fruit_category = FruitCategory(name=name, title=data['title'], parent=fruit_categories_folder) fruit_category.__acl__ = SITE_ACL session = DBSession() session.add(fruit_category) workflow = get_workflow(fruit_category) if workflow: session.flush() workflow.transition_to_state(fruit_category, None, u'public') else: print '################ NO WORKFLOW for ', fruit_category.title session.flush() transaction.commit() fruit_category = \ DBSession.query(FruitCategory).filter_by(name=name).first() return {u'id': fruit_category.id, u'title': fruit_category.title}
def upgrade(): from depot.manager import DepotManager from depot.fields.upload import UploadedFile from depot.fields.sqlalchemy import UploadedFileField from kotti import DBSession, metadata from kotti.resources import File t = sa.Table('files', metadata) t.c.data.type = sa.LargeBinary() dn = DepotManager.get_default() update = t.update() conn = DBSession.connection() for obj in DBSession.query(File): uploaded_file = UploadedFile({'depot_name': dn, 'files': []}) uploaded_file._thaw() uploaded_file.process_content( obj.data, filename=obj.filename, content_type=obj.mimetype) stored_file = DepotManager.get().get(uploaded_file['file_id']) stmt = update.where( t.c.id == obj.id).values(data=uploaded_file.encode()) res = conn.execute(stmt) assert res.rowcount == 1 stored_file.last_modified = obj.modification_date log.info("Migrated {} bytes for File with pk {} to {}/{}".format( len(obj.data), obj.id, dn, uploaded_file['file_id'])) DBSession.flush() if DBSession.get_bind().name != 'sqlite': # not supported by sqlite op.alter_column('files', 'data', type_=UploadedFileField())
def edit_job(request, user, resume_id): t = request.POST["experience"] if resume_id != int(request.POST['resume_id']): #TODO raise error pass if t == "new": resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first() job_schema = JobSchema() cstruct = job_schema.deserialize(request.POST) job_obj = resources.Job() cstruct2job(cstruct, job_obj) resume.jobs.append(job_obj) #flush to get the new id DBSession.flush() widget = JobsWidget(resume_id, resume.jobs) json_string = json.dumps({'__result':0}) return Response(json_string+"$"+widget.render()) elif t == "modify": job_schema = JobSchema() cstruct = job_schema.deserialize(request.POST) DBSession.query(resources.Job).filter_by(resume_id=resume_id, id=int(request.POST['id'])).\ update(cstruct, synchronize_session=False) resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first() widget = JobsWidget(resume_id, resume.jobs) json_string = json.dumps({'__result':0}) return Response(json_string+"$"+widget.render()) elif t == "delete": job = DBSession.query(resources.Job).filter_by(resume_id=resume_id, id=int(request.POST['id'])).first() oid = job.id DBSession.delete(job) return Response(json.dumps({'__result':0,'id':oid})) return Response(json.dumps({'__result':1}))
def upgrade(): sa.orm.events.MapperEvents._clear() # avoids filedepot magic from depot.manager import DepotManager from depot.fields.upload import UploadedFile from depot.fields.sqlalchemy import UploadedFileField from kotti import DBSession, metadata from kotti.resources import File t = sa.Table("files", metadata) t.c.data.type = sa.LargeBinary() dn = DepotManager.get_default() for obj in DBSession.query(File): uploaded_file = UploadedFile({"depot_name": dn, "files": []}) uploaded_file._thaw() uploaded_file.process_content(obj.data, filename=obj.filename, content_type=obj.mimetype) stored_file = DepotManager.get().get(uploaded_file["file_id"]) obj.data = uploaded_file.encode() stored_file.last_modified = obj.modification_date log.info( "Migrated {} bytes for File with pk {} to {}/{}".format(len(obj.data), obj.id, dn, uploaded_file["file_id"]) ) DBSession.flush() if DBSession.get_bind().name != "sqlite": # not supported by sqlite op.alter_column("files", "data", type_=UploadedFileField())
def edit_education(request, user, resume_id): t = request.POST["education"] if resume_id != int(request.POST['resume_id']): #TODO raise error pass if t == 'new': resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first() edu_schema = Education() cstruct = edu_schema.deserialize(request.POST) edu_obj = resources.Education() cstruct2edu(cstruct, edu_obj) resume.educations.append(edu_obj) #flush to get the new id DBSession.flush() widget = EducationsWidget(resume_id, resume.educations) json_string = json.dumps({'__result':0}) return Response(json_string+"$"+widget.render()) elif t == 'modify': edu_schema = Education() cstruct = edu_schema.deserialize(request.POST) DBSession.query(resources.Education).filter_by(resume_id=resume_id, id=int(request.POST['id'])).\ update(cstruct, synchronize_session=False) resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first() widget = EducationsWidget(resume_id, resume.educations) json_string = json.dumps({'__result':0}) return Response(json_string+"$"+widget.render()) elif t == 'delete': edu = DBSession.query(resources.Education).filter_by(resume_id=resume_id, id=int(request.POST['id'])).first() oid = edu.id DBSession.delete(edu) return Response(json.dumps({'__result':0,'id':oid})) # raise error, not exists this operation return Response(json.dumps({'__result':1}))
def paste_nodes(self): """ Paste nodes view. Paste formerly copied or cutted nodes into the current context. Note that a cutted node can not be pasted into itself. :result: Redirect response to the referrer of the request. :rtype: pyramid.httpexceptions.HTTPFound """ ids, action = self.request.session["kotti.paste"] for count, id in enumerate(ids): item = DBSession.query(Node).get(id) if item is not None: if action == "cut": if not self.request.has_permission("edit", item): raise Forbidden() item.__parent__.children.remove(item) item.name = title_to_name(item.name, blacklist=self.context.keys()) self.context[item.name] = item if count is len(ids) - 1: del self.request.session["kotti.paste"] elif action == "copy": copy = item.copy() name = copy.name if not name: # for root name = copy.title name = title_to_name(name, blacklist=self.context.keys()) copy.name = name self.context[name] = copy self.flash( _("${title} was pasted.", mapping=dict(title=item.title)), "success" ) else: self.flash(_("Could not paste node. It no longer exists."), "error") DBSession.flush() if not self.request.is_xhr: return self.back()
def test_principals_with_local_roles(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node from kotti.security import map_principals_with_local_roles from kotti.security import principals_with_local_roles from kotti.security import set_groups root = get_root() child = root[u'child'] = Node() DBSession.flush() self.assertEqual(principals_with_local_roles(root), []) self.assertEqual(principals_with_local_roles(child), []) self.assertEqual(map_principals_with_local_roles(root), []) self.assertEqual(map_principals_with_local_roles(child), []) set_groups('group:bobsgroup', child, ['role:editor']) set_groups('bob', root, ['group:bobsgroup']) set_groups('group:franksgroup', root, ['role:editor']) self.assertEqual(set(principals_with_local_roles(child)), set(['bob', 'group:bobsgroup', 'group:franksgroup'])) self.assertEqual( set(principals_with_local_roles(child, inherit=False)), set(['group:bobsgroup'])) self.assertEqual(set(principals_with_local_roles(root)), set(['bob', 'group:franksgroup']))
def edit_project(request, user, resume_id): t = request.POST["project"] if resume_id != int(request.POST['resume_id']): return Response(json.dumps({'__result':1})) #TODO use try/except if t == "new": resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first() obj = resources.ProjectInfo() cstruct2project(request.POST, obj) resume.projects.append(obj) #flush to get the new id DBSession.flush() widget = ProjectWidget(resume_id, resume.projects) json_string = json.dumps({'__result':0}) return Response(json_string+"$"+widget.render()) elif t == "modify": cstruct = {} cstruct2project(request.POST, cstruct) DBSession.query(resources.ProjectInfo).filter_by(resume_id=resume_id, id=int(request.POST['id'])).\ update(cstruct, synchronize_session=False) resume = DBSession.query(resources.Resume).filter_by(user=user, id=resume_id).first() widget = ProjectWidget(resume_id, resume.projects) json_string = json.dumps({'__result':0}) return Response(json_string+"$"+widget.render()) elif t == "delete": project = DBSession.query(resources.ProjectInfo).filter_by(resume_id=resume_id, id=int(request.POST['id'])).first() oid = project.id DBSession.delete(project) return Response(json.dumps({'__result':0,'id':oid})) return Response(json.dumps({'__result':1}))
def make_document(self, root): from kotti.resources import Document doc = root['doc'] = Document() from kotti import DBSession DBSession.flush() DBSession.refresh(doc) return doc
def test_resume2(): stu = DBSession.query(MbaUser).filter_by(email='*****@*****.**').first() resume1 = Resume(title=u'resume1', user=stu) start_date = datetime.strptime('2003-1-1','%Y-%m-%d').date() finish_date = datetime.strptime('2008-1-1','%Y-%m-%d').date() edu = Education( school_name = u'电子科技大学', start_date=start_date, finish_date=finish_date, major=u'通信工程', degree = 1) resume1.educations.append(edu) job = Job( industy = u'美丽的台湾公司', industy_type = 1, industy_scale = 1, duty = u'软件工程师', start_date = start_date, finish_date = finish_date, ) resume1.jobs.append(job) DBSession.add(resume1) DBSession.flush()
def test_inherit(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node from kotti.security import list_groups from kotti.security import list_groups_raw from kotti.security import set_groups root = get_root() child = root[u'child'] = Node() DBSession.flush() self.assertEqual(list_groups('bob', child), []) set_groups('bob', root, ['role:editor']) self.assertEqual(list_groups('bob', child), ['role:editor']) # Groups from the child are added: set_groups('bob', child, ['group:somegroup']) self.assertEqual( set(list_groups('bob', child)), set(['group:somegroup', 'role:editor']) ) # We can ask to list only those groups that are defined locally: self.assertEqual( list_groups_raw(u'bob', child), set(['group:somegroup']))
def test_copy_local_groups(self): from kotti import DBSession from kotti.resources import get_root from kotti.security import principals_with_local_roles from kotti.security import set_groups self.test_principals_with_local_roles() root = get_root() child = root[u'child'] self.assertEqual(set(principals_with_local_roles(child)), set(['bob', 'group:bobsgroup', 'group:franksgroup'])) # We make a copy of 'child', and we expect the local roles set # on 'child' to not be copied over: child2 = root['child2'] = child.copy() DBSession.flush() self.assertEqual( set(principals_with_local_roles(child2)), set([u'bob', u'group:franksgroup']), ) self.assertEqual(len(principals_with_local_roles(child)), 3) # When we now change the local roles of 'child', the copy is # unaffected: set_groups('group:bobsgroup', child, []) self.assertEqual(len(principals_with_local_roles(child)), 2) self.assertEqual(len(principals_with_local_roles(child2)), 2)
def view_review(context, request): jquery.need() contextbody = jinja2.Markup(context.body) user = get_user(request) if request.POST : if user is None: request.session.flash(u"请先登陆..","info") came_from = request.url return HTTPFound("/login?came_from=%s" % came_from) if 'submit' in request.POST: comment_content = request.params.get("review-comment-input") comment = Comment() comment.type = comment.TYPE_MEETUP_REVIEW comment.user_id = user.id comment.document_id = context.id # ACTION!!!: There is a SQL injection risk here! should be prevented comment.content = comment_content DBSession.add( comment) DBSession.flush() return wrap_user2(request, {'context':context, 'contextbody': contextbody, 'comments_count': len(context.comments) })
def view_meetups(request): if 'delete' in request.POST: todel = request.POST.getall('meetupcheck') for mid in todel: # print 'mid:%s, len mid:%d'% ( mid, len(mid) ) meetup = DBSession.query(Act).filter_by(id=int(mid)).first() if meetup is not None : # print meetup if len(meetup.parts) != 0: request.session.flash(u"活动'%s..'由于已经有人报名不能删除!" % meetup.title[:10], 'danger') else: meetup.status = Act.STATUS_DELETED request.session.flash(u"活动'%s..'已成功删除!" % meetup.title[:10], 'success') DBSession.flush() # DBSession.commit() return view_meetup_entry()
def add_some_groups(): session = DBSession() root = get_root() child = root[u'child'] = Node() grandchild = child[u'grandchild'] = Node() session.flush() # root: # bob -> group:bobsgroup # frank -> group:franksgroup # group:franksgroup -> role:editor # child: # group:bobsgroup -> group:franksgroup # grandchild: # group:franksgroup -> role:admin # group:franksgroup -> group:bobsgroup # bob and frank are a site-wide members of their respective groups: set_groups('bob', root, ['group:bobsgroup']) set_groups('frank', root, ['group:franksgroup']) # franksgroup has a site-wide editor role: set_groups('group:franksgroup', root, ['role:editor']) # bobsgroup is part of franksgroup on the child level: set_groups('group:bobsgroup', child, ['group:franksgroup']) # franksgroup has the admin role on the grandchild. # and finally, to test recursion, we make franksgroup part of # bobsgroup on the grandchild level: set_groups('group:franksgroup', grandchild, ['role:owner', 'group:bobsgroup'])
def test_principals_with_local_roles(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node from kotti.security import map_principals_with_local_roles from kotti.security import principals_with_local_roles from kotti.security import set_groups root = get_root() child = root[u'child'] = Node() DBSession.flush() self.assertEqual(principals_with_local_roles(root), []) self.assertEqual(principals_with_local_roles(child), []) self.assertEqual(map_principals_with_local_roles(root), []) self.assertEqual(map_principals_with_local_roles(child), []) set_groups('group:bobsgroup', child, ['role:editor']) set_groups('bob', root, ['group:bobsgroup']) set_groups('group:franksgroup', root, ['role:editor']) self.assertEqual( set(principals_with_local_roles(child)), set(['bob', 'group:bobsgroup', 'group:franksgroup']) ) self.assertEqual( set(principals_with_local_roles(child, inherit=False)), set(['group:bobsgroup']) ) self.assertEqual( set(principals_with_local_roles(root)), set(['bob', 'group:franksgroup']) )
def test_act(): # Step 1 Act test print 'Test Act' print DBSession.query(Act).count() act = Act(**_TEST_ATTRS) DBSession.add(act) print DBSession.query(Act).count() print 'Act.parts', act.parts # Step 2 Student test print 'Test Student' print DBSession.query(Student).count() stu = Student(name=u'test') DBSession.add(stu) print DBSession.query(Student).count() # Step 3 Participate test part = Participate() part.act_id = act.id part.user_id = stu.id DBSession.add(part) print 'Act.parts', act.parts DBSession.flush() #part = DBSession.query(Participate).first() #print 'Part user', part.user, part.act_id act = DBSession.query(Act).first() print 'query Act', act.id print 'Act.parts', act._parts
def test_copy_local_groups(self): from kotti import DBSession from kotti.resources import get_root from kotti.security import principals_with_local_roles from kotti.security import set_groups self.test_principals_with_local_roles() root = get_root() child = root[u'child'] self.assertEqual( set(principals_with_local_roles(child)), set(['bob', 'group:bobsgroup', 'group:franksgroup']) ) # We make a copy of 'child', and we expect the local roles set # on 'child' to not be copied over: child2 = root['child2'] = child.copy() DBSession.flush() self.assertEqual( set(principals_with_local_roles(child2)), set([u'bob', u'group:franksgroup']), ) self.assertEqual(len(principals_with_local_roles(child)), 3) # When we now change the local roles of 'child', the copy is # unaffected: set_groups('group:bobsgroup', child, []) self.assertEqual(len(principals_with_local_roles(child)), 2) self.assertEqual(len(principals_with_local_roles(child2)), 2)
def test_groups_from_users(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node from kotti.security import list_groups from kotti.security import set_groups self.make_bob() root = get_root() child = root[u'child'] = Node() DBSession.flush() self.assertEqual(list_groups('bob', root), ['group:bobsgroup']) set_groups('group:bobsgroup', root, ['role:editor']) set_groups('role:editor', child, ['group:foogroup']) self.assertEqual( set(list_groups('bob', root)), set(['group:bobsgroup', 'role:editor']) ) self.assertEqual( set(list_groups('bob', child)), set(['group:bobsgroup', 'role:editor', 'group:foogroup']) )
def make_document(self, root): from kotti import DBSession from kotti.resources import Document content = root['doc'] = Document(title=u'MyDocument') DBSession.flush() DBSession.refresh(content) return content
def make_document(self): from kotti import DBSession from kotti.resources import Document content = self.root['document'] = Document() DBSession.flush() DBSession.refresh(content) return content
def make_document(self, root): from kotti import DBSession from kotti.resources import Document content = root["document"] = Document() DBSession.flush() DBSession.refresh(content) return content
def make_document(root): from kotti import DBSession from kotti.resources import Document content = root["document"] = Document() DBSession.flush() DBSession.refresh(content) return content
def test_works_with_auth(self): session = DBSession() root = get_root() child = root[u'child'] = Node() session.flush() request = DummyRequest() auth = CallbackAuthenticationPolicy() auth.unauthenticated_userid = lambda *args: 'bob' auth.callback = list_groups_callback request.context = root self.assertEqual( # user doesn't exist yet auth.effective_principals(request), ['system.Everyone'] ) get_principals()[u'bob'] = dict(name=u'bob') self.assertEqual( auth.effective_principals(request), ['system.Everyone', 'system.Authenticated', 'bob'] ) # Define that bob belongs to bobsgroup on the root level: set_groups('bob', root, ['group:bobsgroup']) request.context = child self.assertEqual( set(auth.effective_principals(request)), set([ 'system.Everyone', 'system.Authenticated', 'bob', 'group:bobsgroup' ]) ) # define that bob belongs to franksgroup in the user db: get_principals()[u'bob'].groups = [u'group:franksgroup'] set_groups('group:franksgroup', child, ['group:anothergroup']) self.assertEqual( set(auth.effective_principals(request)), set([ 'system.Everyone', 'system.Authenticated', 'bob', 'group:bobsgroup', 'group:franksgroup', 'group:anothergroup', ]) ) # And lastly test that circular group defintions are not a # problem here either: get_principals()[u'group:franksgroup'] = dict( name=u'group:franksgroup', title=u"Frank's group", groups=[u'group:funnygroup', u'group:bobsgroup'], ) self.assertEqual( set(auth.effective_principals(request)), set([ 'system.Everyone', 'system.Authenticated', 'bob', 'group:bobsgroup', 'group:franksgroup', 'group:anothergroup', 'group:funnygroup', ]) )
def test_unique_constraint(self, db_session): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node # Try to add two children with the same name to the root node: root = get_root() DBSession.add(Node(name=u'child1', parent=root)) DBSession.add(Node(name=u'child1', parent=root)) with raises(IntegrityError): DBSession.flush()
def save_success(self, appstruct): appstruct.pop('csrf_token', None) name = self.find_name(appstruct) new_item = self.context[name] = self.add(company_id=self.company_id, **appstruct) self.request.session.flash(self.success_message, 'success') location = self.success_url or self.request.resource_url(new_item) #session.refresh(f) DBSession.flush() idstr = str(new_item.id) location = '/job-detail/' + idstr return HTTPFound(location=location)
def test_friend(): #u1,u2,u3,u4,u5 = MbaUser(u'u1'), MbaUser(u'u2'), MbaUser(u'u3'), \ # MbaUser(u'u4'), MbaUser(u'u5') u1,u2,u3,u4,u5 = Student(u'u1'), Student(u'u2'), Student(u'u3'), \ Student(u'u4'), Student(u'u5') u1.friends = [u2, u3] u4.friends = [u2, u5] u3.friends.append(u5) DBSession.add_all([u1,u2,u3,u4,u5]) DBSession.flush() print 'u2 all', u2.all_friends print 'u5 all', u5.all_friends
def test_container_methods(self, db_session): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node # Test some of Node's container methods: root = get_root() assert root.keys() == [] child1 = Node(name=u'child1', parent=root) DBSession.add(child1) assert root.keys() == [u'child1'] assert root[u'child1'] == child1 del root[u'child1'] assert root.keys() == [] # When we delete a parent node, all its child nodes will be # released as well: root[u'child2'] = Node() root[u'child2'][u'subchild'] = Node() assert ( DBSession.query(Node).filter(Node.name == u'subchild').count() == 1) del root[u'child2'] assert ( DBSession.query(Node).filter(Node.name == u'subchild').count() == 0) # We can pass a tuple as the key to more efficiently reach # down to child objects: root[u'child3'] = Node() subchild33 = Node(name=u'subchild33', parent=root[u'child3']) DBSession.add(subchild33) del root.__dict__['_children'] # force a different code path assert root[u'child3', u'subchild33'] is root[u'child3'][u'subchild33'] assert root[(u'child3', u'subchild33')] is subchild33 assert root[(u'child3', u'subchild33')] is subchild33 with raises(KeyError): root[u'child3', u'bad-name'] root.children # force a different code path with raises(KeyError): root[u'child3', u'bad-name'] del root[u'child3'] # Overwriting an existing Node is an error; first delete manually! child4 = Node(name=u'child4', parent=root) DBSession.add(child4) assert root.keys() == [u'child4'] child44 = Node(name=u'child4') DBSession.add(child44) root[u'child4'] = child44 with raises(SQLAlchemyError): DBSession.flush()
def test_container_methods(self, db_session): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node # Test some of Node's container methods: root = get_root() assert root.keys() == [] child1 = Node(name=u'child1', parent=root) DBSession.add(child1) assert root.keys() == [u'child1'] assert root[u'child1'] == child1 del root[u'child1'] assert root.keys() == [] # When we delete a parent node, all its child nodes will be # released as well: root[u'child2'] = Node() root[u'child2'][u'subchild'] = Node() assert (DBSession.query(Node).filter( Node.name == u'subchild').count() == 1) del root[u'child2'] assert (DBSession.query(Node).filter( Node.name == u'subchild').count() == 0) # We can pass a tuple as the key to more efficiently reach # down to child objects: root[u'child3'] = Node() subchild33 = Node(name=u'subchild33', parent=root[u'child3']) DBSession.add(subchild33) del root.__dict__['_children'] # force a different code path assert root[u'child3', u'subchild33'] is root[u'child3'][u'subchild33'] assert root[(u'child3', u'subchild33')] is subchild33 assert root[(u'child3', u'subchild33')] is subchild33 with raises(KeyError): root[u'child3', u'bad-name'] root.children # force a different code path with raises(KeyError): root[u'child3', u'bad-name'] del root[u'child3'] # Overwriting an existing Node is an error; first delete manually! child4 = Node(name=u'child4', parent=root) DBSession.add(child4) assert root.keys() == [u'child4'] child44 = Node(name=u'child4') DBSession.add(child44) root[u'child4'] = child44 with raises(SQLAlchemyError): DBSession.flush()
def test_node_copy_parent_id(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node root = get_root() child1 = root['child1'] = Node() grandchild1 = child1['grandchild1'] = Node() DBSession.flush() grandchild2 = grandchild1.copy() assert grandchild2.parent_id is None assert grandchild2.parent is None
def test_visitors(): stu1 = Student(name=u'test1', real_name=u'testit1') stu2 = Student(name=u'test2', real_name=u'testit2') stu3 = Student(name=u'test3', real_name=u'testit3') DBSession.add(stu1) DBSession.add(stu2) DBSession.add(stu3) DBSession.flush() stu2.add_visit(stu1) stu2.add_visit(stu3) print stu2.visitors
def test_node_copy_parent_id(self, db_session): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node root = get_root() child1 = root['child1'] = Node() grandchild1 = child1['grandchild1'] = Node() DBSession.flush() grandchild2 = grandchild1.copy() assert grandchild2.parent_id is None assert grandchild2.parent is None
def test_document(): print 'Test Act' print DBSession.query(Act).count() act = Act(**_TEST_ATTRS) DBSession.add(act) print DBSession.query(Act).count() act.tags = [u'tag 1', u'tag 2'] DBSession.flush() act = DBSession.query(Act).first() print act.tags print act._tags for t in act._tags: print t.item,
def populate_interests(): if DBSession.query(Interest).count() == 0: inter = [u"唱歌/K歌",u"听音乐",u"看电影",u"看韩剧/综艺娱乐节目",u"看书/小说/杂志",u"逛街/购物",u"跳舞",u"演奏乐器", u"去健身房健身/减肥/塑形/瑜伽",u"打篮球",u"踢足球",u"打排球",u"跑步",u"打羽毛球",u"打乒乓球",u"保龄球", u"高尔夫",u"远足",u"爬山/登山",u"X运动",u"游泳",u"划船/水上娱乐",u"钓鱼/养鱼",u"饲养宠物",u"玩网络游戏/单机游戏", u"上网聊天/论坛/贴吧",u"看新闻",u"摄影/摄像",u"旅游",u"吃美食/做饭",u"十字绣/织毛衣/做服装服饰",u"打扑克/麻将", u"写字/练字/书法",u"下棋/各种棋",u"睡觉",u"美容/保养/化妆/打扮"] for int in inter: io = Interest(name=int) DBSession.add(io) DBSession.flush()
def test_node_copy_with_local_groups(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node from kotti.resources import LocalGroup root = get_root() child1 = root['child1'] = Node() local_group1 = LocalGroup(child1, u'joe', u'role:admin') DBSession.add(local_group1) DBSession.flush() child2 = root['child2'] = child1.copy() DBSession.flush() assert child2.local_groups == []
def test_nested_annotations_mutable(self, db_session): from kotti import DBSession from kotti.resources import get_root root = get_root() root.annotations['foo'] = {} DBSession.flush() DBSession.expire_all() root = get_root() root.annotations['foo']['bar'] = u'baz' assert root in DBSession.dirty DBSession.flush() DBSession.expire_all() root = get_root() assert root.annotations['foo']['bar'] == u'baz'
def test_nested_annotations_mutable(self): from kotti import DBSession from kotti.resources import get_root root = get_root() root.annotations['foo'] = {} DBSession.flush() DBSession.expire_all() root = get_root() root.annotations['foo']['bar'] = u'baz' self.assertTrue(root in DBSession.dirty) DBSession.flush() DBSession.expire_all() root = get_root() self.assertEqual(root.annotations['foo']['bar'], u'baz')
def test_set_and_get_acl(self): from kotti import DBSession from kotti.resources import get_root root = get_root() # The __acl__ attribute of Nodes allows access to the mapped # '_acl' property: del root.__acl__ self.assertRaises(AttributeError, root._get_acl) root.__acl__ = [('Allow', 'system.Authenticated', ['edit'])] self.assertEquals( root.__acl__, [('Allow', 'system.Authenticated', ['edit'])]) root.__acl__ = [ ('Allow', 'system.Authenticated', ['view']), ('Deny', 'system.Authenticated', ALL_PERMISSIONS), ] self.assertEquals( root.__acl__, [ ('Allow', 'system.Authenticated', ['view']), ('Deny', 'system.Authenticated', ALL_PERMISSIONS), ]) # We can append to the ACL, and it'll be persisted fine: root.__acl__.append(('Allow', 'system.Authenticated', ['edit'])) self.assertEquals( root.__acl__, [ ('Allow', 'system.Authenticated', ['view']), ('Deny', 'system.Authenticated', ALL_PERMISSIONS), ('Allow', 'system.Authenticated', ['edit']), ]) DBSession.flush() DBSession.expire_all() self.assertEquals( root.__acl__, [ ('Allow', 'role:admin', ALL_PERMISSIONS), ('Allow', 'system.Authenticated', ['view']), ('Deny', 'system.Authenticated', ALL_PERMISSIONS), ('Allow', 'system.Authenticated', ['edit']), ])
def test_copy_content_copy_tags(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Tag, TagsToContents, Content ses = DBSession root = get_root() root[u'content_1'] = Content() root[u'content_1'].tags = [u'my tag'] assert ses.query(Tag).count() == 1 assert ses.query(TagsToContents).count() == 1 root[u'content_2'] = root[u'content_1'].copy() DBSession.flush() assert root[u'content_1'].tags == [u'my tag'] assert root[u'content_2'].tags == [u'my tag'] assert ses.query(Tag).count() == 1 assert ses.query(TagsToContents).count() == 2
def test_set_and_get_acl(self): from kotti import DBSession from kotti.resources import get_root root = get_root() # The __acl__ attribute of Nodes allows access to the mapped # '_acl' property: del root.__acl__ self.assertRaises(AttributeError, root._get_acl) root.__acl__ = [['Allow', 'system.Authenticated', ['edit']]] self.assertEquals(root.__acl__, [ ('Allow', 'role:admin', ALL_PERMISSIONS), ('Allow', 'system.Authenticated', ['edit']), ]) root.__acl__ = [ ('Allow', 'system.Authenticated', ['view']), ('Deny', 'system.Authenticated', ALL_PERMISSIONS), ] self.assertEquals(root.__acl__, [ ('Allow', 'role:admin', ALL_PERMISSIONS), ('Allow', 'system.Authenticated', ['view']), ('Deny', 'system.Authenticated', ALL_PERMISSIONS), ]) # We can reorder the ACL: first, second = root.__acl__[1:] root.__acl__ = [second, first] self.assertEquals(root.__acl__, [ ('Allow', 'role:admin', ALL_PERMISSIONS), ('Deny', 'system.Authenticated', ALL_PERMISSIONS), ('Allow', 'system.Authenticated', ['view']), ]) DBSession.flush() DBSession.expire_all() self.assertEquals(root.__acl__[1:], [second, first]) root._del_acl() self.assertRaises(AttributeError, root._del_acl)
def test_append_to_empty_acl(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node root = get_root() node = root['child'] = Node() node.__acl__ = [] DBSession.flush() DBSession.expire_all() node.__acl__.append(('Allow', 'system.Authenticated', ['edit'])) DBSession.flush() DBSession.expire_all() assert node.__acl__ == [ ('Allow', 'role:admin', ALL_PERMISSIONS), ('Allow', 'system.Authenticated', ['edit']), ]
def test_local_roles_db_cascade(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import LocalGroup from kotti.resources import Node from kotti.security import set_groups root = get_root() child = root[u'child'] = Node() DBSession.flush() # We set a local group on child and delete child. We then # expect the LocalGroup entry to have been deleted from the # database: self.assertEqual(DBSession.query(LocalGroup).count(), 0) set_groups('group:bobsgroup', child, ['role:editor']) self.assertEqual(DBSession.query(LocalGroup).count(), 1) del root[u'child'] DBSession.flush() self.assertEqual(DBSession.query(LocalGroup).count(), 0)
def test_groups_from_users(self, db_session): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node from kotti.security import list_groups from kotti.security import set_groups self.make_bob() root = get_root() child = root[u'child'] = Node() DBSession.flush() assert list_groups('bob', root) == ['group:bobsgroup'] set_groups('group:bobsgroup', root, ['role:editor']) set_groups('role:editor', child, ['group:foogroup']) assert (set(list_groups('bob', root)) == set( ['group:bobsgroup', 'role:editor'])) assert (set(list_groups('bob', child)) == set( ['group:bobsgroup', 'role:editor', 'group:foogroup']))
def populate(): """ Create the root node (:class:`~kotti.resources.Document`) and the 'about' subnode in the nodes tree if there are no nodes yet. """ lrm = LocalizerRequestMixin() lrm.registry = get_current_registry() lrm.locale_name = get_settings()['pyramid.default_locale_name'] localizer = lrm.localizer if DBSession.query(Node.id).count() == 0: localized_root_attrs = dict([(k, localizer.translate(v)) for k, v in _ROOT_ATTRS.iteritems()]) root = Document(**localized_root_attrs) root.__acl__ = SITE_ACL DBSession.add(root) localized_about_attrs = dict([(k, localizer.translate(v)) for k, v in _ABOUT_ATTRS.iteritems()]) root['about'] = Document(**localized_about_attrs) DBSession.flush() populate_users()
def test_owner(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Content from kotti.security import list_groups from kotti.security import list_groups_raw from kotti.util import clear_cache session = DBSession() self.config.testing_securitypolicy(userid='bob') root = get_root() child = root[u'child'] = Content() session.flush() self.assertEqual(child.owner, u'bob') self.assertEqual(list_groups(u'bob', child), [u'role:owner']) clear_cache() # The event listener does not set the role again for subitems: grandchild = child[u'grandchild'] = Content() session.flush() self.assertEqual(grandchild.owner, u'bob') self.assertEqual(list_groups(u'bob', grandchild), [u'role:owner']) self.assertEqual(len(list_groups_raw(u'bob', grandchild)), 0)
def test_inherit(self, db_session): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node from kotti.security import list_groups from kotti.security import list_groups_raw from kotti.security import set_groups root = get_root() child = root[u'child'] = Node() DBSession.flush() assert list_groups('bob', child) == [] set_groups('bob', root, ['role:editor']) assert list_groups('bob', child) == ['role:editor'] # Groups from the child are added: set_groups('bob', child, ['group:somegroup']) assert (set(list_groups('bob', child)) == set( ['group:somegroup', 'role:editor'])) # We can ask to list only those groups that are defined locally: assert list_groups_raw(u'bob', child) == set(['group:somegroup'])
def test_owner(self, db_session, events, dummy_request): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Content from kotti.security import list_groups from kotti.security import list_groups_raw from kotti.util import clear_cache root = get_root() with patch('kotti.events.authenticated_userid', return_value='bob'): child = root[u'child'] = Content() DBSession.flush() assert child.owner == u'bob' assert list_groups(u'bob', child) == [u'role:owner'] clear_cache() # The event listener does not set the role again for subitems: with patch('kotti.events.authenticated_userid', return_value='bob'): grandchild = child[u'grandchild'] = Content() DBSession.flush() assert grandchild.owner == u'bob' assert list_groups(u'bob', grandchild) == [u'role:owner'] assert len(list_groups_raw(u'bob', grandchild)) == 0
def test_owner(self, get_current_request, authenticated_userid): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Content from kotti.security import list_groups from kotti.security import list_groups_raw from kotti.util import clear_cache get_current_request.return_value = not None authenticated_userid.return_value = 'bob' root = get_root() child = root[u'child'] = Content() DBSession.flush() self.assertEqual(child.owner, u'bob') self.assertEqual(list_groups(u'bob', child), [u'role:owner']) clear_cache() # The event listener does not set the role again for subitems: grandchild = child[u'grandchild'] = Content() DBSession.flush() self.assertEqual(grandchild.owner, u'bob') self.assertEqual(list_groups(u'bob', grandchild), [u'role:owner']) self.assertEqual(len(list_groups_raw(u'bob', grandchild)), 0)
def add_some_groups(): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node from kotti.security import set_groups root = get_root() child = root[u'child'] = Node() grandchild = child[u'grandchild'] = Node() DBSession.flush() # root: # bob -> group:bobsgroup # frank -> group:franksgroup # group:franksgroup -> role:editor # child: # group:bobsgroup -> group:franksgroup # grandchild: # group:franksgroup -> role:admin # group:franksgroup -> group:bobsgroup # bob and frank are a site-wide members of their respective groups: set_groups('bob', root, ['group:bobsgroup']) set_groups('frank', root, ['group:franksgroup']) # franksgroup has a site-wide editor role: set_groups('group:franksgroup', root, ['role:editor']) # bobsgroup is part of franksgroup on the child level: set_groups('group:bobsgroup', child, ['group:franksgroup']) # franksgroup has the admin role on the grandchild. # and finally, to test recursion, we make franksgroup part of # bobsgroup on the grandchild level: set_groups('group:franksgroup', grandchild, ['role:owner', 'group:bobsgroup'])
def test_sqlalchemy_events(self, db_session, events): from kotti import events from kotti import DBSession from kotti.resources import get_root from kotti.resources import Content insert_events = [] def insert(event): insert_events.append(event) update_events = [] def update(event): update_events.append(event) delete_events = [] def delete(event): delete_events.append(event) after_delete_events = [] def after_delete(event): after_delete_events.append(event) def lengths(): return (len(insert_events), len(update_events), len(delete_events), len(after_delete_events)) lis = events.objectevent_listeners lis[(events.ObjectInsert, None)].append(insert) lis[(events.ObjectUpdate, None)].append(update) lis[(events.ObjectDelete, None)].append(delete) lis[(events.ObjectAfterDelete, None)].append(after_delete) root = get_root() child = root[u'child'] = Content() DBSession.flush() assert lengths() == (1, 0, 0, 0) assert insert_events[0].object == child child.title = u"Bar" DBSession.flush() assert lengths() == (1, 1, 0, 0) assert update_events[0].object == child DBSession.delete(child) DBSession.flush() assert lengths() == (1, 1, 1, 1) assert delete_events[0].object == child assert after_delete_events[0].object == child
def test_sqlalchemy_events(self): from kotti import events from kotti import DBSession from kotti.resources import get_root from kotti.resources import Content insert_events = [] def insert(event): insert_events.append(event) update_events = [] def update(event): update_events.append(event) delete_events = [] def delete(event): delete_events.append(event) lis = events.objectevent_listeners lis[(events.ObjectInsert, None)].append(insert) lis[(events.ObjectUpdate, None)].append(update) lis[(events.ObjectDelete, None)].append(delete) root = get_root() child = root[u'child'] = Content() DBSession.flush() self.assertEqual( (len(insert_events), len(update_events), len(delete_events)), (1, 0, 0)) self.assertEqual(insert_events[0].object, child) child.title = u"Bar" DBSession.flush() self.assertEqual( (len(insert_events), len(update_events), len(delete_events)), (1, 1, 0)) self.assertEqual(update_events[0].object, child) DBSession.delete(child) DBSession.flush() self.assertEqual( (len(insert_events), len(update_events), len(delete_events)), (1, 1, 1)) self.assertEqual(delete_events[0].object, child)
def expire(event): DBSession.flush() DBSession.expire_all()
def test_works_with_auth(self): from kotti import DBSession from kotti.resources import get_root from kotti.resources import Node from kotti.security import get_principals from kotti.security import list_groups_callback from kotti.security import set_groups root = get_root() child = root[u'child'] = Node() DBSession.flush() request = DummyRequest() auth = CallbackAuthenticationPolicy() auth.unauthenticated_userid = lambda *args: 'bob' auth.callback = list_groups_callback request.context = root self.assertEqual( # user doesn't exist yet auth.effective_principals(request), ['system.Everyone']) get_principals()[u'bob'] = dict(name=u'bob') self.assertEqual(auth.effective_principals(request), ['system.Everyone', 'system.Authenticated', 'bob']) # Define that bob belongs to bobsgroup on the root level: set_groups('bob', root, ['group:bobsgroup']) request.context = child self.assertEqual( set(auth.effective_principals(request)), set([ 'system.Everyone', 'system.Authenticated', 'bob', 'group:bobsgroup' ])) # define that bob belongs to franksgroup in the user db: get_principals()[u'bob'].groups = [u'group:franksgroup'] set_groups('group:franksgroup', child, ['group:anothergroup']) self.assertEqual( set(auth.effective_principals(request)), set([ 'system.Everyone', 'system.Authenticated', 'bob', 'group:bobsgroup', 'group:franksgroup', 'group:anothergroup', ])) # And lastly test that circular group defintions are not a # problem here either: get_principals()[u'group:franksgroup'] = dict( name=u'group:franksgroup', title=u"Frank's group", groups=[u'group:funnygroup', u'group:bobsgroup'], ) self.assertEqual( set(auth.effective_principals(request)), set([ 'system.Everyone', 'system.Authenticated', 'bob', 'group:bobsgroup', 'group:franksgroup', 'group:anothergroup', 'group:funnygroup', ]))