示例#1
0
def itemDelete():
    """
    Deletes an item owned by the current user
    """
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    cat_name = bleach.clean(request.values.get("item_delete_parent"))
    cat = dal.get_category_by_name(cat_name)
    if not cat:
        return not_found_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()

    item_name = bleach.clean(request.values.get("item_delete_name"))
    item = dal.get_item_by_name(cat.cat_id, item_name)
    if not item:
        return not_found_error()

    if active_user.user_id != item.creator_id:
        return not_authorized_error()

    # All checks passed
    generate_nonce()
    dal.delete_item(item.item_id)
    return redirect("/")
示例#2
0
def itemDelete():
    """
    Deletes an item owned by the current user
    """
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    cat_name = bleach.clean(request.values.get("item_delete_parent"))
    cat = dal.get_category_by_name(cat_name)
    if not cat:
        return not_found_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()

    item_name = bleach.clean(request.values.get("item_delete_name"))
    item = dal.get_item_by_name(cat.cat_id, item_name)
    if not item:
        return not_found_error()

    if active_user.user_id != item.creator_id:
        return not_authorized_error()

    # All checks passed
    generate_nonce()
    dal.delete_item(item.item_id)
    return redirect("/")
示例#3
0
def itemUpdate():
    """
    Selectively update fields on an item owned by the logged-in user
    """
    # This will take a few steps. Start with loading the old object and performing
    # our usual auth process.
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    old_parent_name = bleach.clean(
        request.values.get("item_update_old_parent"))
    old_parent = dal.get_category_by_name(old_parent_name)
    if not old_parent:
        return not_found_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()

    old_item_name = bleach.clean(request.values.get("item_update_old_name"))
    old_item = dal.get_item_by_name(old_parent.cat_id, old_item_name)
    if not old_item:
        return not_found_error()

    # Item was found, security checks out.  Now pull in the new values from
    # the request.  If a field is empty, it's assumed that the user doesn't
    # want to change it.  Set to None so the DAL will skip those.
    new_item_name = bleach.clean(
        request.values.get("item_update_new_name")) or None
    desc = bleach.clean(request.values.get("item_update_description")) or None

    raw_pic_data = request.files["item_update_pic"] or None
    pic_data = None
    try:
        if raw_pic_data:
            pic_data = validate_picture(raw_pic_data)
    except InvalidPictureError:
        return bad_request_error()

    new_parent_name = bleach.clean(
        request.values.get("item_update_new_parent")) or None

    new_cat = dal.get_category_by_name(new_parent_name)
    new_cat_id = new_cat.cat_id if new_cat else None

    # New values look good.  All checks passed.
    generate_nonce()
    dal.update_item(old_item.item_id,
                    name=new_item_name,
                    description=desc,
                    pic_id=old_item.pic_id,
                    pic=pic_data,
                    cat_id=new_cat_id)
    redirect_cat = new_parent_name or old_parent_name
    redirect_item = new_item_name or old_item_name
    return redirect("/catalog/{}/{}/".format(redirect_cat, redirect_item))
示例#4
0
def itemUpdate():
    """
    Selectively update fields on an item owned by the logged-in user
    """
    # This will take a few steps. Start with loading the old object and performing
    # our usual auth process.
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    old_parent_name = bleach.clean(request.values.get("item_update_old_parent"))
    old_parent = dal.get_category_by_name(old_parent_name)
    if not old_parent:
        return not_found_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()

    old_item_name = bleach.clean(request.values.get("item_update_old_name"))
    old_item = dal.get_item_by_name(old_parent.cat_id, old_item_name)
    if not old_item:
        return not_found_error()

    # Item was found, security checks out.  Now pull in the new values from
    # the request.  If a field is empty, it's assumed that the user doesn't
    # want to change it.  Set to None so the DAL will skip those.
    new_item_name = bleach.clean(request.values.get("item_update_new_name")) or None
    desc = bleach.clean(request.values.get("item_update_description")) or None

    raw_pic_data = request.files["item_update_pic"] or None
    pic_data = None
    try:
        if raw_pic_data:
            pic_data = validate_picture(raw_pic_data)
    except InvalidPictureError:
        return bad_request_error()

    new_parent_name = bleach.clean(request.values.get("item_update_new_parent")) or None

    new_cat = dal.get_category_by_name(new_parent_name)
    new_cat_id = new_cat.cat_id if new_cat else None

    # New values look good.  All checks passed.
    generate_nonce()
    dal.update_item(old_item.item_id, name=new_item_name, description=desc,
        pic_id=old_item.pic_id, pic=pic_data, cat_id=new_cat_id)
    redirect_cat = new_parent_name or old_parent_name
    redirect_item = new_item_name or old_item_name
    return redirect("/catalog/{}/{}/".format(redirect_cat, redirect_item))
