def handle_put_user(self, req):
<EOL>account = req.path_info_pop()<EOL>user = req.path_info_pop()<EOL>key = unquote(req.headers.get('<STR_LIT>', '<STR_LIT>'))<EOL>key_hash = unquote(req.headers.get('<STR_LIT>', '<STR_LIT>'))<EOL>admin = req.headers.get('<STR_LIT>') == '<STR_LIT:true>'<EOL>reseller_admin =req.headers.get('<STR_LIT>') == '<STR_LIT:true>'<EOL>if reseller_admin:<EOL><INDENT>admin = True<EOL><DEDENT>if req.path_info or not account or account[<NUM_LIT:0>] == '<STR_LIT:.>' or not user oruser[<NUM_LIT:0>] == '<STR_LIT:.>' or (not key and not key_hash):<EOL><INDENT>return HTTPBadRequest(request=req)<EOL><DEDENT>if key_hash:<EOL><INDENT>try:<EOL><INDENT>swauth.authtypes.validate_creds(key_hash)<EOL><DEDENT>except ValueError:<EOL><INDENT>return HTTPBadRequest(request=req)<EOL><DEDENT><DEDENT>user_arg = account + '<STR_LIT::>' + user<EOL>if reseller_admin:<EOL><INDENT>if not self.is_super_admin(req) andnot self.is_user_changing_own_key(req, user_arg):<EOL><INDENT>return self.denied_response(req)<EOL><DEDENT><DEDENT>elif not self.is_account_admin(req, account) andnot self.is_user_changing_own_key(req, user_arg):<EOL><INDENT>return self.denied_response(req)<EOL><DEDENT>path = quote('<STR_LIT>' % (self.auth_account, account))<EOL>resp = self.make_pre_authed_request(<EOL>req.environ, '<STR_LIT>', path).get_response(self.app)<EOL>if resp.status_int // <NUM_LIT:100> != <NUM_LIT:2>:<EOL><INDENT>raise Exception('<STR_LIT>' %<EOL>(path, resp.status))<EOL><DEDENT>headers = {'<STR_LIT>':<EOL>resp.headers['<STR_LIT>']}<EOL>path = quote('<STR_LIT>' % (self.auth_account, account, user))<EOL>groups = ['<STR_LIT>' % (account, user), account]<EOL>if admin:<EOL><INDENT>groups.append('<STR_LIT>')<EOL><DEDENT>if reseller_admin:<EOL><INDENT>groups.append('<STR_LIT>')<EOL><DEDENT>auth_value = key_hash or self.auth_encoder().encode(key)<EOL>resp = self.make_pre_authed_request(<EOL>req.environ, '<STR_LIT>', path,<EOL>json.dumps({'<STR_LIT>': auth_value,<EOL>'<STR_LIT>': [{'<STR_LIT:name>': g} for g in groups]}),<EOL>headers=headers).get_response(self.app)<EOL>if resp.status_int == <NUM_LIT>:<EOL><INDENT>return HTTPNotFound(request=req)<EOL><DEDENT>if resp.status_int // <NUM_LIT:100> != <NUM_LIT:2>:<EOL><INDENT>raise Exception('<STR_LIT>' %<EOL>(path, resp.status))<EOL><DEDENT>return HTTPCreated(request=req)<EOL>
Handles the PUT v2/<account>/<user> call for adding a user to an
        account.

        X-Auth-User-Key represents the user's key (url encoded),
        - OR -
        X-Auth-User-Key-Hash represents the user's hashed key (url encoded),
        X-Auth-User-Admin may be set to `true` to create an account .admin, and
        X-Auth-User-Reseller-Admin may be set to `true` to create a
        .reseller_admin.

        Creating users
        **************
        Can only be called by an account .admin unless the user is to be a
        .reseller_admin, in which case the request must be by .super_admin.

        Changing password/key
        *********************
        1) reseller_admin key can be changed by super_admin and by himself.
        2) admin key can be changed by any admin in same account,
           reseller_admin, super_admin and himself.
        3) Regular user key can be changed by any admin in his account,
           reseller_admin, super_admin and himself.

        :param req: The swob.Request to process.
        :returns: swob.Response, 2xx on success.