Esempio n. 1
0
def test_get_banned_user(client: TestClient, session: db.Session):
    """Get user returns 404 for banned users"""
    user, _ = utils.create_user_token(session)
    user.is_banned = True
    session.commit()
    response = client.get(f"/v2/players/{user.badge}")
    assert response.status_code == status.HTTP_404_NOT_FOUND, response.json()
Esempio n. 2
0
def save_collection(
        collection: List[str],
        session: db.Session = Depends(get_session),
        current_user: "******" = Depends(login_required),
):
    """Update the user's collection in place.

    PUT a list of release slugs to set them as the user's collection (e.g. `['master-set',
    'the-frostdale-giants']`.

    **This is not a patch!** You must pass the entire list of the user's collections every time.
    """
    # Clear out our existing releases
    session.query(UserRelease).filter(
        UserRelease.user_id == current_user.id).delete()
    session.commit()
    release_ids = ((session.query(Release.id).filter(
        Release.is_legacy.is_(False),
        Release.is_public.is_(True),
        Release.stub.in_(collection),
    ).all()) if collection else None)
    if release_ids:
        for row in release_ids:
            session.add(UserRelease(user_id=current_user.id,
                                    release_id=row.id))
        session.commit()
    query = get_releases_query(session=session, current_user=current_user)
    return query.all()
Esempio n. 3
0
def test_banned_user(client: TestClient, session: db.Session):
    """Login requests by banned users throw an error"""
    user, password = utils.create_user_password(session)
    user.is_banned = True
    session.commit()
    response = client.post("/v2/token", {"username": user.email, "password": password})
    assert response.status_code == status.HTTP_403_FORBIDDEN, response.json()
Esempio n. 4
0
def log_out(
        session: db.Session = Depends(get_session),
        jwt_payload: dict = Depends(get_auth_token),
        current_user: "******" = Depends(login_required),
):
    """Log a user out and revoke their JWT token's access rights.

    It's a good idea to invoke this whenever an authenticated user logs out, because tokens can otherwise be quite
    long-lived.
    """
    # Do some quick clean-up to keep our table lean and mean; deletes any tokens that expired more than 24 hours ago
    session.query(UserRevokedToken).filter(
        UserRevokedToken.expires < dt.datetime.utcnow() -
        dt.timedelta(days=1)).delete(synchronize_session=False)
    session.commit()
    # Then add our newly revoked token
    expires_at = dt.datetime.fromtimestamp(jwt_payload["exp"],
                                           tz=dt.timezone.utc)
    # No need to do `.get("jti")` here because a missing JTI would result in a credentials error in the dependencies
    revoked_hex = jwt_payload["jti"]
    revoked_uuid = uuid.UUID(hex=revoked_hex)
    revoked_token = UserRevokedToken(revoked_uuid=revoked_uuid,
                                     user_id=current_user.id,
                                     expires=expires_at)
    session.add(revoked_token)
    session.commit()
    return {"detail": "Token successfully revoked."}
Esempio n. 5
0
def create_player(
        token: UUID4,
        data: schema.UserRegistrationIn,
        session: db.Session = Depends(get_session),
        _=Depends(anonymous_required),
):
    """Create a new player using the token obtained by requesting an invite.

    Will fail if requested by an authenticated user.
    """
    invite = session.query(Invite).filter(Invite.uuid == token).first()
    if invite is None:
        raise NotFoundException(
            detail="Token not found. Please request a new invite.")
    user = create_user(
        session,
        invite.email,
        data.password,
        username=data.username,
        description=data.description,
        newsletter_opt_in=data.newsletter_opt_in,
    )
    session.delete(invite)
    session.commit()
    access_token = access_token_for_user(user)
    return {"access_token": access_token, "token_type": "bearer", "user": user}
