Ejemplo n.º 1
0
def captcha(publicID):
    publicID = publicID.lower()

    session_info = session_db.find_one({"publicID": publicID}, {"_id": 0})
    hancock = Signer(str(secret_key), salt=str(session_info["privateID"]))

    if (publicID + "-guest") in request.cookies and hancock.validate(
            request.cookies.get(publicID + "-guest")):
        return redirect("https://www.crowdsourcejukebox.com/vote/" + publicID +
                        "/")

    if request.method == "POST":
        captcha_response = request.form["g-recaptcha-response"]
        if is_human(captcha_response):
            resp = make_response(
                redirect("https://www.crowdsourcejukebox.com/vote/" +
                         publicID + "/"))
            guestID = bytes(str(uuid.uuid4()), "utf-8")
            session_db.update_one({"publicID": publicID},
                                  {"$inc": {
                                      "guests": 1
                                  }})
            resp.set_cookie(
                publicID + "-guest",
                value=hancock.sign(guestID),
                expires=datetime.datetime.now() + datetime.timedelta(hours=1),
            )
            return resp
        else:
            return redirect("http://www.crowdsourcejukebox.com/")
    else:
        return render_template("captcha.html",
                               sitekey=os.environ["RC_SITE_KEY"])
Ejemplo n.º 2
0
def user_loader(session_token):
    signer = Signer(current_app.config["SECRET_KEY"])

    # verify the token we're getting hasn't been tampered with.
    if not signer.validate(session_token):
        current_app.logger.critical(f"bad signature from user's session token: {session_token}")
        return

    u =  Users.query.filter(Users.session_token == str(session_token)).first()
    if u:
        # verify token to make sure it hasn't been tampered with while in the database
        if not signer.validate(u.session_token):
            current_app.logger.critical(
                f"bad signature from stored session token: {u.session_token}")
            return

        current_app.logger.debug(
            f"loaded user by session token. user: {u} token: {u.session_token}")
        return u
Ejemplo n.º 3
0
def search(publicID):
    publicID = publicID.lower()
    now = int(time.time())
    session_info = session_db.find_one({"publicID": publicID}, {"_id": 0})
    if session_info is None:
        return redirect("http://www.crowdsourcejukebox.com/"), 301
    session_db.update_one({"publicID": publicID},
                          {"$set": {
                              "lastaccessed": now,
                              "lastread": now
                          }})
    hancock = Signer(secret_key, salt=session_info["privateID"])
    if (publicID + "-guest") not in request.cookies:
        return redirect("http://www.csjb.cc/" + publicID)
    else:
        if not hancock.validate(request.cookies.get(publicID + "-guest")):
            abort(401)
    if (session_info["settings"]["songlimit"]
            and setlist_db[publicID].find_one(
                {
                    "played": 0,
                    "submitted_by": request.cookies.get(publicID + "-guest")
                }) is not None):
        print("got one", file=sys.stderr)
        return render_template("search.html", publicID=publicID, wait=True)

    query = request.query_string.decode("UTF-8")
    if query != "" and "query=" in query:
        query = query[query.index("query="):]
        query = query[query.index("=") + 1:]
        query = query if "&" not in query else query[:query.index("&")]
        if query == "":
            return render_template("search.html",
                                   publicID=publicID,
                                   wait=False)
        query = urllib.parse.unquote_plus(query)
        results = sp.search(query, limit=35)["tracks"]["items"]
        if session_info["settings"]["noexplicit"]:
            results = [x for x in results if not x["explicit"]]
        tracks = [{
            "uri": result["uri"],
            "image": result["album"]["images"][0]["url"],
            "name": result["name"],
            "artist": result["artists"][0]["name"],
        } for result in results]
        return render_template("results.html",
                               tracks=tracks,
                               publicID=publicID,
                               prev_query=query)
    else:
        return render_template("search.html", publicID=publicID, wait=False)
