Esempio n. 1
0
def newacct():
    try:
        emaddr = dbacc.reqarg("email", "AppUser.email", required=True)
        emaddr = normalize_email(emaddr)
        verify_new_email_valid(emaddr)
        pwd = dbacc.reqarg("password", "string", required=True)
        cretime = dbacc.nowISO()
        appuser = {
            "dsType": "AppUser",
            "created": cretime,
            "email": "placeholder",
            "phash": "whatever",
            "accessed": cretime + ";1",
            "completed": "[]",
            "started": "[]",
            "built": "[]"
        }
        update_email_and_password(appuser, emaddr, pwd)
        update_account_fields(appuser)
        appuser = dbacc.write_entity(appuser)
        dbacc.entcache.cache_put(appuser)  # will need this again shortly
        token = token_for_user(appuser)
    except ValueError as e:
        return serve_value_error(e)
    return respJSON([appuser, token], audience="private")
Esempio n. 2
0
def fetchtl():
    """ Return the requested timeline and note the fetch. """
    try:
        tlid = dbacc.reqarg("tlid", "dbid")
        if tlid:
            tl = dbacc.cfbk("Timeline", "dsId", str(tlid), required=True)
        else:
            slug = dbacc.reqarg("slug", "string")
            if not slug:
                slug = "default"
            slug = slug.lower()  # in case someone camelcased the url.
            tl = dbacc.cfbk("Timeline", "slug", slug, required=True)
        tls = contained_timelines(tl)
        # Note the timeline was fetched for daily stats tracking
        det = {
            "referer": flask.request.headers.get("Referer", ""),
            "useragent": flask.request.headers.get("User-Agent", ""),
            "tlid": tl["dsId"],
            "tlname": tl["name"],
            "uid": dbacc.reqarg("uid", "dbid")
        }
        dcd = {
            "dsType": "DayCount",
            "tstamp": dbacc.timestamp(),
            "rtype": "tlfetch",
            "detail": json.dumps(det)
        }
        dbacc.write_entity(dcd)
    except ValueError as e:
        return util.serve_value_error(e)
    return util.respJSON(tls)
Esempio n. 3
0
def authenticate():
    emaddr = dbacc.reqarg("an", "AppUser.email")
    if not emaddr:
        emaddr = dbacc.reqarg("email", "AppUser.email")
    if not emaddr:
        raise ValueError("'an' or 'email' parameter required")
    emaddr = normalize_email(emaddr)
    appuser = dbacc.cfbk("AppUser", "email", emaddr)
    if not appuser:
        raise ValueError(emaddr + " not found")
    dbacc.entcache.cache_put(appuser)  # will likely reference again soon
    reqtok = dbacc.reqarg("at", "string")
    if not reqtok:
        password = dbacc.reqarg("password", "string")
        if not password:
            raise ValueError("Access token or password required")
        phash = make_password_hash(emaddr, password, appuser["created"])
        if phash == appuser["phash"]:  # authenticated, rebuild token
            reqtok = token_for_user(appuser)
        else:  # failing now due to lack of token, log for analysis if needed
            logging.info(appuser["email"] + " password hash did not match")
            logging.info("  AppUser[\"phash\"]: " + appuser["phash"])
            logging.info("      Server phash: " + phash)
    srvtok = token_for_user(appuser)
    if reqtok != srvtok:
        logging.info(appuser["email"] + " authenticated token did not match")
        logging.info("  reqtok: " + reqtok)
        logging.info("  srvtok: " + srvtok)
        raise ValueError("Wrong password")
    return appuser, srvtok
Esempio n. 4
0
def set_fields_from_reqargs(fields, obj):
    for fld in fields:
        val = dbacc.reqarg(fld, "string")
        if not val:
            val = dbacc.reqarg(fld + "in", "string")
        if val:
            if val.lower() == "noval":  # remove any existing value
                val = ""
            obj[fld] = val
    return obj
Esempio n. 5
0
def url_for_mail_message():
    returl = dbacc.reqarg("returl", "string")
    if not returl:
        returl = site_home() + "/timeline/default"
    else:
        returl = urllib.parse.unquote(returl)
    return returl
Esempio n. 6
0
def upldpic():
    """ Form submit and monitoring for uploading a point pic. """
    # flask.request.method always returns "GET", so check for file input.
    picfile = flask.request.files.get("picfilein")
    if not picfile:
        logging.info("upldpic ready for upload")
        return util.respond("Ready", mimetype="text/plain")
    try:
        appuser, _ = util.authenticate()
        ptid = dbacc.reqarg("ptid", "dbid", required=True)
        pt = dbacc.cfbk("Point", "dsId", ptid, required=True)
        logging.info(appuser["email"] + " upldpic Point " + str(ptid))
        if not appuser["dsId"] in util.csv_to_list(pt["editors"]):
            raise ValueError("Not authorized to edit this point")
        img = Image.open(picfile)
        img = ImageOps.exif_transpose(img)  # correct vertical orientation
        sizemaxdims = 400, 400  # max allowed width/height for thumbnail resize
        img.thumbnail(sizemaxdims)  # modify, preserving aspect ratio
        bbuf = io.BytesIO()  # file-like object for save
        img.save(bbuf, format="PNG")
        pt["pic"] = base64.b64encode(bbuf.getvalue())
        pt = dbacc.write_entity(pt, pt["modified"])
    except ValueError as e:
        logging.info("upldpic Point " + str(ptid) + ": " + str(e))
        return util.serve_value_error(e)
    return util.respond("Done: " + pt["modified"], mimetype="text/plain")
