#author Erik R FRitts
#September 10,2014
#code is a class based on a Jython/Python implementation of
#Inductive Automation Ignition API for the purpose of controlling
#concurrent use and access to a project from another project

class AuthUser:
    
    ##############################################################
    #btnState function tells the single button of the authorization window when to change states
    #in this case Akuma(the event object) is a password text box set to visible so it can gain focus
    #but it is very small so it can't be read and hidden behind another object in the z-index
    
    def btnState(self, window):
        window = system.gui.getWindow(window)
        door = system.gui.getWindow('prmtrLgIn')
        chunli = door.rootContainer.getComponent('btnVldtUsr')
        ryu = window.rootContainer.getComponent('Akuma')
        if ryu.text=="":
            chunli.foreground = system.gui.color(0, 0, 0)
            chunli.background = system.gui.color(255, 255, 0)
            chunli.text = 'CANCEL'
        else:
            chunli.foreground = system.gui.color(255, 255, 255)
            chunli.background = system.gui.color(0, 255, 0)
            chunli.text = 'VALIDATE'
        return

    #####################################################################
    #cnclAuth function allows the user to return to normal operation and close
    #authorization window
    
    def cnclAuth(self, window):
        window = system.gui.getWindow(window)
        chunli = window.rootContainer.getComponent('btnVldtUsr')
        if chunli.text=="CANCEL":
            system.nav.closeWindow(window)
        return

    ######################################################################
    #usrAuth function compares event input with security protocols and then acts
    #appropriately. Actions include: Approve, Deny, Log Actions, Approve and Deny Concurrent Use, Give User Feedback
    
    def usrAuth(self, window):
        mbison = shared.AuthUser.AuthUser()
        key = '###' #I'm not showing you my key! The PcProx lets you configure inputs that it will automatically prepend or postpend to the data. You could make it quite complex.
        authRole = "Param" #I created an external DB role but an LDAP role would work as well
        tstamp = system.db.dateFormat(system.tag.read("[System]Client/System/CurrentDateTime").value, "yyyy-MM-dd HH:mm:ss")
        window = system.gui.getWindow(window)
        ryu = window.rootContainer.getComponent('Akuma')
        IdNoVldte = ryu.text[:3]
        IdNo = ryu.text[3:]
        if IdNoVldte==key:
            uname = system.db.runQuery("SELECT `username` FROM rfidacl_users WHERE `username` LIKE '_"+IdNo+"'")
            uname = system.dataset.toDataSet(uname)
            if uname.rowCount==0:
                system.gui.warningBox("Your access is denied! If you beleive this is an error please see a supervisor")
                system.db.runUpdateQuery("INSERT INTO rfidlogins (`datetime`, `rfidtag`, `action`, `cmnname`) VALUES ('"+tstamp+"', '"+IdNo+"', 'DENIED', 'unlisted user')")
                ryu.text = ""
                system.nav.closeWindow('prmtrLgIn')
            else:
                grtName = system.db.runQuery("SELECT `fname`,`lname` FROM rfidacl_users WHERE `username`='"+uname.getValueAt(0,0)+"'")
                grtName = system.dataset.toDataSet(grtName)
                gtrle = system.db.runQuery("SELECT `role_name` FROM rfidacl_roles INNER JOIN rfidacl_user_rl ON rfidacl_roles.id=rfidacl_user_rl.role_id INNER JOIN rfidacl_users ON rfidacl_user_rl.user_id=rfidacl_users.id WHERE `username`='"+uname.getValueAt(0,0)+"' AND `role_name`='"+authRole+"'")
                gtrle = system.dataset.toDataSet(gtrle)
                roles = str(gtrle.getValueAt(0,0))
                if roles==authRole:
                    system.gui.messageBox("Hello "+grtName.getValueAt(0,0)+", "+grtName.getValueAt(0,1),'Access Granted')
                    if window.name=='DIAGNOSTICS':
                        mbison.fullAuto()
                    tail = system.tag.read('[Client]clientWindow').value
                    if system.tag.read("NavTags/wrtLckLn"+tail[4:]).value == 0:
                        system.tag.write("NavTags/wrtLckLn"+tail[4:], 1)
                        mbison.loadRevolver()
                        system.db.runUpdateQuery("INSERT INTO rfidlogins (`datetime`, `rfidtag`, `action`, `cmnname`) VALUES ('"+tstamp+"', '"+IdNo+"', 'GRANTED', '"+grtName.getValueAt(0,0)+" "+grtName.getValueAt(0,1)+"')")
                        system.util.retarget("Parameters", "000.00.00.00:0000/main", {}, ["PARAMS"])
                    else:
                        system.gui.messageBox("The resources you requested are currently in use by another user. Please try again later", 'Request Impossible At This Time')
                ryu.text = ""
                system.nav.closeWindow('prmtrLgIn')
        else: #if someone got into a panel box we don't want them plugging in a keyboard and hacking away hence the key
            system.gui.warningBox("Your access is denied! ATTEMPTED ACCESS WITH UNAUTHORIZED INPUT DEVICE DETECTED!")
            system.db.runUpdateQuery("INSERT INTO rfidlogins (`datetime`, `rfidtag`, `action`, `cmnname`) VALUES ('"+tstamp+"', '"+ryu.text[:25]+"', 'ATTMPTD RDR BYPSS', 'unlisted user')")
            ryu.text = ""
            system.nav.closeWindow('prmtrLgIn')
        return
            
    
    ##########################################################################
#following functions are helpers to keep track of open pages and prevent concurrent use of individual pages

    def tattleTail(self, window):
        window = system.gui.getWindow(window)
        x = window.rootContainer.getComponent("lblTattleTail")
        y = system.tag.read('[Client]clientWindow').value
        x.text = y[4:]
        return
    
    ###########################################################################
    
    def dischargeRevolver(self):
        x = system.tag.read('NavTags/revolver').value
        system.tag.write('[Client]clientWindow', x)
        return
    
    ###########################################################################
    
    def loadRevolver(self):
        x = system.tag.read('[Client]clientWindow').value
        system.tag.write('NavTags/revolver', x)
        return
    
    ##########################################################################
    
    def fullAuto(self):
        window = system.gui.getWindow('DIAGNOSTICS')
        page = window.rootContainer.getComponent('lblDgnstcTtl').text
        if page[6:-14]>='25' and page[6:-14]<='29':
            system.tag.write('[Client]clientWindow', 'MAINthis')
        elif page[6:-14]>='30' and page[6:-14]<='34':
            system.tag.write('[Client]clientWindow', 'MAINthat')
        elif page[6:-14]>='35' and page[6:-14]<='39':
            system.tag.write('[Client]clientWindow', 'MAINother')
        return


