app/soc/views/models/user.py
changeset 590 37735d97b541
parent 587 7504504209a3
child 605 4a384d412640
equal deleted inserted replaced
589:ee9122db04af 590:37735d97b541
    12 # distributed under the License is distributed on an "AS IS" BASIS,
    12 # distributed under the License is distributed on an "AS IS" BASIS,
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14 # See the License for the specific language governing permissions and
    14 # See the License for the specific language governing permissions and
    15 # limitations under the License.
    15 # limitations under the License.
    16 
    16 
    17 """Views for Host profiles.
    17 """Views for User profiles.
    18 """
    18 """
    19 
    19 
    20 __authors__ = [
    20 __authors__ = [
    21     '"Sverre Rabbelier" <sverre@rabbelier.nl>',
    21     '"Sverre Rabbelier" <sverre@rabbelier.nl>',
    22     '"Pawel Solyga" <pawel.solyga@gmail.com>',
    22     '"Pawel Solyga" <pawel.solyga@gmail.com>',
   108   """
   108   """
   109 
   109 
   110   key_name = forms.CharField(widget=forms.HiddenInput)
   110   key_name = forms.CharField(widget=forms.HiddenInput)
   111 
   111 
   112 
   112 
   113 class UserForm(helper.forms.BaseForm):
       
   114   """Django form displayed when creating or editing a User.
       
   115   """
       
   116   class Meta:
       
   117     """Inner Meta class that defines some behavior for the form.
       
   118     """
       
   119     #: db.Model subclass for which the form will gather information
       
   120     model = soc.models.user.User
       
   121 
       
   122     #: list of model fields which will *not* be gathered by the form
       
   123     exclude = ['account', 'former_accounts', 'is_developer']
       
   124 
       
   125   def clean_link_id(self):
       
   126     link_id = self.cleaned_data.get('link_id')
       
   127     if not validate.isLinkIdFormatValid(link_id):
       
   128       raise forms.ValidationError("This link ID is in wrong format.")
       
   129 
       
   130     user = soc.logic.models.user.logic.getForFields({'link_id': link_id},
       
   131                                           unique=True)
       
   132 
       
   133     # Get the currently logged in user account
       
   134     current_account = users.get_current_user()
       
   135 
       
   136     if user:
       
   137       if current_account != user.account:
       
   138         raise forms.ValidationError("This link ID is already in use.")
       
   139 
       
   140     return link_id
       
   141 
       
   142 
       
   143 class View(base.View):
   113 class View(base.View):
   144   """View methods for the User model.
   114   """View methods for the User model.
   145   """
   115   """
   146 
   116 
   147   DEF_USER_ACCOUNT_INVALID_MSG_FMT = ugettext_lazy(
       
   148     'The <b><i>%(email)s</i></b> account cannot be used with this site, for'
       
   149     ' one or more of the following reasons:'
       
   150     '<ul>'
       
   151     ' <li>the account is invalid</li>'
       
   152     ' <li>the account is already attached to a User profile and cannot be'
       
   153     ' used to create another one</li>'
       
   154     ' <li>the account is a former account that cannot be used again</li>'
       
   155     '</ul>')
       
   156 
   117 
   157   def __init__(self, original_params=None):
   118   def __init__(self, original_params=None):
   158     """Defines the fields and methods required for the base View class
   119     """Defines the fields and methods required for the base View class
   159     to provide the user with list, public, create, edit and delete views.
   120     to provide the user with list, public, create, edit and delete views.
   160 
   121 
   162       original_params: a dict with params for this View
   123       original_params: a dict with params for this View
   163     """
   124     """
   164 
   125 
   165     self._logic = soc.logic.models.user.logic
   126     self._logic = soc.logic.models.user.logic
   166 
   127 
   167     rights = {}
       
   168     rights['editSelf'] = [access.allow]
       
   169     rights['roles'] = [access.checkIsUser]
       
   170 
       
   171     params = {}
   128     params = {}
   172     params['rights'] = rights
       
   173 
   129 
   174     params['name'] = "User"
   130     params['name'] = "User"
   175     params['name_short'] = "User"
   131     params['name_short'] = "User"
   176     params['name_plural'] = "Users"
   132     params['name_plural'] = "Users"
   177     params['url_name'] = "user"
   133     params['url_name'] = "user"
   186 
   142 
   187     params = dicts.merge(original_params, params)
   143     params = dicts.merge(original_params, params)
   188 
   144 
   189     base.View.__init__(self, params=params)
   145     base.View.__init__(self, params=params)
   190 
   146 
   191   EDIT_SELF_TMPL = 'soc/user/edit_self.html'
       
   192 
   147 
   193   def editSelf(self, request, page_name=None, params=None, **kwargs):
       
   194     """Displays User self edit page for the entity specified by **kwargs.
       
   195 
       
   196     Args:
       
   197       request: the standard Django HTTP request object
       
   198       page_name: the page name displayed in templates as page and header title
       
   199       params: a dict with params for this View
       
   200       kwargs: The Key Fields for the specified entity
       
   201     """
       
   202 
       
   203     try:
       
   204       self.checkAccess('editSelf', request)
       
   205     except out_of_band.Error, error:
       
   206       return error.response(request, template=self.EDIT_SELF_TMPL)
       
   207 
       
   208     new_params = {}
       
   209     new_params['edit_template'] = self.EDIT_SELF_TMPL
       
   210 
       
   211     params = dicts.merge(params, new_params)
       
   212     params = dicts.merge(params, self._params)
       
   213 
       
   214     account = users.get_current_user()
       
   215     properties = {'account': account}
       
   216 
       
   217     user = soc.logic.models.user.logic.getForFields(properties, unique=True)
       
   218 
       
   219     # create default template context for use with any templates
       
   220     context = helper.responses.getUniversalContext(request)
       
   221 
       
   222     if request.method == 'POST':
       
   223       form = UserForm(request.POST)
       
   224 
       
   225       if form.is_valid():
       
   226         new_link_id = form.cleaned_data.get('link_id')
       
   227         properties = {
       
   228           'link_id': new_link_id,
       
   229           'name': form.cleaned_data.get("name"),
       
   230           'account': account,
       
   231         }
       
   232 
       
   233         # check if user account is not in former_accounts
       
   234         # if it is show error message that account is invalid
       
   235         if soc.logic.models.user.logic.isFormerAccount(account):
       
   236           msg = self.DEF_USER_ACCOUNT_INVALID_MSG_FMT % {
       
   237             'email': account.email()}
       
   238           error = out_of_band.Error(msg)
       
   239           return error.response(request, template=self.EDIT_SELF_TMPL,
       
   240                                 context=context)
       
   241 
       
   242         user = soc.logic.models.user.logic.updateOrCreateFromFields(
       
   243             properties, {'link_id': new_link_id})
       
   244 
       
   245         # redirect to /user/profile?s=0
       
   246         # (causes 'Profile saved' message to be displayed)
       
   247         return helper.responses.redirectToChangedSuffix(
       
   248             request, None, params=params['edit_params'])
       
   249     else: # request.method == 'GET'
       
   250       if user:
       
   251         # is 'Profile saved' parameter present, but referrer was not ourself?
       
   252         # (e.g. someone bookmarked the GET that followed the POST submit)
       
   253         if (request.GET.get(self.DEF_SUBMIT_MSG_PARAM_NAME)
       
   254             and (not helper.requests.isReferrerSelf(request))):
       
   255           # redirect to aggressively remove 'Profile saved' query parameter
       
   256           return http.HttpResponseRedirect(request.path)
       
   257 
       
   258         # referrer was us, so select which submit message to display
       
   259         # (may display no message if ?s=0 parameter is not present)
       
   260         context['notice'] = (
       
   261             helper.requests.getSingleIndexedParamValue(
       
   262                 request, self.DEF_SUBMIT_MSG_PARAM_NAME,
       
   263                 values=params['save_message']))
       
   264 
       
   265         # populate form with the existing User entity
       
   266         form = UserForm(instance=user)
       
   267       else:
       
   268         if request.GET.get(self.DEF_SUBMIT_MSG_PARAM_NAME):
       
   269           # redirect to aggressively remove 'Profile saved' query parameter
       
   270           return http.HttpResponseRedirect(request.path)
       
   271 
       
   272         # no User entity exists for this Google Account, so show a blank form
       
   273         form = UserForm()
       
   274 
       
   275     context['form'] = form
       
   276 
       
   277     template = params['edit_template']
       
   278 
       
   279     return helper.responses.respond(request, template, context)
       
   280   
       
   281   def _editGet(self, request, entity, form):
   148   def _editGet(self, request, entity, form):
   282     """See base.View._editGet().
   149     """See base.View._editGet().
   283     """
   150     """
   284     # fill in the email field with the data from the entity
   151     # fill in the email field with the data from the entity
   285     form.fields['email'].initial = entity.account.email()
   152     form.fields['email'].initial = entity.account.email()
   288     """See base.View._editPost().
   155     """See base.View._editPost().
   289     """
   156     """
   290     # fill in the account field with the user created from email
   157     # fill in the account field with the user created from email
   291     fields['account'] = users.User(fields['email'])
   158     fields['account'] = users.User(fields['email'])
   292 
   159 
   293   def getUserSidebar(self, request):
       
   294     """Returns an dictionary with the user sidebar entry.
       
   295     """
       
   296 
       
   297     params = {}
       
   298     params['sidebar_heading'] = "User (self)"
       
   299     params['sidebar'] = [
       
   300         ('/' + self._params['url_name'] + '/edit', 'Profile', 'editSelf'),
       
   301         ('/' + self._params['url_name'] + '/roles', 'Roles', 'roles'),
       
   302         ]
       
   303     return self.getSidebarLinks(request, params)
       
   304 
       
   305   def getDjangoURLPatterns(self):
       
   306     """See base.View.getDjangoURLPatterns().
       
   307     """
       
   308 
       
   309     patterns = super(View, self).getDjangoURLPatterns()
       
   310     patterns += [(r'^' + self._params['url_name'] + '/edit$',
       
   311                    'soc.views.models.user.edit_self')]
       
   312 
       
   313     page_name = "Requests Overview"
       
   314     patterns += [(r'^' + self._params['url_name'] + '/roles$',
       
   315                    'soc.views.models.request.list_self',
       
   316                    {'page_name': page_name}, page_name)]
       
   317 
       
   318     return patterns
       
   319 
       
   320 
   160 
   321 view = View()
   161 view = View()
   322 
   162 
   323 create = view.create
   163 create = view.create
   324 delete = view.delete
   164 delete = view.delete
   325 edit = view.edit
   165 edit = view.edit
   326 list = view.list
   166 list = view.list
   327 public = view.public
   167 public = view.public
   328 edit_self = view.editSelf