source: main/trunk/openPLM/plmapp/controllers/user.py @ 375

Revision 375, 10.2 KB checked in by pcosquer, 8 years ago (diff)

When a new object is created, sets the sponsor as the signer if
the sponsor is not the company

Line 
1############################################################################
2# openPLM - open source PLM
3# Copyright 2010 Philippe Joulaud, Pierre Cosquer
4#
5# This file is part of openPLM.
6#
7#    openPLM is free software: you can redistribute it and/or modify
8#    it under the terms of the GNU General Public License as published by
9#    the Free Software Foundation, either version 3 of the License, or
10#    (at your option) any later version.
11#
12#    openPLM is distributed in the hope that it will be useful,
13#    but WITHOUT ANY WARRANTY; without even the implied warranty of
14#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15#    GNU General Public License for more details.
16#
17#    You should have received a copy of the GNU General Public License
18#    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
19#
20# Contact :
21#    Philippe Joulaud : ninoo.fr@gmail.com
22#    Pierre Cosquer : pierre.cosquer@insa-rennes.fr
23################################################################################
24
25"""
26This module contains a class called :class:`UserController` which
27provides a controller for :class:`~django.contrib.auth.models.User`.
28This class is similar to :class:`.PLMObjectController` but some methods
29from :class:`.PLMObjectController` are not defined.
30"""
31
32from django.conf import settings
33from django.db.models.fields import FieldDoesNotExist
34from django.utils.translation import ugettext_lazy as _
35from django.contrib.sites.models import Site
36
37import openPLM.plmapp.models as models
38from openPLM.plmapp.mail import send_mail
39from openPLM.plmapp.utils import generate_password
40from openPLM.plmapp.exceptions import PermissionError
41from openPLM.plmapp.controllers.base import Controller, permission_required
42
43class UserController(Controller):
44    u"""
45    Object used to manage a :class:`~django.contrib.auth.models.User` and store his
46    modification in an history
47   
48    :attributes:
49        .. attribute:: object
50
51            The :class:`~django.contrib.auth.models.User` managed by the controller
52
53    :param obj: managed object
54    :type obj: an instance of :class:`~django.contrib.auth.models.User`
55    :param user: user who modify *obj*
56    :type user: :class:`~django.contrib.auth.models.User`
57
58    .. note::
59        This class does not inherit from :class:`.PLMObjectController`.
60
61    """
62
63    HISTORY = models.UserHistory
64
65    def __init__(self, obj, user):
66        super(UserController, self).__init__(obj, user)
67        self.creator = obj
68        self.owner = obj
69        self.mtime = obj.last_login
70        self.ctime = obj.date_joined
71
72    def get_verbose_name(self, attr_name):
73        """
74        Returns a verbose name for *attr_name*.
75
76        Example::
77
78            >>> ctrl.get_verbose_name("ctime")
79            u'date of creation'
80        """
81
82        try:
83            item = unicode(self.object._meta.get_field(attr_name).verbose_name)
84        except FieldDoesNotExist:
85            names = {"mtime" : _("date of last modification"),
86                     "ctime" : _("date of creation"),
87                     "rank" : _("role in PLM"),
88                     "creator" : _("creator"),
89                     "owner" : _("owner")}
90            item = names.get(attr_name, attr_name)
91        return item
92
93    @permission_required(role=models.ROLE_OWNER)
94    def update_from_form(self, form):
95        u"""
96        Updates :attr:`object` from data of *form*
97       
98        This method raises :exc:`ValueError` if *form* is invalid.
99        """
100        if form.is_valid():
101            need_save = False
102            for key, value in form.cleaned_data.iteritems():
103                if key not in ["username"]:
104                    setattr(self, key, value)
105                    need_save = True
106            if need_save:
107                self.save()
108        else:
109            raise ValueError("form is invalid")
110
111    def __setattr__(self, attr, value):
112        # we override this method to make it to modify *object* directly
113        # (or its profile)
114        # if we modify *object*, we records the modification in **_histo*
115        if hasattr(self, "object"):
116            obj = object.__getattribute__(self, "object")
117            profile = obj.get_profile()
118        else:
119            obj = None
120        if obj and (hasattr(obj, attr) or hasattr(profile, attr)) and \
121           not attr in self.__dict__:
122            obj2 = obj if hasattr(obj, attr) else profile
123            old_value = getattr(obj2, attr)
124            setattr(obj2, attr, value)
125            # since x.verbose_name is a proxy methods, we need to get a real
126            # unicode object (with capitalize)
127            field = obj2._meta.get_field(attr).verbose_name.capitalize()
128            if old_value != value:
129                message = "%(field)s : changes from '%(old)s' to '%(new)s'" % \
130                        {"field" : field, "old" : old_value, "new" : value}
131                self._histo += message + "\n"
132        else:
133            super(UserController, self).__setattr__(attr, value)
134
135    def __getattr__(self, attr):
136        # we override this method to get attributes from *object* directly
137        # (or its profile)
138        obj = object.__getattribute__(self, "object")
139        profile = obj.get_profile()
140        if hasattr(self, "object") and hasattr(obj, attr) and \
141           not attr in self.__dict__:
142            return getattr(obj, attr)
143        elif hasattr(profile, attr) and not attr in self.__dict__:
144            return getattr(profile, attr)
145        else:
146            return object.__getattribute__(self, attr)
147
148    def save(self, with_history=True):
149        u"""
150        Saves :attr:`object` and records its history in the database.
151        If *with_history* is False, the history is not recorded.
152        """
153        self.object.get_profile().save()
154        super(UserController, self).save(with_history)
155
156    def has_permission(self, role):
157        if role == models.ROLE_OWNER:
158            return self.object == self._user
159        return False
160
161    def get_object_user_links(self):
162        """
163        Returns all :class:`.Part` attached to :attr:`object`.
164        """
165        return self.plmobjectuserlink_user.order_by("plmobject")
166
167    @permission_required(role=models.ROLE_OWNER)
168    def delegate(self, user, role):
169        """
170        Delegates role *role* to *user*.
171       
172        Possible values for *role* are:
173            ``'notified``
174                valid for all users
175            ``'owner'``
176                valid only for contributors and administrators
177            :samp:``'sign_{x}_level'``
178                valid only for contributors and administrators
179            ``'sign*'``
180                valid only for contributors and administrators, means all sign
181                roles that :attr:`object` has.
182       
183        :raise: :exc:`.PermissionError` if *user* can not have the role *role*
184        :raise: :exc:`ValueError` if *user* is :attr:`object`
185        """
186        if user == self.object:
187            raise ValueError("Bad delegatee (self)")
188        if user.get_profile().is_viewer and role != 'notified':
189            raise PermissionError("%s can not have role %s" % (user, role))
190        if self.object.get_profile().is_viewer and role != 'notified':
191            raise PermissionError("%s can not have role %s" % (self.object, role))
192        if role == "sign*":
193            qset = models.PLMObjectUserLink.objects.filter(user=self.object,
194                        role__startswith="sign_").only("role")
195            roles = set(link.role for link in qset)
196        else:
197            roles = [role]
198        for r in roles:
199            models.DelegationLink.objects.get_or_create(delegator=self.object,
200                        delegatee=user, role=r)
201        details = "%(delegator)s delegates the role %(role)s to %(delegatee)s"
202        details = details % dict(role=role, delegator=self.object,
203                                 delegatee=user)
204        self._save_histo(models.DelegationLink.ACTION_NAME, details)
205
206    @permission_required(role=models.ROLE_OWNER)
207    def remove_delegation(self, delegation_link):
208        """
209        Removes a delegation (*delegation_link*). The delegator must be
210        :attr:`object`, otherwise a :exc:`ValueError` is raised.
211        """
212        if delegation_link.delegator != self.object:
213            raise ValueError("%s is not the delegator of %s" % (self.object, ValueError))
214        details = "%(delegator)s removes his delegation for the role %(role)s to %(delegatee)s"
215        details = details % dict(role=delegation_link.role, delegator=self.object,
216                                 delegatee=delegation_link.delegatee)
217        self._save_histo(models.DelegationLink.ACTION_NAME, details)
218        delegation_link.delete()
219       
220    def get_user_delegation_links(self):
221        """
222        Returns all delegatees of :attr:`object`.
223        """
224        return self.delegationlink_delegator.order_by("role")
225
226    @permission_required(role=models.ROLE_OWNER)
227    def sponsor(self, new_user, is_contributor=True):
228        email = new_user.email
229        try:
230            # checks *email*
231            if settings.RESTRICT_EMAIL_TO_DOMAINS:
232                # i don't know if a domain can contains a '@'
233                domain = email.rsplit("@", 1)[1]
234                if domain not in Site.objects.values_list("domain", flat=True):
235                    raise PermissionError("Email's domain not valid")
236        except AttributeError:
237            # restriction disabled if the setting is not set
238            pass
239        password = generate_password()
240        new_user.set_password(password)
241        new_user.save()
242        new_user.get_profile().is_contributor = is_contributor
243        new_user.get_profile().save()
244        link = models.DelegationLink(delegator=self._user, delegatee=new_user,
245                role=models.ROLE_SPONSOR)
246        link.save()
247        ctx = {
248                "new_user" : new_user,
249                "sponsor" : self._user,
250                "password" : password,
251               }
252        send_mail("New account on openPLM", [new_user], ctx, "mails/new_account")
253        models.UserHistory.objects.create(action="Create", user=self._user,
254                plmobject=self._user, details="New user: %s" % new_user.username)
255        models.UserHistory.objects.create(action="Create", user=self._user,
256                plmobject=new_user, details="Account created")
257       
258       
259
260
Note: See TracBrowser for help on using the repository browser.