Ejemplo n.º 4
0
def api():
    now = int(time.time())

    form = {key: request.form[key] for key in request.form.keys()}
    authorized_requests = [
        "newID",
        "unload",
        "setlist",
        "updates",
        "public",
        "playnext",
        "vote",
        "submit",
        "settings",
        "setFallback",
    ]
    if "req" not in form.keys() or form["req"] not in authorized_requests:
        abort(400)

    print("request:", form, file=sys.stderr)
    return_obj = {}
    if form["req"] == "newID":
        setlists = setlist_db.list_collection_names()
        to_drop = session_db.find(
            {"lastaccessed": {
                "$lt": now - (60 * INACTIVE_TIMEOUT)
            }})
        to_drop = [s["publicID"] for s in to_drop]
        if to_drop != []:
            print(to_drop, flush=True)
            for s in to_drop:
                if s in setlists:
                    setlist_db[s].drop()
        session_db.delete_many(
            {"lastaccessed": {
                "$lt": now - (60 * INACTIVE_TIMEOUT)
            }})

        return_obj = newID()
        killSession(form["oldID"], hard=True)
    if form["req"] == "unload":
        killSession(form["oldID"], hard=True)
    if form["req"] == "playnext":
        publicID = session_db.find_one({"privateID":
                                        form["privateID"]})["publicID"]
        return_obj = list(setlist_db[publicID].find({
            "played": 0,
            "upvotes": {
                "$gte": 0
            }
        }))
        if return_obj == []:
            past_played = [
                x for x in setlist_db[publicID].find({"played": 1}, {"_id": 0})
            ]
            top_played = sorted(past_played,
                                reverse=True,
                                key=lambda i: i["upvotes"])
            if len(top_played) > 20:
                top_played = top_played[:int(len(top_played) / 2)]
            seeds = []
            for i in range(4):
                seeds.append(
                    top_played.pop(random.randint(0,
                                                  len(top_played) - 1))["uri"])
            nextsong = sp.recommendations(seed_tracks=seeds,
                                          limit=1)["tracks"][0]
            return_obj = {"uri": nextsong["uri"], "upvotes": 0}

        else:
            return_obj = sorted(return_obj,
                                reverse=True,
                                key=lambda i: i["upvotes"])[0]
            setlist_db[publicID].update_one({"_id": return_obj.pop("_id")},
                                            {"$set": {
                                                "played": 1
                                            }})
            session_db.update_one(
                {"privateID": form["privateID"]},
                {"$set": {
                    "lastaccessed": now,
                    "lastmodified": now
                }},
            )

    if form["req"] == "setlist":
        form["number"] = int(form["number"])
        return_obj = list(setlist_db[form["publicID"]].find({"played": 0},
                                                            {"_id": 0}))
        return_obj = sorted(return_obj,
                            reverse=True,
                            key=lambda i: i["upvotes"])
        return_obj = (return_obj if form["number"] > len(return_obj) else
                      return_obj[:form["number"]])
        session_db.update_one(
            {"publicID": form["publicID"]},
            {"$set": {
                "lastaccessed": now,
                "lastread": now
            }},
        )
    if form["req"] == "updates":
        now = int(time.time())
        session = session_db.find_one({"publicID": form["publicID"]})
        return_obj = {"update": session["lastmodified"] > now - 7}
        session_db.update_one(
            {"publicID": form["publicID"]},
            {"$set": {
                "lastaccessed": now,
                "lastread": now
            }},
        )
    if form["req"] == "public":
        session_db.update_one(
            {"privateID": form["privateID"]},
            {"$set": {
                "lastaccessed": now,
                "lastread": now
            }},
        )
        info = session_db.find_one({"privateID": form["privateID"]})
        return_obj = {"publicID": info["publicID"], "display": info["display"]}
    if form["req"] == "vote":
        guestID = form["guestID"]
        session_info = session_db.find_one({"publicID": form["publicID"]},
                                           {"_id": 0})
        hancock = Signer(secret_key, salt=session_info["privateID"])
        if not hancock.validate(guestID):
            abort(401)
        publicID = form["publicID"]
        uri = form["uri"]
        direction = form["direction"]

        entry = setlist_db[publicID].find_one({"played": 0, "uri": uri})
        entry["upvoters"] = [] if "upvoters" not in entry.keys(
        ) else entry["upvoters"]
        entry["downvoters"] = ([] if "downvoters" not in entry.keys() else
                               entry["downvoters"])
        # print(guestID)
        if direction == "up":
            if guestID in entry["downvoters"]:
                entry["downvoters"].remove(guestID)
            # if guestID in entry["upvoters"]:
            #     entry["upvoters"].remove(guestID)
            if guestID not in entry["upvoters"]:
                entry["upvoters"].append(guestID)
        if direction == "down":
            if guestID in entry["upvoters"]:
                entry["upvoters"].remove(guestID)
            # if guestID in entry["downvoters"]:
            #     entry["downvoters"].remove(guestID)
            if guestID not in entry["downvoters"]:
                entry["downvoters"].append(guestID)
        if direction == "neutral":
            if guestID in entry["upvoters"]:
                entry["upvoters"].remove(guestID)
            if guestID in entry["downvoters"]:
                entry["downvoters"].remove(guestID)

        entry["upvotes"] = len(entry["upvoters"]) - len(entry["downvoters"])
        # print(entry["upvoters"])
        # print(entry["downvoters"])
        if len(entry["downvoters"]) > int(0.6 * session_info["guests"]) or (
                direction == "down" and guestID == entry["submitted_by"]):
            setlist_db[publicID].delete_one({"_id": entry["_id"]})
        else:
            setlist_db[publicID].update_one({"_id": entry["_id"]},
                                            {"$set": entry})
        session_db.update_one(
            {"publicID": form["publicID"]},
            {"$set": {
                "lastaccessed": now,
                "lastmodified": now
            }},
        )

    if form["req"] == "submit":
        guestID = form["guestID"]
        session_info = session_db.find_one({"publicID": form["publicID"]},
                                           {"_id": 0})
        hancock = Signer(secret_key, salt=session_info["privateID"])
        if not hancock.validate(guestID):
            abort(401)
        publicID = form["publicID"]
        uri = form["uri"]
        if (session_info["settings"]["songlimit"]
                and setlist_db[publicID].find_one({
                    "played": 0,
                    "submitted_by": guestID
                }) is not None):
            abort(403)
        entry = setlist_db[publicID].find_one({"played": 0, "uri": uri})
        if entry is not None:  # if the song is already in the setlist:
            entry["upvoters"] = ([] if "upvoters" not in entry.keys() else
                                 entry["upvoters"])
            entry["downvoters"] = ([] if "downvoters" not in entry.keys() else
                                   entry["downvoters"])
            if guestID in entry["downvoters"]:
                entry["downvoters"].remove(guestID)
            if guestID not in entry["upvoters"]:
                entry["upvoters"].append(guestID)
            entry["upvotes"] = len(entry["upvoters"]) - len(
                entry["downvoters"])
            setlist_db[publicID].update_one({"_id": entry["_id"]},
                                            {"$set": entry})
        else:
            return_obj = {
                "uri": uri,
                "upvoters": [guestID],
                "downvoters": [],
                "submitted_by": guestID,
                "played": 0,
                "upvotes": 1,
            }
            setlist_db[publicID].insert_one(return_obj)
            return_obj.pop("_id")
        session_db.update_one(
            {"publicID": form["publicID"]},
            {"$set": {
                "lastaccessed": now,
                "lastmodified": now
            }},
        )
        # session_db.update_one({"publicID": publicID}, {"$set":{"lastaccessed": now, "lastmodified":now}})

    if form["req"] == "settings":
        # print(str(form), file=sys.stderr)
        session_info = session_db.find_one({"privateID": form["privateID"]},
                                           {"_id": 0})
        if session_info is None:
            abort(404)
        settings = {
            "noexplicit": form["noexplicit"] == "true",
            "songlimit": form["songlimit"] == "true",
            "voteoff": form["voteoff"] == "true",
            "captcha": form["captcha"] == "true",
        }
        # print(settings, file=sys.stderr)
        session_db.update_one(
            {"privateID": form["privateID"]},
            {
                "$set": {
                    "lastaccessed": now,
                    "lastmodified": now,
                    "settings": settings
                }
            },
        )
        return_obj = session_db.find_one({"privateID": form["privateID"]},
                                         {"_id": 0})
        if settings["noexplicit"]:
            tmp_playlist = list(setlist_db[session_info["publicID"]].find(
                {
                    "played": 0
                }, {
                    "_id": 0
                }).sort("upvotes", -1))
            tracks = []
            while len(tmp_playlist) >= 50:
                tracks += sp.tracks([x["uri"]
                                     for x in tmp_playlist[:50]])["tracks"]
                tmp_playlist = tmp_playlist[50:]
            tracks += sp.tracks([x["uri"] for x in tmp_playlist])["tracks"]
            tracks = [t["uri"] for t in tracks if t["explicit"]]

            setlist_db[session_info["publicID"]].delete_many(
                {"uri": {
                    "$in": tracks
                }})
    if form["req"] == "setFallback":
        session_info = session_db.find_one({"privateID": form["privateID"]},
                                           {"_id": 0})
        if session_info is None:
            abort(404)
        setlist_db[session_info["publicID"]].delete_many(
            {"submitted_by": "fallback"})
        to_insert = sp.user_playlist(form["user"],
                                     form["uri"])["tracks"]["items"]
        if session_info["settings"]["noexplicit"]:
            for track in to_insert:
                # print(track["track"], file=sys.stderr)
                if track["track"]["explicit"]:
                    to_insert.remove(track)
        to_insert = [{
            "uri": x["track"]["uri"],
            "upvotes": 0,
            "submitted_by": "fallback",
            "upvoters": [],
            "downvoters": [],
            "played": 0,
        } for x in to_insert]
        # return_obj = to_insert
        setlist_db[session_info["publicID"]].insert_many(to_insert)
        session_db.update_one(
            {"privateID": form["privateID"]},
            {"$set": {
                "lastaccessed": now,
                "lastmodified": now
            }},
        )
        # return_obj.pop("_id")

    print("response:", return_obj, file=sys.stderr)
    return jsonify(return_obj)
