def user_put(id, model):
    model.id = id
    if not model.username:
        response = jsonify({"message": "Username is required."})
        response.status_code = 400
        return response

    if not model.primary_group_id:
        response = jsonify({"message": "Primary group is required."})
        response.status_code = 400
        return response

    # check duplicate username
    if g.uow.users.user_exists_with_id(model.username, model.id):
        response = jsonify({"message": "The specified username is already taken."})
        response.status_code = 409
        return response

    if model.password:
        # password has changed
        salt = bcrypt.gensalt()
        model.password = bcrypt.hashpw(str(model.password), salt)

    # try to parse the expiration date
    if model.expiration_date:
        try:
            model.expiration_date = pytz.UTC.localize(
                datetime.fromtimestamp(mktime(strptime(model.expiration_date[:10], "%Y-%m-%d"))))
        except:
            response = jsonify({"message": "There was an error parsing the expiration date."})
            response.status_code = 500
            return response
    else:
        response = jsonify({"message": "The expiration date is required."})
        response.status_code = 400
        return response

    # update user
    current_user = session['current_user']
    g.uow.users.update_user(current_user['id'], model)

    roles = g.uow.users.get_users_roles(model.id)
    permission_list = map(lambda record: record['permissions'], roles)
    # flatten out permission_list by going through all sublists of permission_list and returning the item
    permissions = list(set([item for sublist in permission_list for item in sublist]))

    # check the users permissions against the PermissionCache
    if permissions != PermissionCache.get_permissions_for_user(model.id, g.uow):
        # rebuild permission cache for user
        PermissionCache.update_user_permission_cache(model.id, g.uow)
    return ""