Esempio n. 6
0
def test_request_password_reset_banned_user(client: TestClient, session: db.Session):
    """Banned users cannot request password resets"""
    user, _ = utils.create_user_token(session)
    user.is_banned = True
    session.commit()
    response = client.post("/v2/reset", json={"email": user.email})
    assert response.status_code == status.HTTP_403_FORBIDDEN
def check_notification_state(i):
    while 1:
            session = Session()
            ins_opition = queue_notification.get(True)
            print "Greenlets %s got : %s" % (i,time.asctime()), " " , ins_opition
            sql = """
                SELECT result
                FROM cloud_result
                WHERE TIME = ( 
                SELECT MAX( TIME ) 
                FROM cloud_result ) 
                AND uuid
                IN (
                '%s'
                )
                """ % ins_opition['uuid']
            result = raw_sql(sql)
            # if result is empty, skip current loop.
            if not result:
                continue
            # analyst notification in another function
            ret = analyst_notification_result(result,ins_opition)
            print "Greenlets notification %s got : %s" % (i,time.asctime()) , ret
            if not ret:
                continue
            q = session.query(Instances).filter(Instances.uuid==ins_opition['uuid'])
            if q.all():
                q.update(
                    {Instances.notification_state:simplejson.dumps(ret)}
                )
                session.commit()
Esempio n. 8
0
def request_password_reset(
        data: UserEmailIn,
        session: db.Session = Depends(get_session),
        _=Depends(anonymous_required),
):
    """Request a reset password link for the given email."""
    email = data.email.lower()
    user: User = session.query(User).filter(User.email == email).first()
    if not user:
        raise NotFoundException(detail="No account found for email.")
    if user.is_banned:
        raise BannedUserException()
    user.reset_uuid = uuid.uuid4()
    session.commit()
    if not send_message(
            recipient=user.email,
            template_id=settings.sendgrid_reset_template,
            data={
                "reset_token": str(user.reset_uuid),
                "email": user.email
            },
    ):
        if settings.debug:
            logger.debug(f"RESET TOKEN FOR {email}: {user.reset_uuid}")
        raise APIException(
            detail=
            "Unable to send password reset email; please contact Skaak#0007 on Discord."
        )
    return {
        "detail": "A link to reset your password has been sent to your email!"
    }
Esempio n. 9
0
def test_list_snapshots_bad_id(client: TestClient, session: db.Session, user1):
    """Not found error thrown when viewing non-existent deck"""
    deck = create_deck_for_user(session, user1)
    deleted_id = deck.id
    session.delete(deck)
    session.commit()
    response = client.get(f"/v2/decks/{deleted_id}/snapshots")
    assert response.status_code == status.HTTP_404_NOT_FOUND
