def new_client(clientid, apikey, role="normal"):
    '''
    Adds new client to the database. A client is an application wishing to interact
    with the gameevents service.
    
    TODO: Protect this function so that only admins have access.
    
    :param clientid: human-readable name of the client 
    :param apikey: apikey (password) to authenticate the client
    :param role: optional role of the client (admin/normal). Normal clients are able to read/write 
                 only one sessionid. Admin clients can read many sessions.
    '''

    if role != "admin":
        role = "normal"

    if clientid is None or apikey is None:
        raise ParseError('Invalid parameters')
    if db.session.query(Client).filter_by(
            clientid=clientid).first() is not None:
        raise ClientExistsException('Client exists')
    client = Client(clientid, apikey, role)
    db.session.add(client)
    try:
        db.session.commit()
        #print(client)
        return client
    except Exception as e:
        LOG.warning(e)
        db.session.rollback()
        db.session.flush()  # for resetting non-commited .add()
        return False
Example #2
0
def record_gameevent(sessionid, token, events):
    '''
    Checks if the token is valid and records the game event(s) in the database.
    
    :param sessionid: Sessionid to which the gameevent is related
    :param token: the token used to authenticate the request
    :param events: JSON representation of the event
    :returns: Number of events inserted successfully in the database.
    :rtype: int
    '''

    client = Client.verify_auth_token(token)
    
   
    if client and ("sessionid" in client):
        if sessionid != client["sessionid"]:
            raise NotAcceptable("Requested sessionID and token sessionid do not match.")
        
        query_sessionid = db.session.query(Session).filter(Session.id == sessionid)
        try:
            res_sessionid = query_sessionid.one()
        except NoResultFound:
            # SessionID is not in the db.
            raise NotFound("This sessionid is not in the database. Did you request a token first?")
            
        #serialized_events = False
        decoded_events = False
        count_new_records = 0
        if (res_sessionid):
            #TODO: Validate the game event against XML schema or JSON-LD context?
            if (isinstance(events, str)):            
                try:
                    decoded_events = simplejson.loads(events)
                #serialized_events = simplejson.dumps(decoded_events)
                except JSONDecodeError:
                    raise BadRequest
            elif (isinstance(events, list)):
                decoded_events = events
            else:
                raise BadRequest
            
            results = []
            if decoded_events:
                for decoded_event in decoded_events:
                    new_gameevent = GameEvent(sessionid, simplejson.dumps(decoded_event))
                    db.session.add(new_gameevent)
                    results.append(new_gameevent)
                    try:
                        db.session.commit()
                        count_new_records = count_new_records + 1
                    except Exception as e:
                        LOG.warning(e)
                        db.session.rollback()
                        db.session.flush() # for resetting non-commited .add()
                        LOG.error(e, exc_info=True)
                        raise e
            return results        
    else:
        raise AuthenticationFailed('Unauthorized token. You need a client token to edit gaming sessions.') 
def token_authenticate(token):
    '''
    Tries to authenticate a client checking the token.
    
    :param token: The token to be checked
    :raises: `AuthenticationFailed` if client does not exist or if token is not valid/has expired.
    :returns: the client that has been authenticated
    :rtype: :py:class:`gameevents_app.models.session.Client`
    '''
    """"""
    try:
        token_client = Client.verify_auth_token(token)
        clientid_from_token = token_client["clientid"]
        client = db.session.query(Client).filter_by(
            clientid=clientid_from_token).one()
        return client
    except NoResultFound:
        # Temporary fix to be able to create the first admin user
        if clientid_from_token == "masteroftheuniverse":
            client = Client(clientid_from_token, "easkdajskda")
            return client
        else:
            raise AuthenticationFailed("Clientid does not exist.")
Example #4
0
def token_authenticate(token):
    '''
    Tries to authenticate a client checking the token.
    
    :param token: The token to be checked
    :raises: `AuthenticationFailed` if client does not exist or if token is not valid/has expired.
    :returns: the client that has been authenticated
    :rtype: :py:class:`gameevents_app.models.session.Client`
    '''
    """"""
    try:
        token_client = Client.verify_auth_token(token)
        clientid_from_token = token_client["clientid"]
        client = db.session.query(Client).filter_by(clientid = clientid_from_token).one()
        return client
    except NoResultFound:
        # Temporary fix to be able to create the first admin user
        if clientid_from_token == "masteroftheuniverse":
            client = Client(clientid_from_token, "easkdajskda")
            return client
        else:
            raise AuthenticationFailed("Clientid does not exist.")