Ejemplo n.º 5
0
def vote(publicID):
    publicID = publicID.lower()
    now = int(time.time())
    session_info = session_db.find_one({"publicID": publicID}, {"_id": 0})
    if session_info is None:
        abort(404)
    session_db.update_one({"publicID": publicID},
                          {"$set": {
                              "lastaccessed": now,
                              "lastread": now
                          }})
    current_playlist = list(setlist_db[publicID].find({
        "played": 0
    }, {
        "_id": 0
    }).sort("upvotes", -1))

    if current_playlist != []:
        tmp_playlist = current_playlist
        tracks = []
        while len(tmp_playlist) >= 49:
            tracks += sp.tracks([x["uri"]
                                 for x in tmp_playlist[:45]])["tracks"]
            tmp_playlist = tmp_playlist[45:]
        tracks += sp.tracks([x["uri"] for x in tmp_playlist])["tracks"]

        for t in range(len(tracks)):
            curr_track = current_playlist[t]
            if publicID + "-guest" in request.cookies:
                if ("upvoters" in curr_track.keys()
                        and request.cookies[publicID + "-guest"]
                        in curr_track["upvoters"]):
                    curr_track["vote"] = "up"
                    # curr_track["upvotes"] -= 1
                elif ("downvoters" in curr_track.keys()
                      and request.cookies[publicID + "-guest"]
                      in curr_track["downvoters"]):
                    curr_track["vote"] = "down"
                    # curr_track["upvotes"] += 1
                else:
                    curr_track["vote"] = "neutral"
            else:
                curr_track["vote"] = "neutral"
            curr_track["image"] = tracks[t]["album"]["images"][1]["url"]
            curr_track["name"] = tracks[t]["name"]
            # curr_track["album"] = tracks[t]["album"]["name"]
            curr_track["artist"] = tracks[t]["artists"][0]["name"]
    resp = make_response(
        render_template("vote.html",
                        publicID=publicID,
                        tracks=current_playlist))
    hancock = Signer(str(secret_key), salt=str(session_info["privateID"]))

    if (publicID + "-guest") not in request.cookies:
        # print(session_info["settings"], file=sys.stderr)
        if session_info["settings"]["captcha"]:
            return redirect("https://www.crowdsourcejukebox.com/captcha/" +
                            publicID + "/")
        else:
            guestID = bytes(str(uuid.uuid4()), "utf-8")
            session_db.update_one({"publicID": publicID},
                                  {"$inc": {
                                      "guests": 1
                                  }})
            resp.set_cookie(
                publicID + "-guest",
                value=hancock.sign(guestID),
                expires=datetime.datetime.now() + datetime.timedelta(hours=1),
            )
    else:
        if not hancock.validate(request.cookies.get(publicID + "-guest")):
            abort(401)
        # guestID = hancock.unsign(request.cookies.get(publicID + "-guest"))
    return resp
