Example #1
0
def toggle_favourite(key):
	"""
	'Like' a dataset

	Marks the dataset as being liked by the currently active user, which can be
	used for organisation in the front-end.

	:param str key: Key of the dataset to mark as favourite.

	:return: A JSON object with the status of the request
	:return-schema: {type=object,properties={success={type=boolean},favourite_status={type=boolean}}}

	:return-error 404:  If the dataset key was not found
	"""
	try:
		dataset = DataSet(key=key, db=db)
	except TypeError:
		return error(404, error="Dataset does not exist.")

	current_status = db.fetchone("SELECT * FROM users_favourites WHERE name = %s AND key = %s",
								 (current_user.get_id(), dataset.key))
	if not current_status:
		db.insert("users_favourites", data={"name": current_user.get_id(), "key": dataset.key})
		return jsonify({"success": True, "favourite_status": True})
	else:
		db.delete("users_favourites", where={"name": current_user.get_id(), "key": dataset.key})
		return jsonify({"success": True, "favourite_status": False})
Example #2
0
def request_token():
    """
	Request an access token

	Requires that the user is currently logged in to 4CAT.

	:return: An object with one item `token`

	:return-schema={type=object,properties={token={type=string}}}

	:return-error 403:  If the user is logged in with an anonymous account.
	"""
    if current_user.get_id() == "autologin":
        # access tokens are only for 'real' users so we can keep track of who
        # (ab)uses them
        return error(403,
                     error="Anonymous users may not request access tokens.")

    token = db.fetchone(
        "SELECT * FROM access_tokens WHERE name = %s AND (expires = 0 OR expires > %s)",
        (current_user.get_id(), int(time.time())))

    if token:
        token = token["token"]
    else:
        token = current_user.get_id() + str(time.time())
        token = hashlib.sha256(token.encode("utf8")).hexdigest()
        token = {
            "name": current_user.get_id(),
            "token": token,
            "expires": int(time.time()) + (365 * 86400)
        }

        # delete any expired tokens
        db.delete("access_tokens", where={"name": current_user.get_id()})

        # save new token
        db.insert("access_tokens", token)

    if request.args.get("forward"):
        # show HTML page
        return redirect(url_for("show_access_tokens"))
    else:
        # show JSON response (by default)
        return jsonify(token)
Example #3
0
def add_user():
	if not current_user.is_admin():
		return error(403, message="This page is off-limits to you.")

	response = {"success": False}

	email = request.form.get("email", request.args.get("email", "")).strip()

	if not email or not re.match(r"[^@]+\@.*?\.[a-zA-Z]+", email):
		response = {**response, **{"message": "Please provide a valid e-mail address."}}
	else:
		username = email
		try:
			db.insert("users", data={"name": username, "timestamp_token": int(time.time())})

			user = User.get_by_name(username)
			if user is None:
				response = {**response, **{"message": "User was created but could not be instantiated properly."}}
			else:
				try:
					user.email_token(new=True)
					response["success"] = True
					response = {**response, **{
						"message": "An e-mail containing a link through which the registration can be completed has been sent to %s." % username}}
				except RuntimeError as e:
					response = {**response, **{
						"message": "User was created but the registration e-mail could not be sent to them (%s)." % e}}
		except psycopg2.IntegrityError:
			db.rollback()
			response = {**response, **{"message": "Error: User %s already exists." % username}}

	if request.args.get("format", None) == "html":
		return render_template("error.html", message=response["message"],
							   title=("New account created" if response["success"] else "Error"))
	else:
		return jsonify(response)
Example #4
0
def add_user():
    """
	Create a new user

	Sends the user an e-mail with a link through which they can set their
	password.

	:return: Either an html page with a message, or a JSON response, depending
	on whether ?format == html
	"""
    if not current_user.is_authenticated or not current_user.is_admin():
        return error(403, message="This page is off-limits to you.")

    response = {"success": False}

    email = request.form.get("email", request.args.get("email", "")).strip()
    fmt = request.form.get("format", request.args.get("format", "")).strip()
    force = request.form.get("force", request.args.get("force", None))

    if not email or not re.match(r"[^@]+\@.*?\.[a-zA-Z]+", email):
        response = {
            **response,
            **{
                "message": "Please provide a valid e-mail address."
            }
        }
    else:
        username = email
        try:
            db.insert("users",
                      data={
                          "name": username,
                          "timestamp_token": int(time.time())
                      })

            user = User.get_by_name(username)
            if user is None:
                response = {
                    **response,
                    **{
                        "message":
                        "User was created but could not be instantiated properly."
                    }
                }
            else:
                try:
                    user.email_token(new=True)
                    response["success"] = True
                    response = {
                        **response,
                        **{
                            "message":
                            "An e-mail containing a link through which the registration can be completed has been sent to %s." % username
                        }
                    }
                except RuntimeError as e:
                    response = {
                        **response,
                        **{
                            "message":
                            "User was created but the registration e-mail could not be sent to them (%s)." % e
                        }
                    }
        except psycopg2.IntegrityError:
            db.rollback()
            if not force:
                response = {
                    **response,
                    **{
                        "message":
                        'Error: User %s already exists. If you want to re-create the user and re-send the registration e-mail, use [this link](/admin/add-user?email=%s&force=1&format=%s).' % (username, username, fmt)
                    }
                }
            else:
                # if a user does not use their token in time, maybe you want to
                # be a benevolent admin and give them another change, without
                # having them go through the whole signup again
                user = User.get_by_name(username)
                db.update("users",
                          data={"timestamp_token": int(time.time())},
                          where={"name": username})

                try:
                    user.email_token(new=True)
                    response["success"] = True
                    response = {
                        **response,
                        **{
                            "message":
                            "A new registration e-mail has been sent to %s." % username
                        }
                    }
                except RuntimeError as e:
                    response = {
                        **response,
                        **{
                            "message":
                            "Token was reset registration e-mail could not be sent to them (%s)." % e
                        }
                    }

    if fmt == "html":
        return render_template(
            "error.html",
            message=response["message"],
            title=("New account created" if response["success"] else "Error"))
    else:
        return jsonify(response)