def record_gameevent(sessionid, token, events):
    '''
    Checks if the token is valid and records the game event(s) in the database.
    
    :param sessionid: Sessionid to which the gameevent is related
    :param token: the token used to authenticate the request
    :param events: JSON representation of the event
    :returns: Number of events inserted successfully in the database.
    :rtype: int
    '''

    client = Client.verify_auth_token(token)

    if client and ("sessionid" in client):
        if sessionid != client["sessionid"]:
            raise NotAcceptable(
                "Requested sessionID and token sessionid do not match.")

        query_sessionid = db.session.query(Session).filter(
            Session.id == sessionid)
        try:
            res_sessionid = query_sessionid.one()
        except NoResultFound:
            # SessionID is not in the db.
            raise NotFound(
                "This sessionid is not in the database. Did you request a token first?"
            )

        #serialized_events = False
        decoded_events = False
        count_new_records = 0
        if (res_sessionid):
            #TODO: Validate the game event against XML schema or JSON-LD context?
            if (isinstance(events, str)):
                try:
                    decoded_events = simplejson.loads(events)
                #serialized_events = simplejson.dumps(decoded_events)
                except JSONDecodeError:
                    raise BadRequest
            elif (isinstance(events, list)):
                decoded_events = events
            else:
                raise BadRequest

            results = []
            if decoded_events:
                for decoded_event in decoded_events:
                    new_gameevent = GameEvent(sessionid,
                                              simplejson.dumps(decoded_event))
                    db.session.add(new_gameevent)
                    results.append(new_gameevent)
                    try:
                        db.session.commit()
                        count_new_records = count_new_records + 1
                    except Exception as e:
                        LOG.warning(e)
                        db.session.rollback()
                        db.session.flush()  # for resetting non-commited .add()
                        LOG.error(e, exc_info=True)
                        raise e
            return results
    else:
        raise AuthenticationFailed(
            'Unauthorized token. You need a client token to edit gaming sessions.'
        )
    def setUpClass(self):

        self.app = create_app(testing=True)
        self.app_context = self.app.app_context()
        self.app_context.push()
        self.client = self.app.test_client()

        LOG.info("Initializing tests.")

        #Create a brand new test db
        db.create_all()

        #Add a clientid and apikey
        new_client = Client("myclientid", "myapikey", "normal")
        new_admin_client = Client("dashboard", "dashboardapikey", "admin")
        db.session.add(new_client)
        db.session.add(new_admin_client)
        try:
            db.session.commit()
            LOG.info("=== Added clients ===")
        except Exception as e:
            LOG.error(e, exc_info=True)

        #Generating gaming sessions ids
        self.newsessionid = UUID(bytes=OpenSSL.rand.bytes(16)).hex
        self.newsessionid2 = UUID(bytes=OpenSSL.rand.bytes(16)).hex
        self.newsessionid3 = UUID(
            bytes=OpenSSL.rand.bytes(16)).hex  #session not in db
        self.unauthorized_sessionid = "ac52bb1d811356ab3a8e8711c5f7ac5d"

        new_session = Session(self.newsessionid, new_client.id)
        new_session2 = Session(self.newsessionid2, new_client.id)
        db.session.add(new_session)
        db.session.add(new_session2)
        try:
            db.session.commit()
            LOG.info("=== Added sessions ===")
            LOG.info("=== Session not in db: %s ===" % self.newsessionid3)
        except Exception as e:
            LOG.error(e, exc_info=True)

        #Generating tokens
        self.mytoken = new_client.generate_auth_token(self.newsessionid)
        self.myexpiredtoken = new_client.generate_auth_token(self.newsessionid,
                                                             expiration=1)

        self.mytokennewsession = new_client.generate_auth_token(
            self.newsessionid3)

        self.myadmintoken = new_admin_client.generate_auth_token()
        self.myexpiredadmintoken = new_admin_client.generate_auth_token(
            expiration=1)

        self.mybadtoken = "badlogin" + self.mytoken.decode()[8:]
        self.mybadtoken = self.mybadtoken.encode("ascii")

        self.xml_valid_event = """<event><timestamp>2015-11-29T12:10:57Z</timestamp>
        <action>STARTGAME</action><level></level><update></update><which_lix>
        </which_lix><result></result></event>"""
        self.json_valid_event = """[{
                "timestamp": "2015-11-29T12:10:57Z",
                "action": "STARTGAME",
                "which_lix": ""
              }]"""
        self.xml_invalid_event = """<event>a
         <action>STARTGAME</action>
         <timestamp>2015-11-29T12:10:57Z</timestamp>
         <which_lix />
      </event>"""
        self.json_invalid_event = """
                "timestamp": "2015-11-29T12:10:57Z",
                "action": "STARTGAME",,
                "which_lix": ""
              """
        self.xml_multiple_events = """<event>
         <action>STARTGAME</action>
         <timestamp>2015-11-29T12:10:57Z</timestamp>
         <which_lix />
      </event>
      <event>
         <action>ENDGAME</action>
         <timestamp>2015-11-29T13:10:57Z</timestamp>
         <which_lix />
      </event>"""

        self.json_multiple_events = """[{ "timestamp": "2015-11-29T12:10:57Z",
                "action": "STARTGAME",
                "which_lix": ""
              }, {
                "timestamp": "2015-11-29T13:10:57Z",
                "action": "ENDGAME",
                "which_lix": ""
              }]"""

        time.sleep(3)  #expire the token

        new_gameevent = GameEvent(new_session.id, self.xml_valid_event)
        db.session.add(new_gameevent)
        try:
            db.session.commit()
            LOG.info("=== Added game event. All set up. ===")
        except Exception as e:
            LOG.error(e, exc_info=True)
 def setUpClass(self):
     
     self.app = create_app(testing=True)
     self.app_context = self.app.app_context()
     self.app_context.push()
     self.client = self.app.test_client()
     
     LOG.info("Initializing tests.")
     
     #Create a brand new test db
     db.create_all()
     
     #Add a clientid and apikey
     new_client = Client("myclientid", "myapikey", "normal")
     new_admin_client = Client("dashboard", "dashboardapikey", "admin")  
     db.session.add(new_client)
     db.session.add(new_admin_client)
     try:
         db.session.commit()
         LOG.info("=== Added clients ===")
     except Exception as e:
         LOG.error(e, exc_info=True)      
     
     #Generating gaming sessions ids
     self.newsessionid = UUID(bytes = OpenSSL.rand.bytes(16)).hex
     self.newsessionid2 = UUID(bytes = OpenSSL.rand.bytes(16)).hex
     self.newsessionid3 = UUID(bytes = OpenSSL.rand.bytes(16)).hex #session not in db
     self.unauthorized_sessionid = "ac52bb1d811356ab3a8e8711c5f7ac5d"
     
     new_session = Session(self.newsessionid, new_client.id)
     new_session2 = Session(self.newsessionid2, new_client.id)
     db.session.add(new_session)
     db.session.add(new_session2)
     try:
         db.session.commit()
         LOG.info("=== Added sessions ===")
         LOG.info("=== Session not in db: %s ===" % self.newsessionid3)
     except Exception as e:
         LOG.error(e, exc_info=True)
     
     #Generating tokens        
     self.mytoken = new_client.generate_auth_token(self.newsessionid)
     self.myexpiredtoken = new_client.generate_auth_token(self.newsessionid, expiration=1)
     
     self.mytokennewsession = new_client.generate_auth_token(self.newsessionid3)
     
     self.myadmintoken = new_admin_client.generate_auth_token()
     self.myexpiredadmintoken = new_admin_client.generate_auth_token(expiration=1)
     
     self.mybadtoken = "badlogin" + self.mytoken.decode()[8:]
     self.mybadtoken = self.mybadtoken.encode("ascii")
     
     self.xml_valid_event = """<event><timestamp>2015-11-29T12:10:57Z</timestamp>
     <action>STARTGAME</action><level></level><update></update><which_lix>
     </which_lix><result></result></event>""";
     self.json_valid_event = """[{
             "timestamp": "2015-11-29T12:10:57Z",
             "action": "STARTGAME",
             "which_lix": ""
           }]"""
     self.xml_invalid_event = """<event>a
      <action>STARTGAME</action>
      <timestamp>2015-11-29T12:10:57Z</timestamp>
      <which_lix />
   </event>"""
     self.json_invalid_event = """
             "timestamp": "2015-11-29T12:10:57Z",
             "action": "STARTGAME",,
             "which_lix": ""
           """
     self.xml_multiple_events = """<event>
      <action>STARTGAME</action>
      <timestamp>2015-11-29T12:10:57Z</timestamp>
      <which_lix />
   </event>
   <event>
      <action>ENDGAME</action>
      <timestamp>2015-11-29T13:10:57Z</timestamp>
      <which_lix />
   </event>"""
     
     self.json_multiple_events = """[{ "timestamp": "2015-11-29T12:10:57Z",
             "action": "STARTGAME",
             "which_lix": ""
           }, {
             "timestamp": "2015-11-29T13:10:57Z",
             "action": "ENDGAME",
             "which_lix": ""
           }]"""
     
     time.sleep(3) #expire the token
  
     new_gameevent = GameEvent(new_session.id,self.xml_valid_event)
     db.session.add(new_gameevent)        
     try:
         db.session.commit()
         LOG.info("=== Added game event. All set up. ===")
     except Exception as e:
         LOG.error(e, exc_info=True)
Example #8
0
app = create_app()
with app.app_context():
    db.create_all()

    #Add the admin user
    from gameevents_app.models.client import Client

    #Generate random password
    from random import choice
    import string
    chars = string.ascii_letters + string.digits
    length = 16
    randompass = ''.join(choice(chars) for _ in range(length))

    admin = Client('administrator', randompass, "admin")
    db.session.add(admin)

    try:

        db.session.commit()
        sys.stdout.write(
            "Created administrator client: %s, with random apikey %s \n" %
            (admin.clientid, randompass))
    except Exception as e:
        sys.stdout.write(e)
        db.session.rollback()
        db.session.flush()  # for resetting non-commited .add()

#
# if not os.path.exists(SQLALCHEMY_MIGRATE_REPO):