Esempio n. 10
0
def test_login_required_banned_user(client: TestClient, session: db.Session):
    """login_required dependency does not allow banned users"""
    user, token = utils.create_user_token(session)
    user.is_banned = True
    session.commit()
    response = client.get(
        "/v2/players/me", headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == status.HTTP_403_FORBIDDEN, response.json()
Esempio n. 11
0
def test_get_releases(client: TestClient, session: db.Session):
    """Releases endpoint must return a list of all releases"""
    master_set = Release(name="Master Set")
    master_set.is_public = True
    session.add(master_set)
    session.commit()
    response = client.get("/v2/releases")
    assert response.status_code == status.HTTP_200_OK
    assert len(response.json()) == 1
Esempio n. 12
0
def test_get_private_share_deleted(
    client: TestClient, session: db.Session, user1, deck1
):
    """Deleted decks must throw an error when accessing their direct share UUID"""
    snapshot2 = create_snapshot_for_deck(session, user1, deck1)
    snapshot2.is_deleted = True
    session.commit()
    response = client.get(f"/v2/decks/shared/{snapshot2.direct_share_uuid}")
    assert response.status_code == status.HTTP_404_NOT_FOUND
Esempio n. 13
0
def test_delete_deck_legacy(client: TestClient, session: db.Session,
                            user_token):
    """Requests to delete a legacy deck must fail"""
    user, token = user_token
    deck = create_deck_for_user(session, user)
    deck.is_legacy = True
    session.commit()
    response = client.delete(f"/v2/decks/{deck.id}",
                             headers={"Authorization": f"Bearer {token}"})
    assert response.status_code == status.HTTP_400_BAD_REQUEST
Esempio n. 14
0
def test_delete_deck_already_deleted(client: TestClient, session: db.Session,
                                     user_token):
    """Must return success if deck was previously deleted"""
    user, token = user_token
    deck = create_deck_for_user(session, user)
    deck.is_deleted = True
    session.commit()
    response = client.delete(f"/v2/decks/{deck.id}",
                             headers={"Authorization": f"Bearer {token}"})
    assert response.status_code == status.HTTP_204_NO_CONTENT
Esempio n. 15
0
def update_my_data(
        updates: schema.UserSelfIn,
        current_user: "******" = Depends(login_required),
        session: db.Session = Depends(get_session),
):
    """Update user information for the logged-in user."""
    update_dict = updates.dict(exclude_unset=True)
    for key, value in update_dict.items():
        setattr(current_user, key, value)
    session.commit()
    return current_user
Esempio n. 16
0
def test_delete_deck_bad_deck(client: TestClient, session: db.Session,
                              user_token):
    """Must disallow access to deck IDs that don't exist"""
    user, token = user_token
    deck = create_deck_for_user(session, user)
    bad_id = deck.id
    session.delete(deck)
    session.commit()
    response = client.delete(f"/v2/decks/{bad_id}",
                             headers={"Authorization": f"Bearer {token}"})
    assert response.status_code == status.HTTP_403_FORBIDDEN
Esempio n. 17
0
def test_post_snapshot_deleted_deck(client: TestClient, session: db.Session,
                                    user_token):
    """Must not allow creating snapshots for a deleted deck"""
    user, token = user_token
    deck = create_deck_for_user(session, user)
    deck.is_deleted = True
    session.commit()
    response = client.post(
        f"/v2/decks/{deck.id}/snapshot",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert response.status_code == status.HTTP_400_BAD_REQUEST
Esempio n. 18
0
def test_put_deck_deleted(client: TestClient, session: db.Session, user_token):
    """Must not allow saving over a deleted deck"""
    user, token = user_token
    deck = create_deck_for_user(session, user)
    deck.is_deleted = True
    session.commit()
    valid_deck = _valid_deck_dict(session)
    valid_deck["id"] = deck.id
    response = client.put("/v2/decks",
                          json=valid_deck,
                          headers={"Authorization": f"Bearer {token}"})
    assert response.status_code == status.HTTP_400_BAD_REQUEST
Esempio n. 19
0
def test_patch_release_non_admin(client: TestClient, session: db.Session):
    """Patching a release must require admin access"""
    master_set = Release(name="Master Set")
    session.add(master_set)
    session.commit()
    user, token = create_user_token(session)
    response = client.patch(
        f"/v2/releases/{master_set.stub}",
        json={"is_public": True},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert response.status_code == status.HTTP_403_FORBIDDEN
Esempio n. 20
0
def test_get_releases_public_only(client: TestClient, session: db.Session):
    """Releases list must only include public releases"""
    master_set = Release(name="Master Set")
    master_set.is_public = True
    session.add(master_set)
    session.add(Release(name="Unreleased"))
    session.commit()
    response = client.get("/v2/releases")
    assert response.status_code == status.HTTP_200_OK
    data = response.json()
    assert len(data) == 1
    assert data[0]["stub"] == master_set.stub
Esempio n. 21
0
def test_reset_password_bad_passwords(client: TestClient, session: db.Session):
    """Password must match confirmation value"""
    user, _ = utils.create_user_token(session)
    user.reset_uuid = uuid.uuid4()
    session.commit()
    password = utils.generate_random_chars(8)
    password2 = f"a{password}"
    response = client.post(
        f"/v2/reset/{user.reset_uuid}",
        json={"password": password, "password_confirm": password2},
    )
    assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
def check_moniting_state_icmp(i):
    while 1:
        #try:
        session = Session()
        ins = queue_moniting.get(True)
        print "Greenlets %s got : %s" % (i,time.asctime()), " " , ins
        instance_result = dict()
        moniting_state = eval(ins['moniting_state'])
        ipaddress = eval(ins['ipaddress'])
        ping = moniting_state['ping']
        arp = moniting_state['arp']
        tcp = moniting_state['tcp']
        udp = moniting_state['udp']
        if ipaddress:
            instance_result['uuid'] = ins['uuid']
            for ip in ipaddress:
                instance_result[ip] = dict()
                if ping:
                    instance_result[ip]['ping'] = 1 if icmp_checker_gevent.check_icmp(ip) == True else 0
                #if arp:
                #    instance_result[ip]['arp'] = 1 if arp_checker_gevent.check_arp(ip) == True else 0
                #if tcp:
                #    instance_result[ip]['tcp'] = dict()
                #    if isinstance(tcp,unicode):
                #        # if tcp is unicode string, means that's only one port.
                #        port = tcp
                #        instance_result[ip]['tcp'][port] = 1 if tcp_checker_gevent.check_tcp(ip,int(port)) == True else 0
                #    else:
                #        for port in tcp:
                #            instance_result[ip]['tcp'][port] = 1 if tcp_checker_gevent.check_tcp(ip,int(port)) == True else 0
                ##if udp:
                #    instance_result[ip]['udp'] = dict()
                #    if isinstance(udp,unicode):
                #        # if tcp is unicode string, means that's only one port.
                #        port = udp
                #        instance_result[ip]['udp'][port] = 1 if udp_checker.checker_udp(ip,int(port)) == True else 0
                #    else:
                #        for port in udp:
                #            instance_result[ip]['udp'][port] = 1 if udp_checker.checker_udp(ip,int(port)) == True else 0
        
        print "Greenlets moniting %s got : %s" % (i,time.asctime()) , instance_result
        # send notification to user, use http or sms
        send_notification(instance_result,'moniting')
        # save last notification, used in next time
        save_one_notification(instance_result,'moniting')
        
        q = session.query(Instances).filter(Instances.uuid==ins['uuid'])
        if q.all():
            q.update(
                {Instances.moniting_state:simplejson.dumps(instance_result)}
            )
            session.commit()
Esempio n. 23
0
def test_get_legacy_card(client: TestClient, session: db.Session):
    """Must be able to read JSON for a legacy card"""
    # This is handled by a migration normally (legacy cards can't normally be created by this API)
    card = (session.query(Card).filter(Card.stub == "example-phoenixborn",
                                       Card.is_legacy == True).first())
    card.json["release"]["is_legacy"] = True
    card.json["is_legacy"] = True
    db.flag_modified(card, "json")
    session.commit()
    response = client.get("/v2/cards/example-phoenixborn",
                          params={"show_legacy": True})
    assert response.status_code == status.HTTP_200_OK
    assert response.json()["is_legacy"] == True, response.json()
Esempio n. 24
0
def test_post_snapshot_precon_non_public(client: TestClient,
                                         session: db.Session):
    """Must stop creation of preconstructed release if not a public snapshot"""
    admin, token = create_user_token(session)
    admin.is_admin = True
    session.commit()
    deck = create_deck_for_user(session, admin, release_stub="expansion")
    response = client.post(
        f"/v2/decks/{deck.id}/snapshot",
        json={"preconstructed_release": "expansion"},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert response.status_code == status.HTTP_400_BAD_REQUEST
Esempio n. 25
0
def test_put_deck_bad_id(client: TestClient, session: db.Session, user_token):
    """Must not allow uploading a deck with a bad ID"""
    # Create a deck so that we can ensure no accidental ID collisions
    user, token = user_token
    deck = create_deck_for_user(session, user)
    bad_id = deck.id
    session.delete(deck)
    session.commit()
    valid_deck = _valid_deck_dict(session)
    valid_deck["id"] = bad_id
    response = client.put("/v2/decks",
                          json=valid_deck,
                          headers={"Authorization": f"Bearer {token}"})
    assert response.status_code == status.HTTP_403_FORBIDDEN
Esempio n. 26
0
def test_post_snapshot_bad_deck_id(client: TestClient, session: db.Session,
                                   user_token):
    """Must not allow creating a snapshot for a bad deck ID"""
    # Create a deck so that we can ensure no accidental ID collisions
    user, token = user_token
    deck = create_deck_for_user(session, user)
    bad_id = deck.id
    session.delete(deck)
    session.commit()
    response = client.post(
        f"/v2/decks/{bad_id}/snapshot",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert response.status_code == status.HTTP_403_FORBIDDEN
Esempio n. 27
0
def test_reset_password(client: TestClient, session: db.Session):
    """Password reset must reset the password"""
    user, _ = utils.create_user_token(session)
    user.reset_uuid = uuid.uuid4()
    session.commit()
    new_password = utils.generate_random_chars(8)
    original_hash = user.password
    response = client.post(
        f"/v2/reset/{user.reset_uuid}",
        json={"password": new_password, "password_confirm": new_password},
    )
    assert response.status_code == status.HTTP_200_OK
    session.refresh(user)
    assert original_hash != user.password
Esempio n. 28
0
def test_admin_required_normal_user(client: TestClient, session: db.Session):
    """Non-admins cannot access admin_required dependency paths"""
    user1, token = utils.create_user_token(session)
    user2, _ = utils.create_user_token(session)
    user2.username = "******"
    session.commit()
    response = client.patch(
        f"/v2/players/{user2.badge}",
        headers={"Authorization": f"Bearer {token}"},
        json={"username": "******", "moderation_notes": "Bad name."},
    )
    assert response.status_code == status.HTTP_403_FORBIDDEN, response.json()
    session.refresh(user2)
    assert user2.username == "oldname"
Esempio n. 29
0
def test_get_deck_no_record(client: TestClient, session: db.Session, user1):
    """Trying to fetch an ID that no longer exists must fail correctly"""
    deck = create_deck_for_user(session, user1)
    deleted_id = deck.id
    session.delete(deck)
    session.commit()
    token = create_access_token(
        data={"sub": user1.badge},
        expires_delta=timedelta(minutes=15),
    )
    response = client.get(
        f"/v2/decks/{deleted_id}", headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == status.HTTP_404_NOT_FOUND
Esempio n. 30
0
def test_patch_release(client: TestClient, session: db.Session):
    """Patching a release to set it public must work"""
    master_set = Release(name="Master Set")
    session.add(master_set)
    session.commit()
    assert master_set.is_public == False
    admin, token = create_admin_token(session)
    response = client.patch(
        f"/v2/releases/{master_set.stub}",
        json={"is_public": True},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert response.status_code == status.HTTP_200_OK
    session.refresh(master_set)
    assert master_set.is_public == True
Esempio n. 31
0
def test_generate_badges_some_taken(session: db.Session, monkeypatch):
    """Unit test to simulate some badges being taken (recursion)"""
    user, _ = create_user_password(session)
    user.badge = "1234"
    session.commit()

    # Ensure our target badge is "randomly" generated the first time
    def _fake_badges(*args, **kwargs):
        # We only want to hijack this once
        monkeypatch.undo()
        return ["1234", "5678"]

    monkeypatch.setattr("api.services.user._random_badges", _fake_badges)

    badges = generate_badges(session, single=False, number=2)
    assert "5678" in badges
Esempio n. 32
0
def test_put_releases_bad_release(client: TestClient, session: db.Session):
    """Putting a nonsense stub must work"""
    master_set = Release(name="Master Set")
    master_set.is_public = True
    session.add(master_set)
    session.commit()
    user, token = create_user_token(session)
    response = client.put(
        "/v2/releases/mine",
        json=["fake-set"],
        headers={"Authorization": f"Bearer {token}"},
    )
    assert response.status_code == status.HTTP_200_OK
    data = response.json()
    assert data[0]["stub"] == master_set.stub
    assert data[0]["is_mine"] == False
Esempio n. 33
0
class check_notification_state(threading.Thread):
    """
    check moniting state for instance
    """
    def __init__(self):
        super(check_notification_state,self).__init__()
        self.daemon = True
        self.session = Session()
        
    
    def run(self):
        while 1:
                ins_opition = queue_notification.get(True)
                sql = """
                    SELECT result
                    FROM cloud_result
                    WHERE TIME = (
                    SELECT MAX( TIME ) 
                    FROM cloud_result ) 
                    AND uuid
                    IN (
                    '%s'
                    )
                    """ % ins_opition['uuid']
                result = raw_sql(sql)
                # if result is empty, skip current loop.
                if not result:
                    continue
                # analyst notification in another function
                ret = analyst_notification_result(result,ins_opition)
                if not ret:
                    continue
                q = self.session.query(Instances).filter(Instances.uuid==ins_opition['uuid'])
                if q.all():
                    q.update(
                        {Instances.notification_state:simplejson.dumps(ret)}
                    )
                    self.session.commit()
Esempio n. 34
0
class check_moniting_state(threading.Thread):
    """
    check moniting state for instance
    """
    def __init__(self):
        super(check_moniting_state,self).__init__()
        self.daemon = True
        self.session = Session()
        
    
    def run(self):
        while 1:
            #try:
            ins = queue_moniting.get(True)
            instance_result = dict()
            moniting_state = eval(ins['moniting_state'])
            ipaddress = eval(ins['ipaddress'])
            ping = moniting_state['ping']
            arp = moniting_state['arp']
            tcp = moniting_state['tcp']
            udp = moniting_state['udp']
            if ipaddress:
                instance_result['uuid'] = ins['uuid']
                for ip in ipaddress:
                    instance_result[ip] = dict()
                    if ping:
                        instance_result[ip]['ping'] = 1 if icmp_checker.check_icmp(ip) == True else 0
                    if arp:
                        instance_result[ip]['arp'] = 1 if arp_checker.check_arp(ip) == True else 0
                    if tcp:
                        instance_result[ip]['tcp'] = dict()
                        if isinstance(tcp,unicode):
                            # if tcp is unicode string, means that's only one port.
                            port = tcp
                            instance_result[ip]['tcp'][port] = 1 if tcp_checker.check_tcp(ip,int(port)) == True else 0
                        else:
                            for port in tcp:
                                instance_result[ip]['tcp'][port] = 1 if tcp_checker.check_tcp(ip,int(port)) == True else 0
                    if udp:
                        instance_result[ip]['udp'] = dict()
                        if isinstance(udp,unicode):
                            # if tcp is unicode string, means that's only one port.
                            port = udp
                            instance_result[ip]['udp'][port] = 1 if udp_checker.checker_udp(ip,int(port)) == True else 0
                        else:
                            for port in udp:
                                instance_result[ip]['udp'][port] = 1 if udp_checker.checker_udp(ip,int(port)) == True else 0
            # send notification to user, use http or sms
            send_notification(instance_result,'moniting')
            # save last notification, used in next time
            save_one_notification(instance_result,'moniting')
            
            q = self.session.query(Instances).filter(Instances.uuid==ins['uuid'])
            if q.all():
                q.update(
                    {Instances.moniting_state:simplejson.dumps(instance_result)}
                )
                self.session.commit()
            #except:
            #    pass
            
            # dont forget to close session at the end
            self.session.close()