Ejemplo n.º 6
0
class User():
    def __init__(self,secret_key):
        #initialize signer
        self.s = Signer(secret_key)
        

    def deserialize(self,request):
        #it runs in framework BEFORE_REQUEST function
        self.cookies = request.cookies
        #check stat in cookie and verify it
        stat_str = str(self.cookies.get('stat'))
        stat_signature = str(self.cookies.get('stat_signature'))
        stat_token = stat_str+'.'+stat_signature
        

        if stat_str=='None' or self.s.validate(stat_token)==False:
            self._create_new_stat(request)
        #if validation success
        else:
            self.stat = json.loads(stat_str)        

        #increase kolvo_visits
        self._increase_kolvo_visits()

        #add actual IP for checking log_token
        self.stat['ip'] = request.environ['REMOTE_ADDR']
        self.log_token = str(self.cookies.get('log_token'))

        #initialize DB
        self._db_init()


    def serialize(self,response):
        #it runs in framework AFTER_REQUEST function
        stat_str = json.dumps(self.stat)

        sign_str = self.s.sign(stat_str)
        last_elem = len(sign_str.split('.'))
        #because dots in IP
        self.stat_signature = sign_str.split('.')[last_elem-1]

        response.set_cookie('stat',value=stat_str)
        response.set_cookie('stat_signature',value=self.stat_signature)

        if self.log_token!='None':
            response.set_cookie('log_token',value=self.log_token)
	else:
            response.set_cookie('log_token','',expires=0)
 


        #increase visits
        return response

    def _create_new_stat(self,request):
        self.stat = {}
        

        self.stat['ip'] = request.environ['REMOTE_ADDR']
        self.stat['first_reg'] = int(time.time())
        self.stat['kolvo_visits'] = 1
        self.stat['_id'] = 'yap'+str(int(time.time()))
        self.stat['last_visit'] = int(time.time()/86400)


    def _increase_kolvo_visits(self):
        new_day = int(time.time()/86400)
        if self.stat.get('last_visit')==None:
            self.stat['last_visit'] = int(time.time()/86400)

        if int(self.stat.get('last_visit'))<new_day:
            self.stat['kolvo_visits'] = self.stat['kolvo_visits']+1
            self.stat['last_visit'] = new_day



    def check_auth(self,roles):

        if self.log_token=='None':
            return 'Error User:Not Login, Please Log IN'

        if self.s.validate(self.log_token)!=True:
            return 'Error User:Not Valid Login Token. Please, Log IN'

        
        self.session = self._get_json(self.log_token)
        if self.session['ip']!=self.stat['ip']:
            return 'Error User:Not valid IP. Please, log IN'
        
        
        if (int(time.time()) - int(self.session['ts']))>int(self.session['live_time']):
            return 'Error User:Session nor fresh, please Log IN'

        #check permission
        for each in self.session['roles']:
            if each in roles:
                return True



        return 'Error User:Not enough permission'


        
    def _gen_token(self,user_id,u_doc):
        self.session = {}

        self.session['_id'] = user_id
        self.session['name'] = u_doc['name']
        self.session['ts'] = int(time.time())
        self.session['roles'] = u_doc['roles']
        self.session['live_time'] = u_doc.get('token_live_time')
        self.session['ip'] = self.stat['ip']



        #create JSON from dict and compress
        j = json.dumps(self.session)
        j64 = base64.b64encode(j)

        #create signature
        j64_sign = self.s.sign(j64)    
    
        return j64_sign
    
    def _get_json(self,token):
        if self.s.validate(token)!=True:
            return 'Error User: not valid Log Token'
        
        jb64 = self.s.unsign(token)
        j = base64.b64decode(jb64)
        j = json.loads(j)
        return j


    def login(self,user_name,user_pass):
        #if user id in db and pass is equal md5 with secret

        #check user name and get user doc

        u_doc,u_id = self._db_check_in(user_name)

        if u_doc==False:
            return 'Error User:No such User'

        #check pass
        if self._md5_trans(user_pass)!=u_doc['pass']:
            return 'Error User:Wrong Pass'

        self.log_token = self._gen_token(u_id, u_doc)
        return True


    def registr(self,u_doc):
        user_id = 'yap'+str(int(time.time()))
        if self._db_check_in(u_doc['name'])!=[False,False]:
            return 'Error User:There is user with the name '+u_doc['name']


        u_doc['pass'] = self._md5_trans(u_doc['pass'])
        self._db_add(user_id,u_doc)

	
        return True



    def drop_log_token(self):
        self.log_token = 'None'
        return True

    def _md5_trans(self,rec):
        m = md5.new()
        m.update(rec)
        return m.hexdigest()

    ##########  DB  #################
    def _db_init(self):
	cl = MongoClient('localhost',27017)
	_db = cl['users']
	self.db = _db['users']


    def _db_check_in(self,u_name):

	u_doc = self.db.find_one({'name':u_name})

	if u_doc==None:
		return [False,False]

	return u_doc,u_doc['_id']


    
    def _db_add(self,u_id,user_d):

	user_d['_id'] = u_id
	self.db.insert_one(user_d)