Beispiel #1
0
class AuthHandler:
    def __init__(self, helperHandler):
        self.helperHandler = helperHandler
        self.beams_client = PushNotifications(
            instance_id='7032df3e-e5a8-494e-9fc5-3b9f05a68e3c',
            secret_key=
            '8AC9B8AABB93DFE452B2EFC2714FCF923841B6740F97207F4512F240264FF493')
        self.userDao = UserDAO()
        self.containerDao = ContainerDAO()
        self.authDao = AuthDao()
        self.locationDao = LocationDao()

    def validateCode(self, request, userDao, authDao):
        f = '%Y-%m-%d %H:%M:%S'
        keys = ["code", "email"]
        dic = None
        try:
            dic = self.helperHandler.handleRequestAndAuth(request,
                                                          keys,
                                                          hasAuth=False)
            res = self.userDao.selectUser(dic["email"])
            self.helperHandler.falseQueryCheck(res)
        except Exception as e:
            return json.dumps({"success": False, "message": str(e)})
        user = res[1]
        userDic = user.userToDict()
        codefromtable = userDic["authCode"]
        authtime = userDic["authTime"]
        authtimets = datetime.strptime(authtime, f)
        timepassed = datetime.now() - authtimets
        if (dic['code'] != codefromtable):
            return json.dumps({
                "success": False,
                "message": "Invalid verification code."
            })
        elif (timepassed.total_seconds() >= 300):
            return json.dumps({
                "success": False,
                "message": "Expired verification code"
            })
        # create new auth
        if "/validateCode" in str(request):
            return self.newAuth(dic, userDic, user)
        resAuth = self.authDao.selectByEmail(dic['email'])
        auth = resAuth[1]
        # update the auth
        authDic = auth.authToDict()
        authDic["auth_token"] = self.helperHandler.id_generator(size=45)
        authDic["refresh_token"] = auth.refresh_token
        auth.dictToAuth(authDic)
        res = self.authDao.updateAuth(auth)
        auth = res[1]
        if type(auth) == str:
            return json.dumps({"success": res[0], "data": auth})
        return json.dumps({"success": res[0], "data": auth.authToDict()})

    def newAuth(self, dic, userDic, user):
        authDic = {}
        authDic["user"] = dic["email"]

        authDic["auth_token"] = self.helperHandler.id_generator(size=45)
        authDic["refresh_token"] = self.helperHandler.id_generator(size=45)
        authDic["expires_at"] = ""
        auth = Auth()
        auth.dictToAuth(authDic)
        self.authDao.deleteAuth(auth)
        res = self.authDao.insertAuth(auth)
        data = auth.authToDict()
        # fix userAuth as well
        userDic["authorized"] = "1"
        user.dictToUser(userDic)
        self.userDao.updateUser(user)
        return json.dumps({"success": res[0], "data": data})
        # return it

    def loginErrorHandler(self, userDic, dic):
        message = None
        dencryptedpas = self.helperHandler.check_encrypted_password(
            dic["password"], userDic["password"])
        print(dencryptedpas)
        if message is None and "authorized" in userDic and userDic[
                "authorized"] == 0:
            message = "Email not found, please try signing up."
        if message is None and dencryptedpas == False:
            message = "Incorrect password."
        return message

    def login(self, request, userDao, authDao):
        dic = None
        keys = ["email", "password"]
        try:
            dic = self.helperHandler.handleRequestAndAuth(request,
                                                          keys,
                                                          hasAuth=False)
            resUser = self.userDao.selectUser(dic["email"])
            self.helperHandler.falseQueryCheck(resUser)
            resAuth = self.authDao.selectByEmail(dic['email'])
            self.helperHandler.falseQueryCheck(resAuth)
        except Exception as e:
            return json.dumps({"success": False, "message": str(e)})
        # handle login errors
        user = resUser[1]
        userDic = user.userToDict()
        errorRes = self.loginErrorHandler(userDic, dic)
        if errorRes is not None:
            return json.dumps({"success": False, "message": errorRes})
        # retrieve auth
        auth = resAuth[1]
        # update the auth
        authDic = auth.authToDict()
        authDic["auth_token"] = self.helperHandler.id_generator(size=45)
        authDic["refresh_token"] = auth.refresh_token
        auth.dictToAuth(authDic)
        res = self.authDao.updateAuth(auth)
        auth = res[1]
        if type(auth) == str:
            return json.dumps({"success": res[0], "data": auth})
        # return it
        return json.dumps({"success": res[0], "data": auth.authToDict()})

    def refreshCode(self, request, authDao):
        dic = None
        keys = ["email", "refresh_token"]
        try:
            dic = self.helperHandler.handleRequestAndAuth(request,
                                                          keys,
                                                          hasAuth=False)
            res = self.authDao.selectByEmail(dic["email"])
            self.helperHandler.falseQueryCheck(res)
        except Exception as e:
            return json.dumps({"success": False, "message": str(e)})
        auth = res[1]
        message = None
        # refresh token mismatch
        authDic = auth.authToDict()
        if dic["refresh_token"] != authDic["refresh_token"]:
            message = "Invalid token"
        # handle is auth code is expired
        timeobj = datetime.strptime(authDic["expires_at"], '%Y-%m-%d %H:%M:%S')
        if datetime.now() >= timeobj:
            message = "Expired token"
        if message is not None:
            return json.dumps({"success": False, "message": message})
        # return normal response
        authDic["token"] = self.helperHandler.id_generator(size=45)
        auth.dictToAuth(authDic)
        res = self.authDao.updateAuth(auth)
        return json.dumps({"success": True, "data": authDic})

    def beams_auth(self, param):
        beams_token = self.beams_client.generate_token(param)
        return json.dumps(beams_token)

    def resendAuthCode(self, request, userDao, authDao):
        f = '%Y-%m-%d %H:%M:%S'
        authCode = None
        dictOfUserAttrib = None
        keys = ["email"]
        dic = None
        try:
            dic = self.helperHandler.handleRequestAndAuth(request,
                                                          keys,
                                                          hasAuth=False)
        except Exception as e:
            return json.dumps({"success": False, "message": str(e)})

        user = User()
        user = self.userDao.selectUser(dic["email"])
        if user[0] == False:
            return json.dumps({"success": user[0], "message": user[1]})
        authtime = user[1].authTime
        authtimets = datetime.strptime(authtime, f)
        timepassed = datetime.now() - authtimets
        if (timepassed.total_seconds() < 300):
            self.helperHandler.sendEmail(user[1].email, user[1].authCode)
            return json.dumps({"success": True, "data": ""})
        if (timepassed.total_seconds() > 300):
            authCode = self.helperHandler.genAuthcode()
            user[1].authCode = authCode
            user[1].authTime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            userdic = user[1].userToDict()

            self.userDao.updateUser(user[1])
            self.helperHandler.sendEmail(user[1].email, authCode)
            return json.dumps({"success": True, "data": ""})

        return json.dumps({
            "success": False,
            "message": "Error in resendAuthCode."
        })