示例#5
0
def itemCreate():
    """
    Creates a new item owned by the logged-in user
    """
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    cat_name = bleach.clean(request.values.get("item_create_parent"))
    cat = dal.get_category_by_name(cat_name)
    if not cat:
        return not_found_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()

    item_name = bleach.clean(request.values.get("item_create_name"))
    duplicate = dal.get_item_by_name(cat.cat_id, item_name)
    if duplicate:
        return already_exists_error()

    try:
        pic_data = validate_picture(request.files["item_create_pic"])
    except InvalidPictureError:
        return bad_request_error()

    # All checks passed
    generate_nonce()
    desc = bleach.clean(request.values.get("item_create_description"))
    item_id = dal.create_item(item_name, cat.cat_id, active_user.user_id,
                              pic_data, desc)
    if not item_id:
        logging.error(
            "Unable to create item: did not receive an item_id from database")
        return internal_error()
    item = dal.get_item(item_id)
    if not item:
        logging.error(
            "Unable to create item: an instance was not created for item_id {}"
            .format(item_id))
        return internal_error()
    return redirect("/catalog/{}/{}/".format(cat_name, item_name))
示例#6
0
def itemCreate():
    """
    Creates a new item owned by the logged-in user
    """
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    cat_name = bleach.clean(request.values.get("item_create_parent"))
    cat = dal.get_category_by_name(cat_name)
    if not cat:
        return not_found_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()

    item_name = bleach.clean(request.values.get("item_create_name"))
    duplicate = dal.get_item_by_name(cat.cat_id, item_name)
    if duplicate:
        return already_exists_error()

    try:
        pic_data = validate_picture(request.files["item_create_pic"])
    except InvalidPictureError:
        return bad_request_error()

    # All checks passed
    generate_nonce()
    desc = bleach.clean(request.values.get("item_create_description"))
    item_id = dal.create_item(
        item_name, cat.cat_id, active_user.user_id, pic_data, desc)
    if not item_id:
        logging.error("Unable to create item: did not receive an item_id from database")
        return internal_error()
    item = dal.get_item(item_id)
    if not item:
        logging.error(
            "Unable to create item: an instance was not created for item_id {}".format(item_id))
        return internal_error()
    return redirect("/catalog/{}/{}/".format(cat_name, item_name))
示例#7
0
def categoryCreate():
    """
    Creates a new category owned by the logged-in user
    """
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()

    cat_name = bleach.clean(request.values.get("cat_create_name"))
    duplicate = dal.get_category_by_name(cat_name)
    if duplicate:
        return already_exists_error()

    # All checks passed
    generate_nonce()
    cat_id = dal.create_category(cat_name, active_user.user_id)
    return redirect("/")
示例#8
0
def categoryCreate():
    """
    Creates a new category owned by the logged-in user
    """
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()

    cat_name = bleach.clean(request.values.get("cat_create_name"))
    duplicate = dal.get_category_by_name(cat_name)
    if duplicate:
        return already_exists_error()

    # All checks passed
    generate_nonce()
    cat_id = dal.create_category(cat_name, active_user.user_id)
    return redirect("/")
示例#9
0
def categoryDelete():
    """
    Deletes a category owned by the logged-in user
    """
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    cat_name = bleach.clean(request.values.get("cat_delete_name"))
    cat = dal.get_category_by_name(cat_name)
    if not cat:
        return not_found_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()
    if active_user.user_id != cat.creator_id:
        return not_authorized_error()

    # All checks passed
    generate_nonce()
    dal.delete_category(cat.cat_id)
    return redirect("/")
示例#10
0
def categoryDelete():
    """
    Deletes a category owned by the logged-in user
    """
    state = request.values.get('state')
    if not check_nonce(state):
        return bad_request_error()

    cat_name = bleach.clean(request.values.get("cat_delete_name"))
    cat = dal.get_category_by_name(cat_name)
    if not cat:
        return not_found_error()

    active_user = get_active_user()
    if not active_user:
        return not_authenticated_error()
    if active_user.user_id != cat.creator_id:
        return not_authorized_error()

    # All checks passed
    generate_nonce()
    dal.delete_category(cat.cat_id)
    return redirect("/")
