def test_remove_signer(self): controller = self.create("Part1") user = self.get_contributor() controller.add_signer(user, level_to_sign_str(0)) controller.remove_signer(self.user, level_to_sign_str(0)) controller.object.is_promotable = lambda: True self.assertRaises(exc.PermissionError, controller.approve_promotion)
def test_remove_signer_error_approved(self): controller = self.create("Part1") user = self.get_contributor() controller.add_signer(user, level_to_sign_str(0)) controller.object.is_promotable = lambda: True controller.approve_promotion() self.assertRaises(exc.PermissionError, controller.remove_signer, user, level_to_sign_str(0)) self.assertTrue(controller.users.now().filter(user=user).exists())
def test_set_sign1(self): controller = self.create("Part1") user = User(username="******") user.save() user.get_profile().is_contributor = True user.get_profile().save() controller.set_signer(user, level_to_sign_str(0)) link = models.PLMObjectUserLink.objects.get(role=level_to_sign_str(0), plmobject=controller.object) self.assertEqual(user, link.user)
def test_add_signer_error_approved(self): controller = self.create("Part1") user = self.get_contributor() controller.add_signer(user, level_to_sign_str(0)) controller.object.is_promotable = lambda: True controller.approve_promotion() user2 = self.get_contributor("toto") self.assertRaises(exc.PermissionError, controller.add_signer, user2, level_to_sign_str(0)) self.assertFalse(controller.users.filter(user=user2))
def test_set_role(self): controller = self.create("Part1") user = self.get_contributor() controller.set_role(user, "owner") self.assertEqual(controller.owner, user) controller.set_role(self.user, "notified") models.PLMObjectUserLink.current_objects.get(user=self.user, plmobject=controller.object, role="notified") controller.set_role(user, level_to_sign_str(0)) users = models.PLMObjectUserLink.current_objects.filter(role=level_to_sign_str(0), plmobject=controller.object).values_list("user", flat=True) self.assertTrue(user.id in users) self.assertTrue(self.user.id in users)
def test_approve_promotion_delegator_and_signer(self): controller = self.create("Part1") controller.object.is_promotable = lambda: True user = self.get_contributor("gege") UserController(self.user, self.user).delegate(user, level_to_sign_str(0)) models.PLMObjectUserLink.objects.create(user=user, plmobject=controller.object, role=level_to_sign_str(0)) ctrl2 = self.CONTROLLER(controller.object, user) self.assertTrue(ctrl2.is_last_promoter()) ctrl2.approve_promotion() obj = models.PLMObject.objects.get(id=controller.id) self.assertEqual(self.cie, obj.owner) self.assertEqual("official", obj.state.name)
def approve_promotion(self): if self.object.is_promotable(): lcl = self.lifecycle.to_states_list() role = level_to_sign_str(lcl.index(self.state.name)) self.check_permission(role) represented = self.get_represented_approvers() if not represented: raise PromotionError() next_state = lcl.next_state(self.state.name) nxt = models.State.objects.get(name=next_state) users = list(models.User.objects.filter(id__in=represented)) for user in users: self.approvals.create(user=user, current_state=self.object.state, next_state=nxt) if self._all_approved(): self.promote(checked=True) else: details = u"Represented users: %s" % u", ".join(u.username for u in users) details += u"promoted from state: %s to state:%s" % ( self.state.name, next_state) self._save_histo(u"promoted", details, roles=(role, )) else: raise PromotionError()
def promote(self, checked=False): u""" Promotes :attr:`object` in its lifecycle and writes its promotion in the history :raise: :exc:`.PromotionError` if :attr:`object` is not promotable :raise: :exc:`.PermissionError` if the use can not sign :attr:`object` :returns: a dictionary with two keys: new_state the new current :class:`.State` of the object updated_revisions a list of updated (deprecated or cancelled) revisions """ if checked or self.object.is_promotable(): state = self.object.state lifecycle = self.object.lifecycle lcl = lifecycle.to_states_list() if not checked: self.check_permission(level_to_sign_str(lcl.index(state.name))) new_state = lcl.next_state(state.name) self.object.state = models.State.objects.get_or_create(name=new_state)[0] self.object.save() details = "from state %(first)s to state %(second)s" % \ {"first" :state.name, "second" : new_state} self._save_histo("promoted", details, roles=["sign_"]) updated_revisions = [] if self.object.state == lifecycle.official_state: updated_revisions = self._officialize() self._update_state_history() self._clear_approvals() return {"new_state": self.object, "updated_revisions": updated_revisions} else: raise PromotionError()
def display_object_lifecycle(request, obj_type, obj_ref, obj_revi): """ Manage html page which displays lifecycle of the selected object. It computes a context dictionnary based on .. include:: views_params.txt """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if request.method == 'POST': if request.POST["action"] == "DEMOTE": obj.demote() elif request.POST["action"] == "PROMOTE": obj.promote() state = obj.state.name object_lifecycle = [] roles = dict(obj.plmobjectuserlink_plmobject.values_list("role", "user__username")) for i, st in enumerate(obj.lifecycle): signer = roles.get(level_to_sign_str(i)) object_lifecycle.append((st, st == state, signer)) is_signer = obj.check_permission(obj.get_current_sign_level(), False) is_signer_dm = obj.check_permission(obj.get_previous_sign_level(), False) ctx.update({'current_page':'lifecycle', 'object_lifecycle': object_lifecycle, 'is_signer' : is_signer, 'is_signer_dm' : is_signer_dm}) return r2r('DisplayObjectLifecycle.htm', ctx, request)
def promote(self): u""" Promotes :attr:`object` in his lifecycle and writes his promotion in the history :raise: :exc:`.PromotionError` if :attr:`object` is not promotable :raise: :exc:`.PermissionError` if the use can not sign :attr:`object` """ if self.object.is_promotable(): state = self.object.state lifecycle = self.object.lifecycle lcl = lifecycle.to_states_list() self.check_permission(level_to_sign_str(lcl.index(state.name))) try: new_state = lcl.next_state(state.name) self.object.state = models.State.objects.get_or_create(name=new_state)[0] self.object.save() details = "change state from %(first)s to %(second)s" % \ {"first" :state.name, "second" : new_state} self._save_histo("Promote", details, roles=["sign_"]) if self.object.state == lifecycle.official_state: cie = models.User.objects.get(username=settings.COMPANY) self.set_owner(cie) except IndexError: # FIXME raises it ? pass else: raise PromotionError()
def test_set_sign_error2(self): """Test sign error : user is not a contributor""" controller = self.create("Part1") user = User(username="******") user.save() self.assertRaises(exc.PermissionError, controller.set_role, user, level_to_sign_str(0))
def test_is_readable_not_editable(self): """ Tests that an official or deprecated object is readable by every body. """ controller = self.create("P1") controller.object.lifecycle = models.Lifecycle.objects.get(name="draft_proposed_official_deprecated") controller.object.save() controller.add_signer(self.user, level_to_sign_str(2)) controller.object.is_promotable = lambda: True robert = models.User.objects.create_user("Robert", "pwd", "*****@*****.**") robert.groups.add(self.group) ned = models.User.objects.create_user("Ned", "pwd", "*****@*****.**") for i in range(2): ctrl = self.CONTROLLER(controller.object, ned) self.assertRaises(exc.PermissionError, ctrl.check_readable) for user in (self.user, self.cie, robert): ctrl = self.CONTROLLER(controller.object, user) ctrl.check_readable() controller.promote() for i in range(2): # i = 0 -> official, i = 1 -> deprecated for user in (self.user, self.cie, robert, ned): ctrl = self.CONTROLLER(controller.object, user) ctrl.check_readable() if i == 0: controller.promote()
def demote(self): u""" Demotes :attr:`object` in irs lifecycle and writes irs demotion in the history :raise: :exc:`.PermissionError` if the use can not sign :attr:`object` """ if not self.is_proposed: raise PromotionError() state = self.object.state lifecycle = self.object.lifecycle lcl = lifecycle.to_states_list() try: new_state = lcl.previous_state(state.name) self.check_permission(level_to_sign_str(lcl.index(new_state))) self.object.state = models.State.objects.get_or_create( name=new_state)[0] self.object.save() self._clear_approvals() details = "from state %(first)s to state %(second)s" % \ {"first" :state.name, "second" : new_state} self._save_histo("demoted", details, roles=["sign_"]) self._update_state_history() except IndexError: # FIXME raises it ? pass
def test_delegate_sign_post(self): data = {"type": "User", "username": self.brian.username} for level in xrange(1, 4): url = self.user_url + "delegation/delegate/sign/%d/" % level response = self.post(url, data) role = level_to_sign_str(level - 1) m.DelegationLink.objects.get(role=role, delegator=self.user, delegatee=self.brian)
def demote(self): u""" Demotes :attr:`object` in irs lifecycle and writes irs demotion in the history :raise: :exc:`.PermissionError` if the use can not sign :attr:`object` """ if not self.is_proposed: raise PromotionError() state = self.object.state lifecycle = self.object.lifecycle lcl = lifecycle.to_states_list() try: new_state = lcl.previous_state(state.name) self.check_permission(level_to_sign_str(lcl.index(new_state))) self.object.state = models.State.objects.get_or_create(name=new_state)[0] self.object.save() self._clear_approvals() details = "change state from %(first)s to %(second)s" % \ {"first" :state.name, "second" : new_state} self._save_histo("Demote", details, roles=["sign_"]) #self._update_state_history() except IndexError: # FIXME raises it ? pass
def promote(self, checked=False): u""" Promotes :attr:`object` in its lifecycle and writes its promotion in the history :raise: :exc:`.PromotionError` if :attr:`object` is not promotable :raise: :exc:`.PermissionError` if the use can not sign :attr:`object` """ if checked or self.object.is_promotable(): state = self.object.state lifecycle = self.object.lifecycle lcl = lifecycle.to_states_list() if not checked: self.check_permission(level_to_sign_str(lcl.index(state.name))) try: new_state = lcl.next_state(state.name) self.object.state = models.State.objects.get_or_create(name=new_state)[0] self.object.save() details = "change state from %(first)s to %(second)s" % \ {"first" :state.name, "second" : new_state} self._save_histo("Promote", details, roles=["sign_"]) if self.object.state == lifecycle.official_state: self._officialize() #self._update_state_history() self._clear_approvals() except IndexError: # FIXME raises it ? pass else: raise PromotionError()
def test_add_sign_error1(self): """Test sign error : bad level""" controller = self.create("Part1") user = self.get_contributor() for i in (2, 3, 1664): self.assertRaises(ValueError, controller.add_signer, user, level_to_sign_str(i))
def test_delegate_sign_all_post(self): # sign all level data = {"type": "User", "username": self.brian.username} url = self.user_url + "delegation/delegate/sign/all/" response = self.post(url, data) for level in xrange(2): role = level_to_sign_str(level) m.DelegationLink.objects.get(role=role, delegator=self.user, delegatee=self.brian)
def test_management_replace_get(self): role = level_to_sign_str(0) self.controller.set_signer(self.brian, role) link = m.PLMObjectUserLink.objects.get(plmobject=self.controller.object, user=self.brian, role=role) response = self.get(self.base_url + "management/replace/%d/" % link.id, link=True, page="management") attach = response.context["attach"] self.assertEqual(self.controller.id, attach[0].id) self.assertEqual("delegate", attach[1])
def get_current_sign_level(self): """ Returns the current sign level that a user must have to promote this object. """ rank = LifecycleStates.objects.get(state=self.state, lifecycle=self.lifecycle).rank return level_to_sign_str(rank)
def get_previous_sign_level(self): """ Returns the current sign level that a user must have to demote this object. """ rank = pmodels.LifecycleStates.objects.get( state=self.state, lifecycle=self.lifecycle).rank return level_to_sign_str(rank - 1)
def test_delegate_sign_post(self): data = { "type" : "User", "username": self.brian.username } for level in xrange(1, 4): url = self.user_url + "delegation/delegate/sign/%d/" % level response = self.post(url, data) role = level_to_sign_str(level - 1) m.DelegationLink.objects.get(role=role, delegator=self.user, delegatee=self.brian)
def get_previous_sign_level(self): """ Returns the current sign level that a user must have to demote this object. """ rank = pmodels.LifecycleStates.objects.get(state=self.state, lifecycle=self.lifecycle).rank return level_to_sign_str(rank - 1)
def test_set_sign_error2(self): """Test sign error : user is not a contributor""" controller = self.create("Part1") user = User(username="******") user.save() user.groups.add(controller.group) self.assertRaises(exc.PermissionError, controller.set_role, user, level_to_sign_str(0))
def add_management(request, obj_type, obj_ref, obj_revi, reader=False, level=None): """ View to add a manager (notified user or restricted reader). :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/management/add/` or :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/management/add-reader/` .. include:: views_params.txt :param reader: True to add a restricted reader instead of a notified user **Template:** :file:`management_replace.html` **Context:** ``RequestContext`` ``replace_manager_form`` a form to select the new manager (a user) ``link_creation`` Set to True ``role`` role of the new user (:const:`.ROLE_NOTIFIED` or :const:`.ROLE_READER`) ``attach`` set to (*obj*, :samp:`"add_{role}"`) """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if level is None: role = models.ROLE_READER if reader else models.ROLE_NOTIFIED else: role = level_to_sign_str(int(level)) if request.method == "POST": add_management_form = forms.SelectUserForm(request.POST) if add_management_form.is_valid(): if add_management_form.cleaned_data["type"] == "User": user_obj = get_obj_from_form(add_management_form, request.user) obj.set_role(user_obj.object, role) message = _(u"Role %(add_role)s granted." % dict(add_role=role)) messages.info(request, message) return HttpResponseRedirect("../../lifecycle/") else: add_management_form = forms.SelectUserForm() ctx.update({'current_page':'lifecycle', 'replace_manager_form': add_management_form, 'link_creation': True, 'role' : role, "attach" : (obj, "add_" + role)}) return r2r('management_replace.html', ctx, request)
def test_set_sign_error1(self): """Test sign error : bad level""" controller = self.create("Part1") user = User(username="******") user.save() user.get_profile().is_contributor = True user.get_profile().save() self.assertRaises(exc.PermissionError, controller.set_role, user, level_to_sign_str(1664))
def test_delegate_sign_all_post(self): # sign all level data = { "type" : "User", "username": self.brian.username } url = self.user_url + "delegation/delegate/sign/all/" response = self.post(url, data) for level in xrange(2): role = level_to_sign_str(level) m.DelegationLink.objects.get(role=role, delegator=self.user, delegatee=self.brian)
def test_management_replace_post(self): role = level_to_sign_str(0) self.controller.set_signer(self.brian, role) link = m.PLMObjectUserLink.objects.get(plmobject=self.controller.object, user=self.brian, role=role) data = dict(type="User", username=self.user.username) response = self.post(self.base_url + "management/replace/%d/" % link.id, data) self.assertFalse( m.PLMObjectUserLink.objects.filter(plmobject=self.controller.object, user=self.brian, role=role) ) self.assertTrue(m.PLMObjectUserLink.objects.filter(plmobject=self.controller.object, user=self.user, role=role))
def test_replace_signer(self): controller = self.create("Part1") user = self.get_contributor() controller.replace_signer(self.user, user, level_to_sign_str(0)) controller.object.is_promotable = lambda: True self.assertEqual(list(controller.get_current_signers()), [user.id]) self.assertRaises(exc.PermissionError, controller.approve_promotion) ctrl2 = self.CONTROLLER(controller.object, user) ctrl2.approve_promotion() self.assertEqual("official", controller.object.state.name)
def test_management_replace_signer_get(self): role = level_to_sign_str(0) self.brian.groups.add(self.group) self.controller.replace_signer(self.user, self.brian, role) link = m.PLMObjectUserLink.current_objects.get(plmobject=self.controller.object, user=self.brian, role=role) response = self.get(self.base_url + "management/replace/%d/" % link.id, link=True, page="lifecycle") attach = response.context["attach"] self.assertEqual(self.controller.id, attach[0].id) self.assertEqual("add_" + role, attach[1])
def test_management_replace_signer_get(self): role = level_to_sign_str(0) self.brian.groups.add(self.group) self.controller.replace_signer(self.user, self.brian, role) link = m.PLMObjectUserLink.current_objects.get( plmobject=self.controller.object, user=self.brian, role=role) response = self.get(self.base_url + "management/replace/%d/" % link.id, link=True, page="lifecycle") attach = response.context["attach"] self.assertEqual(self.controller.id, attach[0].id) self.assertEqual("add_" + role, attach[1])
def test_represented_signer(self): brian = self.get_contributor() models.DelegationLink.objects.create(delegator=brian, delegatee=self.user, role=level_to_sign_str(0)) self.assertPromotion( ("P1", D, {}, [ ("P2", D, {"signers": [brian]}, [ ("P3", D, {}, [ ("P4", D, {}, []), ]), ]), ]), )
def delegate(request, obj_ref, role, sign_level): """ Manage html page for delegations modification of the selected :class:`~django.contrib.auth.models.User`. It computes a context dictionary based on :param request: :class:`django.http.QueryDict` :param obj_type: :class:`~django.contrib.auth.models.User` :type obj_ref: str :param role: :attr:`.DelegationLink.role` if role is not "sign" :type role: str :param sign_level: used for :attr:`.DelegationLink.role` if role is "sign" :type sign_level: str :return: a :class:`django.http.HttpResponse` """ obj, ctx = get_generic_data(request, "User", obj_ref) if request.method == "POST": delegation_form = forms.SelectUserForm(request.POST) if delegation_form.is_valid(): if delegation_form.cleaned_data["type"] == "User": user_obj = get_obj_from_form(delegation_form, request.user) if role == "notified" or role == "owner": obj.delegate(user_obj.object, role) return HttpResponseRedirect("../..") elif role == "sign": if sign_level == "all": obj.delegate(user_obj.object, "sign*") return HttpResponseRedirect("../../..") elif sign_level.isdigit(): obj.delegate(user_obj.object, level_to_sign_str(int(sign_level) - 1)) return HttpResponseRedirect("../../..") else: delegation_form = forms.SelectUserForm() if role == 'sign': if sign_level.isdigit(): role = _("signer level") + " " + str(sign_level) else: role = _("signer all levels") elif role == "notified": role = _("notified") ctx.update({ 'current_page': 'delegation', 'replace_manager_form': delegation_form, 'link_creation': True, 'attach': (obj, "delegate"), 'role': role }) return r2r('management_replace.html', ctx, request)
def test_represented_signer(self): brian = self.get_contributor() models.DelegationLink.objects.create(delegator=brian, delegatee=self.user, role=level_to_sign_str(0)) self.assertPromotion(("P1", D, {}, [ ("P2", D, { "signers": [brian] }, [ ("P3", D, {}, [ ("P4", D, {}, []), ]), ]), ]), )
def test_management_replace_signer_post(self): role = level_to_sign_str(0) self.brian.groups.add(self.group) self.controller.replace_signer(self.user, self.brian, role) link = m.PLMObjectUserLink.current_objects.get( plmobject=self.controller.object, user=self.brian, role=role) data = dict(type="User", username=self.user.username) response = self.post( self.base_url + "management/replace/%d/" % link.id, data) self.assertFalse( m.PLMObjectUserLink.current_objects.filter( plmobject=self.controller.object, user=self.brian, role=role)) self.assertTrue( m.PLMObjectUserLink.current_objects.filter( plmobject=self.controller.object, user=self.user, role=role))
def delegate(request, obj_ref, role, sign_level): """ Manage html page for delegations modification of the selected :class:`~django.contrib.auth.models.User`. It computes a context dictionary based on :param request: :class:`django.http.QueryDict` :param obj_type: :class:`~django.contrib.auth.models.User` :type obj_ref: str :param role: :attr:`.DelegationLink.role` if role is not "sign" :type role: str :param sign_level: used for :attr:`.DelegationLink.role` if role is "sign" :type sign_level: str :return: a :class:`django.http.HttpResponse` """ obj, ctx = get_generic_data(request, "User", obj_ref) if request.method == "POST": delegation_form = forms.SelectUserForm(request.POST) if delegation_form.is_valid(): if delegation_form.cleaned_data["type"] == "User": user_obj = get_obj_from_form(delegation_form, request.user) if role == "notified" or role == "owner": obj.delegate(user_obj.object, role) return HttpResponseRedirect("../..") elif role == "sign": if sign_level == "all": obj.delegate(user_obj.object, "sign*") return HttpResponseRedirect("../../..") elif sign_level.isdigit(): obj.delegate(user_obj.object, level_to_sign_str(int(sign_level)-1)) return HttpResponseRedirect("../../..") else: delegation_form = forms.SelectUserForm() if role == 'sign': if sign_level.isdigit(): role = _("signer level") + " " + str(sign_level) else: role = _("signer all levels") elif role == "notified": role = _("notified") ctx.update({'current_page':'delegation', 'replace_manager_form': delegation_form, 'link_creation': True, 'attach' : (obj, "delegate"), 'role': role}) return r2r('management_replace.html', ctx, request)
def approve_promotion(self): if self.object.is_promotable(): lcl = self.lifecycle.to_states_list() role = level_to_sign_str(lcl.index(self.state.name)) self.check_permission(role) represented = self.get_represented_approvers() if not represented: raise PromotionError() next_state = lcl.next_state(self.state.name) nxt = models.State.objects.get(name=next_state) users = list(models.User.objects.filter(id__in=represented)) for user in users: self.approvals.create(user=user, current_state=self.object.state, next_state=nxt) if self._all_approved(): self.promote(checked=True) else: details = u"Current state: %s, next state:%s\n" % (self.state.name, next_state) details += u"Represented users: %s" % u", ".join(u.username for u in users) self._save_histo(u"Approved promotion", details, roles=(role,)) else: raise PromotionError()
def promote(self, checked=False): u""" Promotes :attr:`object` in its lifecycle and writes its promotion in the history :raise: :exc:`.PromotionError` if :attr:`object` is not promotable :raise: :exc:`.PermissionError` if the use can not sign :attr:`object` :returns: a dictionary with two keys: new_state the new current :class:`.State` of the object updated_revisions a list of updated (deprecated or cancelled) revisions """ if checked or self.object.is_promotable(): state = self.object.state lifecycle = self.object.lifecycle lcl = lifecycle.to_states_list() if not checked: self.check_permission(level_to_sign_str(lcl.index(state.name))) new_state = lcl.next_state(state.name) self.object.state = models.State.objects.get_or_create( name=new_state)[0] self.object.save() details = "from state %(first)s to state %(second)s" % \ {"first" :state.name, "second" : new_state} self._save_histo("promoted", details, roles=["sign_"]) updated_revisions = [] if self.object.state == lifecycle.official_state: updated_revisions = self._officialize() self._update_state_history() self._clear_approvals() return { "new_state": self.object, "updated_revisions": updated_revisions } else: raise PromotionError()
def test_add_signer(self): controller = self.create("Part1") user = self.get_contributor() controller.add_signer(user, level_to_sign_str(0)) self.assertEqual(2, len(controller.get_current_signers()))
def test_management_add_signer1_post(self): self.do_test_management_add_post( self.base_url + "management/add-signer1/", level_to_sign_str(1))
def test_management_add_signer0_get(self): self.do_test_management_add_get( self.base_url + "management/add-signer0/", level_to_sign_str(0))
def test_add_signer_error_not_in_group(self): controller = self.create("Part1") user = self.get_contributor() user.groups.remove(self.group) self.assertRaises(exc.PermissionError, controller.set_role, user, level_to_sign_str(0))
def test_management_delete_signer1_post(self): self.do_test_management_delete_post( self.base_url + "management/delete/", level_to_sign_str(1))
def test_add_sign_error_already_signer(self): """Test sign error : bad level""" controller = self.create("Part1") user = self.get_contributor() self.assertRaises(IntegrityError, controller.add_signer, self.user, level_to_sign_str(0))
def test_remove_signer_error_one_signer(self): controller = self.create("Part1") self.assertRaises(exc.PermissionError, controller.remove_signer, self.user, level_to_sign_str(0)) self.assertTrue(controller.users.now().filter(user=self.user).exists())
def test_replace_sign_error1(self): """Test replace signer error : bad level""" controller = self.create("Part1") user = self.get_contributor() self.assertRaises(ValueError, controller.replace_signer, self.user, user, level_to_sign_str(1789))