Beispiel #2
0
class unitTestAuthDAO(unittest.TestCase):
    """
    Test the authDAO class methods using the unit test framework.  
    To run these tests:
         python3 -m unittest unitTestAuthDAO.py
    """
    def setUp(self):
        """
       Setup a temporary database
       """
        self.dao = AuthDao()
        self.dao.changeDatabase("temp")

    def tearDown(self):
        """
        Delete the temporary database
        """
        self.dao = AuthDao()
        auth = Auth("*****@*****.**",
                    "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                    "2021-01-01 01:01:01")
        self.dao.deleteAuth(auth)

    # test creating auth token
    def testInsertAuthSmoke(self):
        self.dao = AuthDao()
        auth = Auth("*****@*****.**",
                    "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                    "2021-01-01 01:01:01")
        return self.dao.insertAuth(auth)

    def testInsertAuth(self):
        """
        Test that we can add an auth token that doesn't exist in the database
        """
        rc, msg = self.testInsertAuthSmoke()
        self.assertTrue(rc)

    def testInsertAuthTwice(self):
        """
        Test that we can't add an auth token twice
        First add should work correctly
        """
        rc, msg = self.testInsertAuthSmoke()
        self.assertTrue(rc)
        """
        Second add should fail
        """
        rc, msg = self.testInsertAuthSmoke()
        self.assertFalse(rc)
        self.assertEqual(msg, "Duplicate Entry")

    def testInsertAuthNoneType(self):
        self.dao = AuthDao()

        auth = Auth(None, "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                    "2021-01-01 01:01:01")
        rc, msg = self.dao.insertAuth(auth)
        self.assertFalse(rc)

        auth = Auth("*****@*****.**", None,
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                    "2021-01-01 01:01:01")
        rc, msg = self.dao.insertAuth(auth)
        self.assertFalse(rc)

        auth = Auth("*****@*****.**",
                    "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL", None,
                    "2021-01-01 01:01:01")
        rc, msg = self.dao.insertAuth(auth)
        self.assertFalse(rc)

    def testSelectByEmail(self):
        """
        Test that we can select a location that exists in the database already
        """
        rc, msg = self.testInsertAuthSmoke()
        self.assertTrue(rc)

        email = "*****@*****.**"
        self.dao = AuthDao()
        rc, selectByEmail = self.dao.selectByEmail(email)

        self.assertTrue(rc)
        self.assertEqual(email, selectByEmail.user)

    def testselectByEmailDoesntExist(self):
        """
        Test that we can't select a location that doesnt exist in the database already
        """
        rc, msg = self.testInsertAuthSmoke()
        self.assertTrue(rc)

        email = "*****@*****.**"
        self.dao = AuthDao()

        rc, selectByEmail = self.dao.selectByEmail(email)
        self.assertFalse(rc)

        rc, selectByEmail = self.dao.selectByEmail(None)
        self.assertFalse(rc)

    def testUpdateAuth(self):
        """
        Test that we can update an Auth.
        """
        rc, msg = self.testInsertAuthSmoke()
        self.assertTrue(rc)

        newAuth = Auth("*****@*****.**",
                       "Fcpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
                       "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                       "2021-01-01 01:01:01")
        self.dao = AuthDao()

        rc = self.dao.updateAuth(newAuth)
        self.assertTrue(rc)

        rc, updat = self.dao.selectByEmail(newAuth.user)
        self.assertTrue(rc)

        self.assertEqual(newAuth.auth_token, updat.auth_token)

    def testUpdateAuthDoesntExist(self):
        """
        Test that we can't update an Auth that doesn't exost.
        """
        rc, msg = self.testInsertAuthSmoke()
        self.assertTrue(rc)

        newAuth = Auth("*****@*****.**",
                       "Fcpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
                       "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                       "2021-01-01 01:01:01")
        self.dao = AuthDao()

        rc, updat = self.dao.selectByEmail(newAuth.user)
        self.assertFalse(rc)

        rc, updat = self.dao.selectByEmail(None)
        self.assertFalse(rc)

    def testDeleteAuth(self):
        """
        Test that we can delete an auth from the database
        """
        rc, msg = self.testInsertAuthSmoke()
        self.assertTrue(rc)

        auth = Auth("*****@*****.**",
                    "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                    "2021-01-01 01:01:01")
        self.dao = AuthDao()

        rc, deleteAuth = self.dao.deleteAuth(auth)
        self.assertTrue(rc)

        rc, selectByEmail = self.dao.selectByEmail(auth.user)
        self.assertFalse(rc)

    def testDeleteAuthDoesntExist(self):
        """
        Test that we can't delete an auth that doesn't exist
        """
        rc, msg = self.testInsertAuthSmoke()
        self.assertTrue(rc)

        auth = Auth("*****@*****.**",
                    "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                    "2021-01-01 01:01:01")
        self.dao = AuthDao()

        rc, deleteAuth = self.dao.deleteAuth(auth)
        self.assertTrue(rc)

        rc, deleteAuth = self.dao.deleteAuth(auth)
        self.assertFalse(rc)

        auth = Auth("*****@*****.**",
                    "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                    "2021-01-01 01:01:01")

        rc, deleteAuth = self.dao.deleteAuth(auth)
        self.assertFalse(rc)

        rc, deleteAuth = self.dao.deleteAuth(None)
        self.assertFalse(rc)

    def testInsertAuthUserTooLong(self):
        """
        Test that we cannot add a user to auth that is over 45 characters long
        """
        auth = Auth(
            "*****@*****.**",
            "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
            "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
            "2021-01-01 01:01:01")

        rc, insertAuth = self.dao.insertAuth(auth)
        self.assertFalse(rc)

    def testInsertAuth_TokenTooLong(self):
        """
        Test that we cannot add an auth_token to auth that is over 45 characters long
        """
        auth = Auth("*****@*****.**",
                    "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRLXXX",
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                    "2021-01-01 01:01:01")

        rc, insertAuth = self.dao.insertAuth(auth)
        self.assertFalse(rc)

    def testInsertRefresh_TokenTooLong(self):
        """
        Test that we cannot add an refresh_token to auth that is over 45 characters long
        """
        auth = Auth("*****@*****.**",
                    "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyL11ISH5ij9iRL",
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9XXX",
                    "2021-01-01 01:01:01")

        rc, insertAuth = self.dao.insertAuth(auth)
        self.assertFalse(rc)

    def testInsertWrongExpiresAt(self):
        """
        Test that we cannot add a incorrectly formatted date
        """
        auth = Auth("*****@*****.**",
                    "Fgpmy1lEbwaNoIqZmkjBkkzOtskzYquyM11ISH5ij9iRL",
                    "F9R51hFTGUgV0LeyJJAkwbSiZL1dfennuGDlPcUJnnNm9",
                    "01:01:01 2021-01-01")

        rc, insertAuth = self.dao.insertAuth(auth)
        self.assertFalse(rc)
Beispiel #3
0
class UserHandler:

    def __init__(self, helperHandler):
        self.helperHandler = helperHandler
        self.userDao = UserDAO()
        self.authDao = AuthDao()
        self.formats = {
            'email' : {
                "format":"([a-zA-Z0-9_.+-]+@+((students\.stonehill\.edu)|(stonehill\.edu))$)",
                "error":"Email"
                },
            'password' : {
                "format":"(([a-z|A-Z|0-9])|([^A-Za-z0-9]))+$",
                "error":"Password"
                },
            'firstName': {
                "format":"[a-z|A-Z]+$",
                "error":"First Name"
                },
            'lastName': {
                "format":"[a-z|A-Z]+$",
                "error":"Last Name"
                },
            'middleName': {
                "format":"[a-z|A-Z]*$",
                "error":"Middle Name"
                },
            'phoneNum': {
                "format":"([0-9]{10}$)|([0-9]{11}$)|([0-9]{12}$)",
                "error":"Phone Number"
                }
            
        }

    def getUser(self, request, userDao, hasAuth):
        keys = ["email"]
        return self.userCRUDS(data=[request,keys], userDao=userDao, hasAuth=hasAuth, f=1)

    def getAllUsers(self, request, userDao, hasAuth):
        keys = ["email"]
        return self.userCRUDS(data=[request,keys], userDao=userDao, hasAuth=hasAuth, f=4)

    def addUser(self, request, userDao):
        dictOfUserAttrib = None
        # keys to scape from request
        keys = ['email', 'password', 'firstName', 'lastName', 'middleName', 'phoneNum', 'role']
        
        #generate authCode
        authCode=self.helperHandler.genAuthcode()
        try:
            dictOfUserAttrib = self.helperHandler.handleRequestAndAuth(request=request, keys=keys, formats=self.formats, hasAuth=False)
            pas=self.helperHandler.encrypt_password(dictOfUserAttrib["password"])
            dictOfUserAttrib["password"]=pas
            dictOfUserAttrib['authCode'] = authCode
            dictOfUserAttrib['authTime'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            dictOfUserAttrib['lastLogIn'] = "******"
            dictOfUserAttrib['authorized'] = "0"
            dictOfUserAttrib['beams_token'] = self.helperHandler.beams_auth(dictOfUserAttrib['email'])
            dictOfUserAttrib['points']="0"
            dictOfUserAttrib['reward_date']= "2021-01-01 01:01:01"
        except Exception as e:
            return json.dumps({"success" : False, "message" :str(e)})
        user = User()
        user.dictToUser(dictOfUserAttrib)
        res = self.userDao.insertUser(user)
        if(res[0] and "/secretAddUser" not in str(request)):
            self.helperHandler.sendEmail(dictOfUserAttrib['email'], dictOfUserAttrib['authCode'])
        return self.helperHandler.handleResponse(res)


    def updateUser(self, request, userDao):
        keys = ['email', 'firstName', 'lastName', 'middleName', 'phoneNum', 'auth_token']
        return self.userCRUDS(data=[request,keys], userDao=userDao, hasAuth=True, f=3)

    def deleteUser(self, request, userDao, hasAuth):
        keys = ['email']
        return self.userCRUDS(data=[request,keys], userDao=userDao, hasAuth=hasAuth, f=2)

    #f values 0->add 1->get 2->delete 3->update 4->getAll
    def userCRUDS(self, data, userDao, hasAuth, f):
        dictOfUserAttrib = None
        request = data[0]
        keys = data[1]
        formats=None
        t= "json"
        isSelectAll=False #remember if request is for select or selectAll
        if f == 1 or f==4:
            t= "args"
        if f==3:
            formats = self.formats
        if f==4:
            isSelectAll=True
        if hasAuth is True and "auth_token" not in keys:
            keys.append('auth_token')
        try:
            dictOfUserAttrib = self.helperHandler.handleRequestAndAuth(request=request, keys=keys, formats=formats, hasAuth=hasAuth, t=t)
            if(isSelectAll==True):
                res = self.userDao.selectAll()
                temp=[]
                for row in res[1]:
                    temp.append(row.userToDict())
                res = [True,temp]
                self.helperHandler.falseQueryCheck(res)
                return self.helperHandler.handleResponse(res)
            else:
                res = self.userDao.selectUser(dictOfUserAttrib["email"])
            self.helperHandler.falseQueryCheck(res)
        except Exception as e:
            return json.dumps({"success" : False, "message" : str(e)})
        res = self.sort(userDao, dictOfUserAttrib, f, res)
        return self.helperHandler.handleResponse(res)


    def sort(self, userDao, d, f, res):
        # get user from table to get missing fields
        user = res[1]
        # convert user obj to dict for simplicity
        UserDic = user.userToDict()
        #get the user from the auth table
        #tempUser = None
        if f == 1: #GET
            UserDic.update({'badges' : UserDic['points'] // 500})
            UserDic.update({'rewardCheck' : self.rewardEligible(UserDic)})
            res = [True, UserDic]
        elif f == 2: #DELETE: delete user and auth
            try:
                res = self.authDao.selectByEmail(d["email"])
                auth = res[1]
                self.authDao.deleteAuth(auth)
            except:
                pass
            self.userDao.deleteUser(user)
            dic = user.userToDict()
            res = [True, dic]
        elif f == 3: #UPDATE: update dic, convert to user, and update user table
            for key in d:
                UserDic[key] = d[key]
            user.dictToUser(UserDic)
            self.userDao.updateUser(user)
            res = [True, UserDic]
        return res
    
    def rewardEligible(self, UserDic):
        f='%Y-%m-%d %H:%M:%S'
        rewardTime = UserDic['reward_date']
        if rewardTime == "2021-01-01 01:01:01":
            return False
        authtimets=datetime.strptime(rewardTime, f)
        timepassed=datetime.now()-authtimets
        if (timepassed.total_seconds() / 3600) > 120:
            return False
        else:
            return True

    def changePassword(self, request, userDao):
        userDic = None
        if "/forgetPassword" in str (request):
            keys=['email','newPass', 'auth_token']
        else:
            keys = ['email', 'oldPass', 'newPass', 'auth_token']
        try:
            if "/forgetPassword" in str (request):
                userDic = self.helperHandler.handleRequestAndAuth(request=request, keys=keys,hasAuth=False) 
            else:
                userDic = self.helperHandler.handleRequestAndAuth(request=request, keys=keys) 
            newPass=self.helperHandler.encrypt_password(userDic["newPass"]) #hash new password
            res = self.userDao.selectUser(userDic['email'])
            self.helperHandler.falseQueryCheck(res)
            user = res[1]
            userAttrib = user.userToDict()
            if "/changePassword" in str (request):
                if not self.helperHandler.check_encrypted_password(userDic['oldPass'], userAttrib['password']):
                    raise Exception("Incorrect password")#check if password is correct
        except Exception as e:
            return json.dumps({"success" : False, "message" :str(e)}) 
        userAttrib['password'] = newPass #set newPass as user Password
        user.dictToUser(userAttrib)
        res = self.userDao.updateUser(user) #Convert to object and update the database
        return self.helperHandler.handleResponse(res)

    def claimReward(self, request, userDao):
        UserDic = None
        keys = ['email', 'auth_token']
        try:
            UserDic = self.helperHandler.handleRequestAndAuth(request = request, keys = keys)
            res = self.userDao.selectUser(UserDic['email'])
            self.helperHandler.falseQueryCheck(res)
        except Exception as e:
            return json.dumps({"success" : False, "message" :str(e)})
        user = res[1]
        UserDic = user.userToDict()
        UserDic['reward_date']= "2021-01-01 01:01:01"
        user.dictToUser(UserDic)
        res = self.userDao.updateUser(user)
        if res[0] == False:
            return json.dumps({"success" : False, "message" :str(e)})
        else:
            return self.helperHandler.handleResponse(res)