Esempio n. 7
0
def obimg():
    """ Return the associated image for the give object, or a blank 4x4. """
    # The client might make a call to get a pic for an object which might
    # not have one.  Better to return a blank than an error in that case.
    imgdat = B64ENCTRANSPARENT4X4PNG
    try:
        dsType = dbacc.reqarg("dt", "string", required=True)
        dsId = dbacc.reqarg("di", "string", required=True)
        inst = dbacc.cfbk(dsType, "dsId", dsId)
        if inst:
            picfldmap = {"Point": "pic"}
            imgdat = inst[picfldmap[dsType]]
            imgdat = base64.b64decode(imgdat)
    except ValueError as e:
        return util.serve_value_error(e)
    return util.respond(imgdat, mimetype="image/png")
Esempio n. 8
0
def fetchobj():
    """ General purpose object retrieval, public info only. """
    oj = ""
    try:
        dsType = dbacc.reqarg("dt", "string", required=True)
        keyfld = dbacc.reqarg("ak", "string")  # alternate key
        if keyfld:
            fldval = dbacc.reqarg("kv", "string", required=True)
        else:
            keyfld = "dsId"
            fldval = dbacc.reqarg("di", "string", required=True)
        inst = dbacc.cfbk(dsType, keyfld, fldval)
        if not inst:
            raise ValueError(dsType + " " + keyfld + ": " + fldval +
                             " not found")
        oj = util.safe_JSON(inst)
    except ValueError as e:
        return util.serve_value_error(e)
    return util.respJSON("[" + oj + "]")
Esempio n. 9
0
def findcomps():
    """ Return completions from other people for the given timeline. """
    try:
        appuser, _ = util.authenticate()
        tlid = dbacc.reqarg("tlid", "dbid", required=True)
        where = ("WHERE tlid = " + tlid + " AND userid != " + appuser["dsId"] +
                 " ORDER BY modified DESC LIMIT 50")
        tlcs = dbacc.query_entity("TLComp", where)
    except ValueError as e:
        return util.serve_value_error(e)
    return util.respJSON(tlcs)
Esempio n. 10
0
def supphelp():
    accurl = "Nope."
    try:
        administrator_auth()
        emaddr = dbacc.reqarg("email", "AppUser.email", required=True)
        appuser = dbacc.cfbk("AppUser", "email", emaddr)
        accurl = (site_home() + "/timeline/default?an=" +
                  urllib.parse.quote(appuser["email"]) + "&at=" +
                  token_for_user(appuser))
    except ValueError as e:
        return serve_value_error(e)
    return accurl
Esempio n. 11
0
def notefs():
    """ Note first save of Timeline progress. """
    # normally called to make note of an anonymous user having reached the
    # first save point in a timeline.  Shows someone interacted with the
    # timeline even if they don't create an account.
    try:
        det = {
            "useragent": flask.request.headers.get("User-Agent", ""),
            "tlid": dbacc.reqarg("tlid", "dbid"),
            "tlname": dbacc.reqarg("tlname", "string"),
            "uid": dbacc.reqarg("uid", "dbid")
        }
        dcd = {
            "dsType": "DayCount",
            "tstamp": dbacc.timestamp(),
            "rtype": "guestsave",
            "detail": json.dumps(det)
        }
        dbacc.write_entity(dcd)
    except ValueError as e:
        return util.serve_value_error(e)
    return util.respJSON("[]")
Esempio n. 12
0
def updacc():
    try:
        appuser, token = authenticate()
        chg = update_email_and_password(
            appuser, dbacc.reqarg("updemail", "AppUser.email"),
            dbacc.reqarg("updpassword", "string"))
        if chg != "nochange":
            logging.info("Changing " + chg + " for " + appuser["email"])
        update_account_fields(appuser)
        update_accessed_count(appuser)
        actcode = dbacc.reqarg("actcode", "string")
        if actcode:
            logging.info(appuser["email"] + " actcode: " + actcode)
            if actcode == appuser["actcode"]:
                appuser["status"] = "Active"
            else:
                logging.info("actcode did not match: " + appuser["actcode"])
        appuser = dbacc.write_entity(appuser, appuser["modified"])
        dbacc.entcache.cache_put(appuser)  # ensure cache has latest
        token = token_for_user(appuser)  # return possibly updated token
    except ValueError as e:
        return serve_value_error(e)
    return respJSON([appuser, token], audience="private")
Esempio n. 13
0
def mailpwr():
    try:
        subj = "PastKey.org account password reset link"
        emaddr = dbacc.reqarg("email", "AppUser.email", required=True)
        returl = url_for_mail_message()
        body = "You asked to reset your PastKey account password.\n\n"
        user = dbacc.cfbk("AppUser", "email", emaddr)
        if user:
            logging.info("mailpwr sending access link to " + emaddr)
            body += "Use this link to access the settings for your account: "
            body += (returl + "?an=" + urllib.parse.quote(user["email"]) +
                     "&at=" + token_for_user(user) + "\n\n")
        else:
            logging.info("mailpwr no account found for " + emaddr)
            body += "You do not have an account for " + emaddr + ". "
            body += "Either you have not signed up yet, or you used "
            body += "a different email address.  To create an account "
            body += "visit " + returl + "\n\n"
        send_mail(emaddr, subj, body)
    except ValueError as e:
        return serve_value_error(e)
    return respJSON("[]")