示例#11
0
def gconnect():
    """
    Receives and processes Google Plus login requests.
    Most of this code was adapted from the intro course on authentication.
    """
    if not check_nonce(request.args.get('state')):
        return create_err_response("Invalid state parameter", 401)
    code = request.data
    try:
        # Upgrade the authorization code into a credentials object
        scope = "email profile"
        oauth_flow = flow_from_clientsecrets(PATH_TO_CLIENT_SECRETS, scope=scope)
        oauth_flow.redirect_uri = "postmessage"
        credentials = oauth_flow.step2_exchange(code)
    except FlowExchangeError:
        return create_err_response("Failed to upgrade the authorization code", 401)

    # Check that the access token is valid
    access_token = credentials.access_token
    url = ("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s" % access_token)
    h = httplib2.Http()
    result = json.loads(h.request(url, "GET")[1])
    if result.get("error") is not None:
        return create_err_response(result.get("error"), 500)

    # Verify that the access token is used for the intended user
    gplus_id = credentials.id_token["sub"]
    if result["user_id"] != gplus_id:
        return create_err_response("Token's user ID doesn't match given user ID", 401)

    # Check to see if user is already logged in
    stored_credentials = session.get(SessionKeys.CREDENTIALS)
    stored_gplus_id = session.get(SessionKeys.GPLUS_ID)
    if stored_credentials is not None and gplus_id == stored_gplus_id:
        return create_err_response("Current user is already connected", 200)

    # Store the access token in the session for later use.
    save_to_session(SessionKeys.CREDENTIALS, credentials)
    session[SessionKeys.GPLUS_ID] = gplus_id

    # Get user info from Google
    try:
        answer = None
        data = None

        userinfo_url = "https://www.googleapis.com/oauth2/v1/userinfo"
        params = {"access_token": credentials.access_token, "alt":"json"}
        answer = requests.get(userinfo_url, params=params)
        data = json.loads(answer.text)

        username = data["email"]
        auth_source = AuthSource.GOOGLE_PLUS
        auth_source_id = data["id"]
        # Everything checks out.  Create a new user record if this is the
        # first time they've logged in, then set them as active in the session.
        user = dal.get_or_create_user(username, auth_source, auth_source_id)
        set_active_user(user)
    except Exception:
        return create_err_response(
            "Received invalid user data\n\nanswer.text: {}\n\ndata: {}".format(
                answer.text, data), 401)
    generate_nonce()
    return "Authentication successful"
示例#12
0
def gconnect():
    """
    Receives and processes Google Plus login requests.
    Most of this code was adapted from the intro course on authentication.
    """
    if not check_nonce(request.args.get('state')):
        return create_err_response("Invalid state parameter", 401)
    code = request.data
    try:
        # Upgrade the authorization code into a credentials object
        scope = "email profile"
        oauth_flow = flow_from_clientsecrets("client_secrets.json",
                                             scope=scope)
        oauth_flow.redirect_uri = "postmessage"
        credentials = oauth_flow.step2_exchange(code)
    except FlowExchangeError:
        return create_err_response("Failed to upgrade the authorization code",
                                   401)

    # Check that the access token is valid
    access_token = credentials.access_token
    url = ("https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s" %
           access_token)
    h = httplib2.Http()
    result = json.loads(h.request(url, "GET")[1])
    if result.get("error") is not None:
        return create_err_response(result.get("error"), 500)

    # Verify that the access token is used for the intended user
    gplus_id = credentials.id_token["sub"]
    if result["user_id"] != gplus_id:
        return create_err_response(
            "Token's user ID doesn't match given user ID", 401)

    # Check to see if user is already logged in
    stored_credentials = session.get(SessionKeys.CREDENTIALS)
    stored_gplus_id = session.get(SessionKeys.GPLUS_ID)
    if stored_credentials is not None and gplus_id == stored_gplus_id:
        return create_err_response("Current user is already connected", 200)

    # Store the access token in the session for later use.
    save_to_session(SessionKeys.CREDENTIALS, credentials)
    session[SessionKeys.GPLUS_ID] = gplus_id

    # Get user info from Google
    try:
        answer = None
        data = None

        userinfo_url = "https://www.googleapis.com/oauth2/v1/userinfo"
        params = {"access_token": credentials.access_token, "alt": "json"}
        answer = requests.get(userinfo_url, params=params)
        data = json.loads(answer.text)

        username = data["email"]
        auth_source = AuthSource.GOOGLE_PLUS
        auth_source_id = data["id"]
        # Everything checks out.  Create a new user record if this is the
        # first time they've logged in, then set them as active in the session.
        user = dal.get_or_create_user(username, auth_source, auth_source_id)
        set_active_user(user)
    except Exception:
        return create_err_response(
            "Received invalid user data\n\nanswer.text: {}\n\ndata: {}".format(
                answer.text, data), 401)
    generate_nonce()
    return "Authentication successful"