Update syntax and improve importations
This commit is contained in:
parent
83fcd383b7
commit
e9246bb376
163
.gitignore
vendored
163
.gitignore
vendored
@ -1,2 +1,163 @@
|
|||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
Server/.env
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
||||||
|
.pdm.toml
|
||||||
|
.pdm-python
|
||||||
|
.pdm-build/
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
Server/Program/env.py
|
||||||
|
|||||||
@ -7,10 +7,10 @@ from mfrc522 import MFRC522
|
|||||||
from ssd1306 import SSD1306_I2C
|
from ssd1306 import SSD1306_I2C
|
||||||
|
|
||||||
# Global variables
|
# Global variables
|
||||||
DOOR_ID = '[Your door ID]'
|
DOOR_ID = "[Your door ID]"
|
||||||
WLAN_SSID = '[Your SSID]'
|
WLAN_SSID = "[Your SSID]"
|
||||||
WLAN_PASS = '[Your password]'
|
WLAN_PASS = "[Your password]"
|
||||||
SERVER_IP = '[Your server IP]'
|
SERVER_IP = "[Your server IP]"
|
||||||
SERVER_PORT = 5000
|
SERVER_PORT = 5000
|
||||||
|
|
||||||
# Initialize RFID reader
|
# Initialize RFID reader
|
||||||
@ -31,23 +31,26 @@ redled.on()
|
|||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
redled.off()
|
redled.off()
|
||||||
|
|
||||||
|
|
||||||
def init_oled():
|
def init_oled():
|
||||||
global oled
|
global oled
|
||||||
try:
|
try:
|
||||||
oled = SSD1306_I2C(128, 64, i2c)
|
oled = SSD1306_I2C(128, 64, i2c)
|
||||||
oled.fill(0)
|
oled.fill(0)
|
||||||
oled.text('Initializing...', 0, 0)
|
oled.text("Initializing...", 0, 0)
|
||||||
oled.show()
|
oled.show()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("display error:", e)
|
print("display error:", e)
|
||||||
# init_oled()
|
# init_oled()
|
||||||
|
|
||||||
|
|
||||||
def display_message(message, ip_address):
|
def display_message(message, ip_address):
|
||||||
try:
|
try:
|
||||||
oled.fill(0)
|
oled.fill(0)
|
||||||
oled.text(f'Door ID: {DOOR_ID}', 0, 0) # Display Door ID at the top
|
oled.text(f"Door ID: {DOOR_ID}", 0, 0) # Display Door ID at the top
|
||||||
oled.text("___________________", 0, 3)
|
oled.text("___________________", 0, 3)
|
||||||
|
|
||||||
lines = message.split('\n')
|
lines = message.split("\n")
|
||||||
for i, line in enumerate(lines):
|
for i, line in enumerate(lines):
|
||||||
oled.text(line, 0, 20 + i * 10) # Adjust the y position for each line
|
oled.text(line, 0, 20 + i * 10) # Adjust the y position for each line
|
||||||
oled.text("__________________", 0, 47)
|
oled.text("__________________", 0, 47)
|
||||||
@ -59,6 +62,7 @@ def display_message(message, ip_address):
|
|||||||
print("display error:", e)
|
print("display error:", e)
|
||||||
init_oled()
|
init_oled()
|
||||||
|
|
||||||
|
|
||||||
# Connect to WiFi
|
# Connect to WiFi
|
||||||
def connect_wifi(ssid, password):
|
def connect_wifi(ssid, password):
|
||||||
wlan = network.WLAN(network.STA_IF)
|
wlan = network.WLAN(network.STA_IF)
|
||||||
@ -69,7 +73,7 @@ def connect_wifi(ssid, password):
|
|||||||
print("Connecting to WiFi...")
|
print("Connecting to WiFi...")
|
||||||
ip_address = wlan.ifconfig()[0]
|
ip_address = wlan.ifconfig()[0]
|
||||||
print("Connected to WiFi:", ip_address)
|
print("Connected to WiFi:", ip_address)
|
||||||
display_message('WiFi Connected', ip_address)
|
display_message("WiFi Connected", ip_address)
|
||||||
|
|
||||||
# Test connection to the server
|
# Test connection to the server
|
||||||
|
|
||||||
@ -77,20 +81,22 @@ def connect_wifi(ssid, password):
|
|||||||
response = requests.get(f"http://{SERVER_IP}:{SERVER_PORT}/")
|
response = requests.get(f"http://{SERVER_IP}:{SERVER_PORT}/")
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
print("Server connection successful")
|
print("Server connection successful")
|
||||||
display_message('Server Connected', ip_address)
|
display_message("Server Connected", ip_address)
|
||||||
else:
|
else:
|
||||||
print("Server connection failed")
|
print("Server connection failed")
|
||||||
display_message('Server Fail', ip_address)
|
display_message("Server Fail", ip_address)
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
while response.status_code != 200:
|
while response.status_code != 200:
|
||||||
wlan.connect(ssid, password)
|
wlan.connect(ssid, password)
|
||||||
response = requests.get(f"http://{SERVER_IP}:{SERVER_PORT}/")
|
response = requests.get(f"http://{SERVER_IP}:{SERVER_PORT}/")
|
||||||
display_message('Reconnecting ...', ip_address)
|
display_message("Reconnecting ...", ip_address)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Server connection error:", e)
|
print("Server connection error:", e)
|
||||||
display_message(f'Server Error \n {e}', ip_address)
|
display_message(f"Server Error \n {e}", ip_address)
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
|
|
||||||
# while response.status_code != 200 :
|
# while response.status_code != 200 :
|
||||||
# wlan.connect(ssid, password)
|
# wlan.connect(ssid, password)
|
||||||
# try :
|
# try :
|
||||||
@ -102,14 +108,12 @@ def connect_wifi(ssid, password):
|
|||||||
# Function to send RFID UID to the server
|
# Function to send RFID UID to the server
|
||||||
def send_rfid_to_server(rfid_uid):
|
def send_rfid_to_server(rfid_uid):
|
||||||
url = f"http://{SERVER_IP}:{SERVER_PORT}/access"
|
url = f"http://{SERVER_IP}:{SERVER_PORT}/access"
|
||||||
headers = {'Content-Type': 'application/json'}
|
headers = {"Content-Type": "application/json"}
|
||||||
data = {
|
data = {"rfid_uid": rfid_uid, "door_id": DOOR_ID}
|
||||||
'rfid_uid': rfid_uid,
|
|
||||||
'door_id': DOOR_ID
|
|
||||||
}
|
|
||||||
response = requests.post(url, headers=headers, data=json.dumps(data))
|
response = requests.post(url, headers=headers, data=json.dumps(data))
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
# Main loop to scan RFID tags
|
# Main loop to scan RFID tags
|
||||||
def main():
|
def main():
|
||||||
# Retry mechanism for OLED initialization
|
# Retry mechanism for OLED initialization
|
||||||
@ -123,36 +127,36 @@ def main():
|
|||||||
|
|
||||||
connect_wifi(WLAN_SSID, WLAN_PASS)
|
connect_wifi(WLAN_SSID, WLAN_PASS)
|
||||||
ip_address = network.WLAN(network.STA_IF).ifconfig()[0]
|
ip_address = network.WLAN(network.STA_IF).ifconfig()[0]
|
||||||
display_message('Scan your tag', ip_address)
|
display_message("Scan your tag", ip_address)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
(status, tag_type) = reader.request(reader.REQIDL)
|
(status, tag_type) = reader.request(reader.REQIDL)
|
||||||
if status == reader.OK:
|
if status == reader.OK:
|
||||||
(status, uid) = reader.SelectTagSN()
|
(status, uid) = reader.SelectTagSN()
|
||||||
if status == reader.OK:
|
if status == reader.OK:
|
||||||
rfid_uid_decimal = ''.join([str(i) for i in uid])
|
rfid_uid_decimal = "".join([str(i) for i in uid])
|
||||||
print("RFID UID:", rfid_uid_decimal)
|
print("RFID UID:", rfid_uid_decimal)
|
||||||
display_message('Checking...', ip_address)
|
display_message("Checking...", ip_address)
|
||||||
|
|
||||||
response = send_rfid_to_server(rfid_uid_decimal)
|
response = send_rfid_to_server(rfid_uid_decimal)
|
||||||
|
|
||||||
if response.get('access_granted'):
|
if response.get("access_granted"):
|
||||||
user_upn = response.get('upn')
|
user_upn = response.get("upn")
|
||||||
print("Access Granted:", user_upn)
|
print("Access Granted:", user_upn)
|
||||||
display_message(f'Access Granted\n{user_upn}', ip_address)
|
display_message(f"Access Granted\n{user_upn}", ip_address)
|
||||||
# Turn on the LED to indicate door open
|
# Turn on the LED to indicate door open
|
||||||
greenled.on()
|
greenled.on()
|
||||||
# Add code here to open the door (e.g., trigger a relay)
|
# Add code here to open the door (e.g., trigger a relay)
|
||||||
else:
|
else:
|
||||||
print("Access Denied")
|
print("Access Denied")
|
||||||
display_message('Access Denied', ip_address)
|
display_message("Access Denied", ip_address)
|
||||||
redled.on()
|
redled.on()
|
||||||
|
|
||||||
time.sleep(2) # Delay to avoid rapid repeated reads
|
time.sleep(2) # Delay to avoid rapid repeated reads
|
||||||
greenled.off()
|
greenled.off()
|
||||||
redled.off() # Turn off the LED
|
redled.off() # Turn off the LED
|
||||||
display_message('Scan your tag', ip_address)
|
display_message("Scan your tag", ip_address)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@ -3,7 +3,6 @@ from os import uname
|
|||||||
|
|
||||||
|
|
||||||
class MFRC522:
|
class MFRC522:
|
||||||
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
OK = 0
|
OK = 0
|
||||||
NOTAGERR = 1
|
NOTAGERR = 1
|
||||||
@ -18,9 +17,7 @@ class MFRC522:
|
|||||||
PICC_ANTICOLL2 = 0x95
|
PICC_ANTICOLL2 = 0x95
|
||||||
PICC_ANTICOLL3 = 0x97
|
PICC_ANTICOLL3 = 0x97
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, sck, mosi, miso, rst, cs, baudrate=1000000, spi_id=0):
|
def __init__(self, sck, mosi, miso, rst, cs, baudrate=1000000, spi_id=0):
|
||||||
|
|
||||||
self.sck = Pin(sck, Pin.OUT)
|
self.sck = Pin(sck, Pin.OUT)
|
||||||
self.mosi = Pin(mosi, Pin.OUT)
|
self.mosi = Pin(mosi, Pin.OUT)
|
||||||
self.miso = Pin(miso)
|
self.miso = Pin(miso)
|
||||||
@ -32,14 +29,25 @@ class MFRC522:
|
|||||||
|
|
||||||
board = uname()[0]
|
board = uname()[0]
|
||||||
|
|
||||||
if board == 'WiPy' or board == 'LoPy' or board == 'FiPy':
|
if board == "WiPy" or board == "LoPy" or board == "FiPy":
|
||||||
self.spi = SPI(0)
|
self.spi = SPI(0)
|
||||||
self.spi.init(SPI.MASTER, baudrate=1000000, pins=(self.sck, self.mosi, self.miso))
|
self.spi.init(
|
||||||
elif (board == 'esp8266') or (board == 'esp32'):
|
SPI.MASTER, baudrate=1000000, pins=(self.sck, self.mosi, self.miso)
|
||||||
self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso)
|
)
|
||||||
|
elif (board == "esp8266") or (board == "esp32"):
|
||||||
|
self.spi = SPI(
|
||||||
|
baudrate=100000,
|
||||||
|
polarity=0,
|
||||||
|
phase=0,
|
||||||
|
sck=self.sck,
|
||||||
|
mosi=self.mosi,
|
||||||
|
miso=self.miso,
|
||||||
|
)
|
||||||
self.spi.init()
|
self.spi.init()
|
||||||
elif board == 'rp2':
|
elif board == "rp2":
|
||||||
self.spi = SPI(spi_id,baudrate=baudrate,sck=self.sck, mosi= self.mosi, miso= self.miso)
|
self.spi = SPI(
|
||||||
|
spi_id, baudrate=baudrate, sck=self.sck, mosi=self.mosi, miso=self.miso
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unsupported platform")
|
raise RuntimeError("Unsupported platform")
|
||||||
|
|
||||||
@ -47,16 +55,14 @@ class MFRC522:
|
|||||||
self.init()
|
self.init()
|
||||||
|
|
||||||
def _wreg(self, reg, val):
|
def _wreg(self, reg, val):
|
||||||
|
|
||||||
self.cs.value(0)
|
self.cs.value(0)
|
||||||
self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e)))
|
self.spi.write(b"%c" % int(0xFF & ((reg << 1) & 0x7E)))
|
||||||
self.spi.write(b'%c' % int(0xff & val))
|
self.spi.write(b"%c" % int(0xFF & val))
|
||||||
self.cs.value(1)
|
self.cs.value(1)
|
||||||
|
|
||||||
def _rreg(self, reg):
|
def _rreg(self, reg):
|
||||||
|
|
||||||
self.cs.value(0)
|
self.cs.value(0)
|
||||||
self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
|
self.spi.write(b"%c" % int(0xFF & (((reg << 1) & 0x7E) | 0x80)))
|
||||||
val = self.spi.read(1)
|
val = self.spi.read(1)
|
||||||
self.cs.value(1)
|
self.cs.value(1)
|
||||||
|
|
||||||
@ -69,7 +75,6 @@ class MFRC522:
|
|||||||
self._wreg(reg, self._rreg(reg) & (~mask))
|
self._wreg(reg, self._rreg(reg) & (~mask))
|
||||||
|
|
||||||
def _tocard(self, cmd, send):
|
def _tocard(self, cmd, send):
|
||||||
|
|
||||||
recv = []
|
recv = []
|
||||||
bits = irq_en = wait_irq = n = 0
|
bits = irq_en = wait_irq = n = 0
|
||||||
stat = self.ERR
|
stat = self.ERR
|
||||||
@ -129,7 +134,6 @@ class MFRC522:
|
|||||||
return stat, recv, bits
|
return stat, recv, bits
|
||||||
|
|
||||||
def _crc(self, data):
|
def _crc(self, data):
|
||||||
|
|
||||||
self._cflags(0x05, 0x04)
|
self._cflags(0x05, 0x04)
|
||||||
self._sflags(0x0A, 0x80)
|
self._sflags(0x0A, 0x80)
|
||||||
|
|
||||||
@ -148,7 +152,6 @@ class MFRC522:
|
|||||||
return [self._rreg(0x22), self._rreg(0x21)]
|
return [self._rreg(0x22), self._rreg(0x21)]
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
self._wreg(0x2A, 0x8D)
|
self._wreg(0x2A, 0x8D)
|
||||||
self._wreg(0x2B, 0x3E)
|
self._wreg(0x2B, 0x3E)
|
||||||
@ -162,14 +165,12 @@ class MFRC522:
|
|||||||
self._wreg(0x01, 0x0F)
|
self._wreg(0x01, 0x0F)
|
||||||
|
|
||||||
def antenna_on(self, on=True):
|
def antenna_on(self, on=True):
|
||||||
|
|
||||||
if on and ~(self._rreg(0x14) & 0x03):
|
if on and ~(self._rreg(0x14) & 0x03):
|
||||||
self._sflags(0x14, 0x03)
|
self._sflags(0x14, 0x03)
|
||||||
else:
|
else:
|
||||||
self._cflags(0x14, 0x03)
|
self._cflags(0x14, 0x03)
|
||||||
|
|
||||||
def request(self, mode):
|
def request(self, mode):
|
||||||
|
|
||||||
self._wreg(0x0D, 0x07)
|
self._wreg(0x0D, 0x07)
|
||||||
(stat, recv, bits) = self._tocard(0x0C, [mode])
|
(stat, recv, bits) = self._tocard(0x0C, [mode])
|
||||||
|
|
||||||
@ -179,7 +180,6 @@ class MFRC522:
|
|||||||
return stat, bits
|
return stat, bits
|
||||||
|
|
||||||
def anticoll(self, anticolN):
|
def anticoll(self, anticolN):
|
||||||
|
|
||||||
ser_chk = 0
|
ser_chk = 0
|
||||||
ser = [anticolN, 0x20]
|
ser = [anticolN, 0x20]
|
||||||
|
|
||||||
@ -197,7 +197,6 @@ class MFRC522:
|
|||||||
|
|
||||||
return stat, recv
|
return stat, recv
|
||||||
|
|
||||||
|
|
||||||
def PcdSelect(self, serNum, anticolN):
|
def PcdSelect(self, serNum, anticolN):
|
||||||
backData = []
|
backData = []
|
||||||
buf = []
|
buf = []
|
||||||
@ -219,7 +218,6 @@ class MFRC522:
|
|||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def SelectTag(self, uid):
|
def SelectTag(self, uid):
|
||||||
byte5 = 0
|
byte5 = 0
|
||||||
|
|
||||||
@ -242,9 +240,6 @@ class MFRC522:
|
|||||||
s = s + "]"
|
s = s + "]"
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def SelectTagSN(self):
|
def SelectTagSN(self):
|
||||||
valid_uid = []
|
valid_uid = []
|
||||||
(status, uid) = self.anticoll(self.PICC_ANTICOLL1)
|
(status, uid) = self.anticoll(self.PICC_ANTICOLL1)
|
||||||
@ -252,10 +247,12 @@ class MFRC522:
|
|||||||
if status != self.OK:
|
if status != self.OK:
|
||||||
return (self.ERR, [])
|
return (self.ERR, [])
|
||||||
|
|
||||||
if self.DEBUG: print("anticol(1) {}".format(uid))
|
if self.DEBUG:
|
||||||
|
print("anticol(1) {}".format(uid))
|
||||||
if self.PcdSelect(uid, self.PICC_ANTICOLL1) == 0:
|
if self.PcdSelect(uid, self.PICC_ANTICOLL1) == 0:
|
||||||
return (self.ERR, [])
|
return (self.ERR, [])
|
||||||
if self.DEBUG: print("pcdSelect(1) {}".format(uid))
|
if self.DEBUG:
|
||||||
|
print("pcdSelect(1) {}".format(uid))
|
||||||
|
|
||||||
# check if first byte is 0x88
|
# check if first byte is 0x88
|
||||||
if uid[0] == 0x88:
|
if uid[0] == 0x88:
|
||||||
@ -265,12 +262,15 @@ class MFRC522:
|
|||||||
# print("Select Tag 2:",self.tohexstring(uid))
|
# print("Select Tag 2:",self.tohexstring(uid))
|
||||||
if status != self.OK:
|
if status != self.OK:
|
||||||
return (self.ERR, [])
|
return (self.ERR, [])
|
||||||
if self.DEBUG: print("Anticol(2) {}".format(uid))
|
if self.DEBUG:
|
||||||
|
print("Anticol(2) {}".format(uid))
|
||||||
rtn = self.PcdSelect(uid, self.PICC_ANTICOLL2)
|
rtn = self.PcdSelect(uid, self.PICC_ANTICOLL2)
|
||||||
if self.DEBUG: print("pcdSelect(2) return={} uid={}".format(rtn,uid))
|
if self.DEBUG:
|
||||||
|
print("pcdSelect(2) return={} uid={}".format(rtn, uid))
|
||||||
if rtn == 0:
|
if rtn == 0:
|
||||||
return (self.ERR, [])
|
return (self.ERR, [])
|
||||||
if self.DEBUG: print("PcdSelect2() {}".format(uid))
|
if self.DEBUG:
|
||||||
|
print("PcdSelect2() {}".format(uid))
|
||||||
# now check again if uid[0] is 0x88
|
# now check again if uid[0] is 0x88
|
||||||
if uid[0] == 0x88:
|
if uid[0] == 0x88:
|
||||||
valid_uid.extend(uid[1:4])
|
valid_uid.extend(uid[1:4])
|
||||||
@ -278,10 +278,12 @@ class MFRC522:
|
|||||||
# print("Select Tag 3:",self.tohexstring(uid))
|
# print("Select Tag 3:",self.tohexstring(uid))
|
||||||
if status != self.OK:
|
if status != self.OK:
|
||||||
return (self.ERR, [])
|
return (self.ERR, [])
|
||||||
if self.DEBUG: print("Anticol(3) {}".format(uid))
|
if self.DEBUG:
|
||||||
|
print("Anticol(3) {}".format(uid))
|
||||||
if self.MFRC522_PcdSelect(uid, self.PICC_ANTICOLL3) == 0:
|
if self.MFRC522_PcdSelect(uid, self.PICC_ANTICOLL3) == 0:
|
||||||
return (self.ERR, [])
|
return (self.ERR, [])
|
||||||
if self.DEBUG: print("PcdSelect(3) {}".format(uid))
|
if self.DEBUG:
|
||||||
|
print("PcdSelect(3) {}".format(uid))
|
||||||
valid_uid.extend(uid[0:5])
|
valid_uid.extend(uid[0:5])
|
||||||
# if we are here than the uid is ok
|
# if we are here than the uid is ok
|
||||||
# let's remove the last BYTE whic is the XOR sum
|
# let's remove the last BYTE whic is the XOR sum
|
||||||
@ -289,11 +291,6 @@ class MFRC522:
|
|||||||
return (self.OK, valid_uid[: len(valid_uid) - 1])
|
return (self.OK, valid_uid[: len(valid_uid) - 1])
|
||||||
# return (self.OK , valid_uid)
|
# return (self.OK , valid_uid)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def auth(self, mode, addr, sect, ser):
|
def auth(self, mode, addr, sect, ser):
|
||||||
return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]
|
return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]
|
||||||
|
|
||||||
@ -305,19 +302,16 @@ class MFRC522:
|
|||||||
status = self.auth(self.AUTHENT1B, addr, keyB, uid)
|
status = self.auth(self.AUTHENT1B, addr, keyB, uid)
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|
||||||
def stop_crypto1(self):
|
def stop_crypto1(self):
|
||||||
self._cflags(0x08, 0x08)
|
self._cflags(0x08, 0x08)
|
||||||
|
|
||||||
def read(self, addr):
|
def read(self, addr):
|
||||||
|
|
||||||
data = [0x30, addr]
|
data = [0x30, addr]
|
||||||
data += self._crc(data)
|
data += self._crc(data)
|
||||||
(stat, recv, _) = self._tocard(0x0C, data)
|
(stat, recv, _) = self._tocard(0x0C, data)
|
||||||
return stat, recv
|
return stat, recv
|
||||||
|
|
||||||
def write(self, addr, data):
|
def write(self, addr, data):
|
||||||
|
|
||||||
buf = [0xA0, addr]
|
buf = [0xA0, addr]
|
||||||
buf += self._crc(buf)
|
buf += self._crc(buf)
|
||||||
(stat, recv, bits) = self._tocard(0x0C, buf)
|
(stat, recv, bits) = self._tocard(0x0C, buf)
|
||||||
@ -330,11 +324,14 @@ class MFRC522:
|
|||||||
buf.append(data[i])
|
buf.append(data[i])
|
||||||
buf += self._crc(buf)
|
buf += self._crc(buf)
|
||||||
(stat, recv, bits) = self._tocard(0x0C, buf)
|
(stat, recv, bits) = self._tocard(0x0C, buf)
|
||||||
if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
|
if (
|
||||||
|
not (stat == self.OK)
|
||||||
|
or not (bits == 4)
|
||||||
|
or not ((recv[0] & 0x0F) == 0x0A)
|
||||||
|
):
|
||||||
stat = self.ERR
|
stat = self.ERR
|
||||||
return stat
|
return stat
|
||||||
|
|
||||||
|
|
||||||
def writeSectorBlock(self, uid, sector, block, data, keyA=None, keyB=None):
|
def writeSectorBlock(self, uid, sector, block, data, keyA=None, keyB=None):
|
||||||
absoluteBlock = sector * 4 + (block % 4)
|
absoluteBlock = sector * 4 + (block % 4)
|
||||||
if absoluteBlock > 63:
|
if absoluteBlock > 63:
|
||||||
@ -357,7 +354,12 @@ class MFRC522:
|
|||||||
for absoluteBlock in range(Start, End):
|
for absoluteBlock in range(Start, End):
|
||||||
status = self.authKeys(uid, absoluteBlock, keyA, keyB)
|
status = self.authKeys(uid, absoluteBlock, keyA, keyB)
|
||||||
# Check if authenticated
|
# Check if authenticated
|
||||||
print("{:02d} S{:02d} B{:1d}: ".format(absoluteBlock, absoluteBlock//4 , absoluteBlock % 4),end="")
|
print(
|
||||||
|
"{:02d} S{:02d} B{:1d}: ".format(
|
||||||
|
absoluteBlock, absoluteBlock // 4, absoluteBlock % 4
|
||||||
|
),
|
||||||
|
end="",
|
||||||
|
)
|
||||||
if status == self.OK:
|
if status == self.OK:
|
||||||
status, block = self.read(absoluteBlock)
|
status, block = self.read(absoluteBlock)
|
||||||
if status == self.ERR:
|
if status == self.ERR:
|
||||||
@ -367,10 +369,10 @@ class MFRC522:
|
|||||||
print("{:02X} ".format(value), end="")
|
print("{:02X} ".format(value), end="")
|
||||||
print(" ", end="")
|
print(" ", end="")
|
||||||
for value in block:
|
for value in block:
|
||||||
if (value > 0x20) and (value < 0x7f):
|
if (value > 0x20) and (value < 0x7F):
|
||||||
print(chr(value), end="")
|
print(chr(value), end="")
|
||||||
else:
|
else:
|
||||||
print('.',end="")
|
print(".", end="")
|
||||||
print("")
|
print("")
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|||||||
@ -1,32 +1,47 @@
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
from flask import Flask, render_template, send_file, Response, request, redirect, jsonify
|
from flask import (
|
||||||
|
Flask,
|
||||||
|
render_template,
|
||||||
|
send_file,
|
||||||
|
Response,
|
||||||
|
request,
|
||||||
|
redirect,
|
||||||
|
jsonify,
|
||||||
|
)
|
||||||
import io
|
import io
|
||||||
from ldapSync import sync_ldap_to_database
|
from ldapSync import sync_ldap_to_database
|
||||||
from database import *
|
from database import (WebServerPORT, add_door_to_database, check_access, delete_group_from_database,
|
||||||
from env import *
|
get_doors, get_existing_groups, get_latest_logs, get_logs, get_users,
|
||||||
|
log_access_attempt)
|
||||||
|
from env import DBFILE
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
# Route to the home
|
# Route to the home
|
||||||
@app.route('/')
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
existing_groups = get_existing_groups(DBFILE) # Update with your database file path
|
existing_groups = get_existing_groups(DBFILE) # Update with your database file path
|
||||||
logs = get_latest_logs(DBFILE, 5)
|
logs = get_latest_logs(DBFILE, 5)
|
||||||
# print(logs[0])
|
# print(logs[0])
|
||||||
return render_template('./index.html', existing_groups=existing_groups, logs=logs)
|
return render_template("./index.html", existing_groups=existing_groups, logs=logs)
|
||||||
|
|
||||||
|
|
||||||
# Route to display the fuser db
|
# Route to display the fuser db
|
||||||
@app.route('/UserDB')
|
@app.route("/UserDB")
|
||||||
def usersdb():
|
def usersdb():
|
||||||
users = get_users()
|
users = get_users()
|
||||||
return render_template('userdb.html', users=users)
|
return render_template("userdb.html", users=users)
|
||||||
|
|
||||||
|
|
||||||
# Route to display the fuser db
|
# Route to display the fuser db
|
||||||
@app.route('/LogsDB')
|
@app.route("/LogsDB")
|
||||||
def logsdb():
|
def logsdb():
|
||||||
logs = get_logs()
|
logs = get_logs()
|
||||||
return render_template('logsdb.html', logs=logs)
|
return render_template("logsdb.html", logs=logs)
|
||||||
|
|
||||||
@app.route('/export_logs')
|
|
||||||
|
@app.route("/export_logs")
|
||||||
def export_logs():
|
def export_logs():
|
||||||
logs = get_logs()
|
logs = get_logs()
|
||||||
|
|
||||||
@ -45,21 +60,25 @@ def export_logs():
|
|||||||
return Response(
|
return Response(
|
||||||
log_output,
|
log_output,
|
||||||
mimetype="text/plain",
|
mimetype="text/plain",
|
||||||
headers={"Content-disposition": "attachment; filename=logs.csv"}
|
headers={"Content-disposition": "attachment; filename=logs.csv"},
|
||||||
)
|
)
|
||||||
|
|
||||||
@app.route('/GroupsDB')
|
|
||||||
|
@app.route("/GroupsDB")
|
||||||
def groupsdb():
|
def groupsdb():
|
||||||
doors = get_doors()
|
doors = get_doors()
|
||||||
groups = get_existing_groups(DBFILE)
|
groups = get_existing_groups(DBFILE)
|
||||||
return render_template('groupsdb.html', doors=doors, groups=groups)
|
return render_template("groupsdb.html", doors=doors, groups=groups)
|
||||||
|
|
||||||
@app.route('/delete_group/<group_cn>', methods=['POST'])
|
|
||||||
|
@app.route("/delete_group/<group_cn>", methods=["POST"])
|
||||||
def delete_group(group_cn):
|
def delete_group(group_cn):
|
||||||
delete_group_from_database(group_cn)
|
delete_group_from_database(group_cn)
|
||||||
return render_template('./index.html')
|
return render_template("./index.html")
|
||||||
|
|
||||||
|
|
||||||
# Route to handle form submission and add the door to the database
|
# Route to handle form submission and add the door to the database
|
||||||
@app.route('/add_door', methods=['POST'])
|
@app.route("/add_door", methods=["POST"])
|
||||||
def add_door():
|
def add_door():
|
||||||
Door_id = request.form["Door_id"]
|
Door_id = request.form["Door_id"]
|
||||||
group_cn = request.form["group_cn"]
|
group_cn = request.form["group_cn"]
|
||||||
@ -67,45 +86,49 @@ def add_door():
|
|||||||
# Update with your database file path
|
# Update with your database file path
|
||||||
exec = add_door_to_database(DBFILE, group_cn, Door_id)
|
exec = add_door_to_database(DBFILE, group_cn, Door_id)
|
||||||
if add_door_to_database(DBFILE, group_cn, Door_id):
|
if add_door_to_database(DBFILE, group_cn, Door_id):
|
||||||
return redirect('/')
|
return redirect("/")
|
||||||
else:
|
else:
|
||||||
return f"Failed to add door to the database."
|
return f"Failed to add door to the database."
|
||||||
|
|
||||||
|
|
||||||
# Route to handle sync button click
|
# Route to handle sync button click
|
||||||
@app.route('/sync')
|
@app.route("/sync")
|
||||||
def sync():
|
def sync():
|
||||||
sync_ldap_to_database(DBFILE)
|
sync_ldap_to_database(DBFILE)
|
||||||
return render_template('./LDAP.html')
|
return render_template("./LDAP.html")
|
||||||
|
|
||||||
|
|
||||||
# Route to handle door access requests
|
# Route to handle door access requests
|
||||||
@app.route('/access', methods=['POST'])
|
@app.route("/access", methods=["POST"])
|
||||||
def door_access():
|
def door_access():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
rfid_uid = data.get('rfid_uid')
|
rfid_uid = data.get("rfid_uid")
|
||||||
door_id = data.get('door_id')
|
door_id = data.get("door_id")
|
||||||
|
|
||||||
if rfid_uid is None or door_id is None:
|
if rfid_uid is None or door_id is None:
|
||||||
return jsonify({'error': 'RFID UID and door ID are required'}), 400
|
return jsonify({"error": "RFID UID and door ID are required"}), 400
|
||||||
|
|
||||||
access_granted, upn = check_access(rfid_uid, door_id)
|
access_granted, upn = check_access(rfid_uid, door_id)
|
||||||
if access_granted:
|
if access_granted:
|
||||||
print('')
|
print("")
|
||||||
log_access_attempt(DBFILE, upn, rfid_uid, True, door_id)
|
log_access_attempt(DBFILE, upn, rfid_uid, True, door_id)
|
||||||
return jsonify({'access_granted': True, 'upn': upn}), 200
|
return jsonify({"access_granted": True, "upn": upn}), 200
|
||||||
|
|
||||||
else:
|
else:
|
||||||
log_access_attempt(DBFILE, upn, rfid_uid, False, door_id)
|
log_access_attempt(DBFILE, upn, rfid_uid, False, door_id)
|
||||||
return jsonify({'access_granted': False}), 403
|
return jsonify({"access_granted": False}), 403
|
||||||
|
|
||||||
|
|
||||||
def run_flask_app():
|
def run_flask_app():
|
||||||
app.run(debug=True, use_reloader=False, port=5000, host="0.0.0.0")
|
app.run(debug=True, use_reloader=False, port=5000, host="0.0.0.0")
|
||||||
|
|
||||||
|
|
||||||
def run_webServer_thread():
|
def run_webServer_thread():
|
||||||
print(f'STARTING WEB SERVER ON PORT {WebServerPORT}')
|
print(f"STARTING WEB SERVER ON PORT {WebServerPORT}")
|
||||||
flask_thread = Thread(target=run_flask_app, daemon=True)
|
flask_thread = Thread(target=run_flask_app, daemon=True)
|
||||||
flask_thread.start()
|
flask_thread.start()
|
||||||
# flask_thread.join()
|
# flask_thread.join()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
|
|||||||
0
Server/Program/__init__.py
Normal file
0
Server/Program/__init__.py
Normal file
@ -1,34 +1,42 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from env import *
|
from env import DBFILE
|
||||||
|
|
||||||
|
|
||||||
# Function to check if a table exists in the database
|
# Function to check if a table exists in the database
|
||||||
def table_exists(cursor, table_name):
|
def table_exists(cursor, table_name):
|
||||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name=?", (table_name,))
|
cursor.execute(
|
||||||
|
"SELECT name FROM sqlite_master WHERE type='table' AND name=?", (table_name,)
|
||||||
|
)
|
||||||
return cursor.fetchone() is not None
|
return cursor.fetchone() is not None
|
||||||
|
|
||||||
|
|
||||||
# Function to create the Users table
|
# Function to create the Users table
|
||||||
def create_users_table(cursor):
|
def create_users_table(cursor):
|
||||||
cursor.execute('''CREATE TABLE Users (
|
cursor.execute("""CREATE TABLE Users (
|
||||||
upn TEXT PRIMARY KEY,
|
upn TEXT PRIMARY KEY,
|
||||||
rFIDUID TEXT,
|
rFIDUID TEXT,
|
||||||
MemberOf TEXT,
|
MemberOf TEXT,
|
||||||
FOREIGN KEY (MemberOf) REFERENCES Groups(cn)
|
FOREIGN KEY (MemberOf) REFERENCES Groups(cn)
|
||||||
)''')
|
)""")
|
||||||
|
|
||||||
|
|
||||||
# Function to create the Groups table
|
# Function to create the Groups table
|
||||||
def create_groups_table(cursor):
|
def create_groups_table(cursor):
|
||||||
cursor.execute('''CREATE TABLE Groups (
|
cursor.execute("""CREATE TABLE Groups (
|
||||||
cn TEXT PRIMARY KEY
|
cn TEXT PRIMARY KEY
|
||||||
)''')
|
)""")
|
||||||
|
|
||||||
|
|
||||||
# Function to create the Doors table
|
# Function to create the Doors table
|
||||||
def create_doors_table(cursor):
|
def create_doors_table(cursor):
|
||||||
cursor.execute('''CREATE TABLE Doors (
|
cursor.execute("""CREATE TABLE Doors (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
GroupCn TEXT,
|
GroupCn TEXT,
|
||||||
FOREIGN KEY (GroupCn) REFERENCES Groups(cn)
|
FOREIGN KEY (GroupCn) REFERENCES Groups(cn)
|
||||||
)''')
|
)""")
|
||||||
|
|
||||||
|
|
||||||
# Function to create the logs table
|
# Function to create the logs table
|
||||||
def create_logs_table(cursor):
|
def create_logs_table(cursor):
|
||||||
"""
|
"""
|
||||||
@ -36,7 +44,7 @@ def create_logs_table(cursor):
|
|||||||
|
|
||||||
:param db_file: The database file path.
|
:param db_file: The database file path.
|
||||||
"""
|
"""
|
||||||
cursor.execute('''
|
cursor.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS log (
|
CREATE TABLE IF NOT EXISTS log (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
timestamp TEXT ,
|
timestamp TEXT ,
|
||||||
@ -48,7 +56,9 @@ def create_logs_table(cursor):
|
|||||||
FOREIGN KEY (user) REFERENCES Users (upn)
|
FOREIGN KEY (user) REFERENCES Users (upn)
|
||||||
FOREIGN KEY (rFIDUID) REFERENCES Users (rFIDUID)
|
FOREIGN KEY (rFIDUID) REFERENCES Users (rFIDUID)
|
||||||
)
|
)
|
||||||
''')
|
""")
|
||||||
|
|
||||||
|
|
||||||
# Function to setup the database
|
# Function to setup the database
|
||||||
def setup_database(db_file):
|
def setup_database(db_file):
|
||||||
# Connect to the SQLite database
|
# Connect to the SQLite database
|
||||||
@ -85,6 +95,7 @@ def setup_database(db_file):
|
|||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
def log_access_attempt(db_file, user, rFIDUID, granted, doorID):
|
def log_access_attempt(db_file, user, rFIDUID, granted, doorID):
|
||||||
"""
|
"""
|
||||||
Log an access attempt to the log table.
|
Log an access attempt to the log table.
|
||||||
@ -98,14 +109,18 @@ def log_access_attempt(db_file, user, rFIDUID, granted, doorID):
|
|||||||
conn = sqlite3.connect(db_file)
|
conn = sqlite3.connect(db_file)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
print(f"[{datetime.now()}] User {user} get granted : {granted} on door : {doorID}")
|
||||||
print(f'[{datetime.now()}] User {user} get granted : {granted} on door : {doorID}')
|
cursor.execute(
|
||||||
cursor.execute('''
|
"""
|
||||||
INSERT INTO log (timestamp, user, rFIDUID, granted, door_id) VALUES (?, ?, ?, ?, ?)
|
INSERT INTO log (timestamp, user, rFIDUID, granted, door_id) VALUES (?, ?, ?, ?, ?)
|
||||||
''', (datetime.now(), user, rFIDUID, granted, doorID))
|
""",
|
||||||
|
(datetime.now(), user, rFIDUID, granted, doorID),
|
||||||
|
)
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
def print_users_table(cursor):
|
def print_users_table(cursor):
|
||||||
cursor.execute("SELECT * FROM Users")
|
cursor.execute("SELECT * FROM Users")
|
||||||
rows = cursor.fetchall()
|
rows = cursor.fetchall()
|
||||||
@ -113,6 +128,7 @@ def print_users_table(cursor):
|
|||||||
for row in rows:
|
for row in rows:
|
||||||
print(row)
|
print(row)
|
||||||
|
|
||||||
|
|
||||||
# Function to print the content of the Groups table
|
# Function to print the content of the Groups table
|
||||||
def print_groups_table(cursor):
|
def print_groups_table(cursor):
|
||||||
cursor.execute("SELECT * FROM Groups")
|
cursor.execute("SELECT * FROM Groups")
|
||||||
@ -121,6 +137,7 @@ def print_groups_table(cursor):
|
|||||||
for row in rows:
|
for row in rows:
|
||||||
print(row)
|
print(row)
|
||||||
|
|
||||||
|
|
||||||
# Function to print the content of the Doors table
|
# Function to print the content of the Doors table
|
||||||
def print_doors_table(cursor):
|
def print_doors_table(cursor):
|
||||||
cursor.execute("SELECT * FROM Doors")
|
cursor.execute("SELECT * FROM Doors")
|
||||||
@ -128,6 +145,8 @@ def print_doors_table(cursor):
|
|||||||
print("Doors:")
|
print("Doors:")
|
||||||
for row in rows:
|
for row in rows:
|
||||||
print(row)
|
print(row)
|
||||||
|
|
||||||
|
|
||||||
# Function to print the content of the Log table
|
# Function to print the content of the Log table
|
||||||
def print_log_table(cursor):
|
def print_log_table(cursor):
|
||||||
cursor.execute("SELECT * FROM log")
|
cursor.execute("SELECT * FROM log")
|
||||||
@ -136,6 +155,7 @@ def print_log_table(cursor):
|
|||||||
for row in rows:
|
for row in rows:
|
||||||
print(row)
|
print(row)
|
||||||
|
|
||||||
|
|
||||||
# Function to print the content of the entire database
|
# Function to print the content of the entire database
|
||||||
def print_database_content(db_file):
|
def print_database_content(db_file):
|
||||||
conn = sqlite3.connect(db_file)
|
conn = sqlite3.connect(db_file)
|
||||||
@ -148,8 +168,8 @@ def print_database_content(db_file):
|
|||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
def get_logs():
|
|
||||||
|
|
||||||
|
def get_logs():
|
||||||
"""
|
"""
|
||||||
Fetch all logs from the log table in the database.
|
Fetch all logs from the log table in the database.
|
||||||
:return: List of log records.
|
:return: List of log records.
|
||||||
@ -157,11 +177,11 @@ def get_logs():
|
|||||||
conn = sqlite3.connect(DBFILE)
|
conn = sqlite3.connect(DBFILE)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
cursor.execute('''
|
cursor.execute("""
|
||||||
SELECT timestamp, user, rFIDUID, granted, door_id
|
SELECT timestamp, user, rFIDUID, granted, door_id
|
||||||
FROM log
|
FROM log
|
||||||
ORDER BY id DESC
|
ORDER BY id DESC
|
||||||
''')
|
""")
|
||||||
|
|
||||||
logs = cursor.fetchall()
|
logs = cursor.fetchall()
|
||||||
|
|
||||||
@ -179,16 +199,21 @@ def get_latest_logs(db_file,limit=10):
|
|||||||
conn = sqlite3.connect(db_file)
|
conn = sqlite3.connect(db_file)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
cursor.execute('''
|
cursor.execute(
|
||||||
|
"""
|
||||||
SELECT timestamp, user, rFIDUID, granted, door_id
|
SELECT timestamp, user, rFIDUID, granted, door_id
|
||||||
FROM log
|
FROM log
|
||||||
ORDER BY id DESC
|
ORDER BY id DESC
|
||||||
LIMIT ?
|
LIMIT ?
|
||||||
''', (limit,))
|
""",
|
||||||
|
(limit,),
|
||||||
|
)
|
||||||
|
|
||||||
logs = cursor.fetchall()
|
logs = cursor.fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
return logs
|
return logs
|
||||||
|
|
||||||
|
|
||||||
# Function to fetch list of existing groups from the database
|
# Function to fetch list of existing groups from the database
|
||||||
def get_existing_groups(db_file):
|
def get_existing_groups(db_file):
|
||||||
try:
|
try:
|
||||||
@ -201,6 +226,8 @@ def get_existing_groups(db_file):
|
|||||||
except sqlite3.Error as e:
|
except sqlite3.Error as e:
|
||||||
print(f"SQLite Error: {e}")
|
print(f"SQLite Error: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def delete_group_from_database(group_cn):
|
def delete_group_from_database(group_cn):
|
||||||
conn = sqlite3.connect(DBFILE)
|
conn = sqlite3.connect(DBFILE)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
@ -208,6 +235,7 @@ def delete_group_from_database(group_cn):
|
|||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
def get_doors():
|
def get_doors():
|
||||||
conn = sqlite3.connect(DBFILE)
|
conn = sqlite3.connect(DBFILE)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
@ -216,6 +244,7 @@ def get_doors():
|
|||||||
conn.close()
|
conn.close()
|
||||||
return doors
|
return doors
|
||||||
|
|
||||||
|
|
||||||
def get_users():
|
def get_users():
|
||||||
"""
|
"""
|
||||||
Fetch all users from the Users table in the database.
|
Fetch all users from the Users table in the database.
|
||||||
@ -224,18 +253,25 @@ def get_users():
|
|||||||
conn = sqlite3.connect(DBFILE)
|
conn = sqlite3.connect(DBFILE)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
cursor.execute('SELECT upn, rFIDUID, MemberOf FROM Users')
|
cursor.execute("SELECT upn, rFIDUID, MemberOf FROM Users")
|
||||||
users = cursor.fetchall()
|
users = cursor.fetchall()
|
||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
return users
|
return users
|
||||||
|
|
||||||
|
|
||||||
# Function to add a door to the database
|
# Function to add a door to the database
|
||||||
def add_door_to_database(db_file, group_cn, Door_id):
|
def add_door_to_database(db_file, group_cn, Door_id):
|
||||||
try:
|
try:
|
||||||
conn = sqlite3.connect(db_file)
|
conn = sqlite3.connect(db_file)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute("INSERT INTO Doors (id, GroupCn) VALUES (?,?)", (Door_id,group_cn,))
|
cursor.execute(
|
||||||
|
"INSERT INTO Doors (id, GroupCn) VALUES (?,?)",
|
||||||
|
(
|
||||||
|
Door_id,
|
||||||
|
group_cn,
|
||||||
|
),
|
||||||
|
)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
# print_database_content(DBFILE)
|
# print_database_content(DBFILE)
|
||||||
@ -245,6 +281,7 @@ def add_door_to_database(db_file, group_cn, Door_id):
|
|||||||
print(f"SQLite Error: {e}")
|
print(f"SQLite Error: {e}")
|
||||||
return (False, e)
|
return (False, e)
|
||||||
|
|
||||||
|
|
||||||
# Function to verify if the user is allowed to open the door
|
# Function to verify if the user is allowed to open the door
|
||||||
def check_access(rfid_uid_str, door_id):
|
def check_access(rfid_uid_str, door_id):
|
||||||
try:
|
try:
|
||||||
@ -252,10 +289,12 @@ def check_access(rfid_uid_str, door_id):
|
|||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
# Convert the received RFID UID string to bytes
|
# Convert the received RFID UID string to bytes
|
||||||
rfid_uid_bytes = rfid_uid_str.encode('utf-8')
|
rfid_uid_bytes = rfid_uid_str.encode("utf-8")
|
||||||
|
|
||||||
# Get the user's UPN and group memberships based on the RFID UID
|
# Get the user's UPN and group memberships based on the RFID UID
|
||||||
cursor.execute("SELECT upn, MemberOf FROM Users WHERE rFIDUID = ?", (rfid_uid_bytes,))
|
cursor.execute(
|
||||||
|
"SELECT upn, MemberOf FROM Users WHERE rFIDUID = ?", (rfid_uid_bytes,)
|
||||||
|
)
|
||||||
user_data = cursor.fetchone()
|
user_data = cursor.fetchone()
|
||||||
if user_data is None:
|
if user_data is None:
|
||||||
return False, None # User not found
|
return False, None # User not found
|
||||||
@ -263,7 +302,7 @@ def check_access(rfid_uid_str, door_id):
|
|||||||
upn_bytes, user_groups = user_data
|
upn_bytes, user_groups = user_data
|
||||||
|
|
||||||
# Decode the UPN bytes to string
|
# Decode the UPN bytes to string
|
||||||
upn = upn_bytes.decode('utf-8')
|
upn = upn_bytes.decode("utf-8")
|
||||||
|
|
||||||
# Get the group associated with the door
|
# Get the group associated with the door
|
||||||
cursor.execute("SELECT GroupCn FROM Doors WHERE id = ?", (door_id,))
|
cursor.execute("SELECT GroupCn FROM Doors WHERE id = ?", (door_id,))
|
||||||
@ -274,7 +313,7 @@ def check_access(rfid_uid_str, door_id):
|
|||||||
door_group = door_group[0]
|
door_group = door_group[0]
|
||||||
|
|
||||||
# Check if the user's group is allowed to open the door
|
# Check if the user's group is allowed to open the door
|
||||||
if door_group in user_groups.split(','):
|
if door_group in user_groups.split(","):
|
||||||
return True, upn # Access granted
|
return True, upn # Access granted
|
||||||
else:
|
else:
|
||||||
return False, None # Access denied
|
return False, None # Access denied
|
||||||
|
|||||||
@ -3,7 +3,8 @@ import ldap
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
import threading
|
import threading
|
||||||
import schedule
|
import schedule
|
||||||
from env import *
|
from env import DOOR_ACCESS_GROUPS_DN, LDAPPASS, LDAPUSER, LDAP_SERVER, USERS_DN
|
||||||
|
|
||||||
|
|
||||||
# Function to initialize LDAP connection
|
# Function to initialize LDAP connection
|
||||||
def initialize_ldap_connection():
|
def initialize_ldap_connection():
|
||||||
@ -22,9 +23,10 @@ def initialize_ldap_connection():
|
|||||||
print(f"[{datetime.now()}] LDAP connection successful.")
|
print(f"[{datetime.now()}] LDAP connection successful.")
|
||||||
return connect
|
return connect
|
||||||
except ldap.LDAPError as e:
|
except ldap.LDAPError as e:
|
||||||
print(f'[{datetime.now()}] LDAP Error: {e}')
|
print(f"[{datetime.now()}] LDAP Error: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# Function to retrieve users from LDAP
|
# Function to retrieve users from LDAP
|
||||||
def retrieve_users_from_ldap(ldap_connection):
|
def retrieve_users_from_ldap(ldap_connection):
|
||||||
"""
|
"""
|
||||||
@ -36,12 +38,15 @@ def retrieve_users_from_ldap(ldap_connection):
|
|||||||
if it fail, return empty list and print error code
|
if it fail, return empty list and print error code
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
result = ldap_connection.search_s(USERS_DN, ldap.SCOPE_SUBTREE, '(objectClass=user)')
|
result = ldap_connection.search_s(
|
||||||
|
USERS_DN, ldap.SCOPE_SUBTREE, "(objectClass=user)"
|
||||||
|
)
|
||||||
return result
|
return result
|
||||||
except ldap.LDAPError as e:
|
except ldap.LDAPError as e:
|
||||||
print(f'[{datetime.now()}] LDAP Error: {e}')
|
print(f"[{datetime.now()}] LDAP Error: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
# Function to retrieve groups from LDAP
|
# Function to retrieve groups from LDAP
|
||||||
def retrieve_groups_from_ldap(ldap_connection):
|
def retrieve_groups_from_ldap(ldap_connection):
|
||||||
"""
|
"""
|
||||||
@ -53,12 +58,15 @@ def retrieve_groups_from_ldap(ldap_connection):
|
|||||||
if it fail, return empty list and print error code
|
if it fail, return empty list and print error code
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
result = ldap_connection.search_s(DOOR_ACCESS_GROUPS_DN, ldap.SCOPE_SUBTREE, '(objectClass=group)')
|
result = ldap_connection.search_s(
|
||||||
|
DOOR_ACCESS_GROUPS_DN, ldap.SCOPE_SUBTREE, "(objectClass=group)"
|
||||||
|
)
|
||||||
return result
|
return result
|
||||||
except ldap.LDAPError as e:
|
except ldap.LDAPError as e:
|
||||||
print(f'[{datetime.now()}]LDAP Error: {e}')
|
print(f"[{datetime.now()}]LDAP Error: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
# Function to add user to the database or update if already exists
|
# Function to add user to the database or update if already exists
|
||||||
def add_user_to_database(conn, cursor, upn, rfid_uid, member_of):
|
def add_user_to_database(conn, cursor, upn, rfid_uid, member_of):
|
||||||
try:
|
try:
|
||||||
@ -67,18 +75,27 @@ def add_user_to_database(conn, cursor, upn, rfid_uid, member_of):
|
|||||||
if existing_user:
|
if existing_user:
|
||||||
# User already exists, check if data needs to be updated
|
# User already exists, check if data needs to be updated
|
||||||
if existing_user[1] != rfid_uid or existing_user[2] != member_of:
|
if existing_user[1] != rfid_uid or existing_user[2] != member_of:
|
||||||
cursor.execute("UPDATE Users SET rFIDUID=?, MemberOf=? WHERE upn=?", (rfid_uid, member_of, upn))
|
cursor.execute(
|
||||||
|
"UPDATE Users SET rFIDUID=?, MemberOf=? WHERE upn=?",
|
||||||
|
(rfid_uid, member_of, upn),
|
||||||
|
)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
print(f"[{datetime.now()}] User '{upn}' updated in the database.")
|
print(f"[{datetime.now()}] User '{upn}' updated in the database.")
|
||||||
else:
|
else:
|
||||||
print(f"[{datetime.now()}] User '{upn}' already exists in the database with the same data.")
|
print(
|
||||||
|
f"[{datetime.now()}] User '{upn}' already exists in the database with the same data."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# User doesn't exist, insert new user
|
# User doesn't exist, insert new user
|
||||||
cursor.execute("INSERT INTO Users (upn, rFIDUID, MemberOf) VALUES (?, ?, ?)", (upn, rfid_uid, member_of))
|
cursor.execute(
|
||||||
|
"INSERT INTO Users (upn, rFIDUID, MemberOf) VALUES (?, ?, ?)",
|
||||||
|
(upn, rfid_uid, member_of),
|
||||||
|
)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
print(f"[{datetime.now()}] User '{upn}' added to the database.")
|
print(f"[{datetime.now()}] User '{upn}' added to the database.")
|
||||||
except sqlite3.Error as e:
|
except sqlite3.Error as e:
|
||||||
print(f'SQLite Error: {e}')
|
print(f"SQLite Error: {e}")
|
||||||
|
|
||||||
|
|
||||||
# Function to add group to the database or update if already exists
|
# Function to add group to the database or update if already exists
|
||||||
def add_group_to_database(conn, cursor, cn):
|
def add_group_to_database(conn, cursor, cn):
|
||||||
@ -94,7 +111,8 @@ def add_group_to_database(conn, cursor, cn):
|
|||||||
conn.commit()
|
conn.commit()
|
||||||
print(f"[{datetime.now()}] Group '{cn}' added to the database.")
|
print(f"[{datetime.now()}] Group '{cn}' added to the database.")
|
||||||
except sqlite3.Error as e:
|
except sqlite3.Error as e:
|
||||||
print(f'SQLite Error: {e}')
|
print(f"SQLite Error: {e}")
|
||||||
|
|
||||||
|
|
||||||
# Function to sync LDAP users and groups to the database
|
# Function to sync LDAP users and groups to the database
|
||||||
def sync_ldap_to_database(db_file):
|
def sync_ldap_to_database(db_file):
|
||||||
@ -124,41 +142,52 @@ def sync_ldap_to_database(db_file):
|
|||||||
# Retrieve users from LDAP and add them to the database
|
# Retrieve users from LDAP and add them to the database
|
||||||
users = retrieve_users_from_ldap(ldap_conn)
|
users = retrieve_users_from_ldap(ldap_conn)
|
||||||
for dn, user_info in users:
|
for dn, user_info in users:
|
||||||
upn = user_info.get('userPrincipalName', [''])[0]
|
upn = user_info.get("userPrincipalName", [""])[0]
|
||||||
rfid_uid = user_info.get('rFIDUID', [''])[0]
|
rfid_uid = user_info.get("rFIDUID", [""])[0]
|
||||||
member_of = [group.decode('utf-8').split(',')[0].split('=')[1] for group in user_info.get('memberOf', [])]
|
member_of = [
|
||||||
|
group.decode("utf-8").split(",")[0].split("=")[1]
|
||||||
|
for group in user_info.get("memberOf", [])
|
||||||
|
]
|
||||||
|
|
||||||
# Check if the user is disabled in LDAP
|
# Check if the user is disabled in LDAP
|
||||||
user_account_control = user_info.get('userAccountControl', [0])[0]
|
user_account_control = user_info.get("userAccountControl", [0])[0]
|
||||||
if user_account_control == b'514' or user_account_control == b'66050': # Check if the 9th bit is set (ADS_UF_ACCOUNTDISABLE flag)
|
if (
|
||||||
|
user_account_control == b"514" or user_account_control == b"66050"
|
||||||
|
): # Check if the 9th bit is set (ADS_UF_ACCOUNTDISABLE flag)
|
||||||
# User is disabled, check if user exists in the database and remove if present
|
# User is disabled, check if user exists in the database and remove if present
|
||||||
cursor.execute("SELECT * FROM Users WHERE upn=?", (upn,))
|
cursor.execute("SELECT * FROM Users WHERE upn=?", (upn,))
|
||||||
existing_user = cursor.fetchone()
|
existing_user = cursor.fetchone()
|
||||||
if existing_user:
|
if existing_user:
|
||||||
cursor.execute("DELETE FROM Users WHERE upn=?", (upn,))
|
cursor.execute("DELETE FROM Users WHERE upn=?", (upn,))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
print(f"[{datetime.now()}] User '{upn}' disabled in LDAP and removed from the database.")
|
print(
|
||||||
|
f"[{datetime.now()}] User '{upn}' disabled in LDAP and removed from the database."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print(f"[{datetime.now()}] User '{upn}' disabled in LDAP but not present in the database.")
|
print(
|
||||||
|
f"[{datetime.now()}] User '{upn}' disabled in LDAP but not present in the database."
|
||||||
|
)
|
||||||
continue # Skip adding the disabled user to the database
|
continue # Skip adding the disabled user to the database
|
||||||
|
|
||||||
# User is not disabled, add or update user in the database
|
# User is not disabled, add or update user in the database
|
||||||
add_user_to_database(conn, cursor, upn, rfid_uid, ', '.join(member_of))
|
add_user_to_database(conn, cursor, upn, rfid_uid, ", ".join(member_of))
|
||||||
|
|
||||||
# Retrieve groups from LDAP and add them to the database
|
# Retrieve groups from LDAP and add them to the database
|
||||||
groups = retrieve_groups_from_ldap(ldap_conn)
|
groups = retrieve_groups_from_ldap(ldap_conn)
|
||||||
for dn, group_info in groups:
|
for dn, group_info in groups:
|
||||||
cn = group_info.get('cn', [''])[0].decode('utf-8')
|
cn = group_info.get("cn", [""])[0].decode("utf-8")
|
||||||
add_group_to_database(conn, cursor, cn)
|
add_group_to_database(conn, cursor, cn)
|
||||||
|
|
||||||
# Close connections
|
# Close connections
|
||||||
conn.close()
|
conn.close()
|
||||||
ldap_conn.unbind()
|
ldap_conn.unbind()
|
||||||
|
|
||||||
|
|
||||||
def run_sync_ldap_to_database_thread(db_file):
|
def run_sync_ldap_to_database_thread(db_file):
|
||||||
print(f"[{datetime.now()}] Running LDAP sync")
|
print(f"[{datetime.now()}] Running LDAP sync")
|
||||||
threading.Thread(target=sync_ldap_to_database, args=(db_file,), daemon=True).start()
|
threading.Thread(target=sync_ldap_to_database, args=(db_file,), daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
def schedule_sync_ldap_to_database(db_file):
|
def schedule_sync_ldap_to_database(db_file):
|
||||||
run_sync_ldap_to_database_thread(db_file) # Run immediately
|
run_sync_ldap_to_database_thread(db_file) # Run immediately
|
||||||
schedule.every(5).minutes.do(run_sync_ldap_to_database_thread, db_file)
|
schedule.every(5).minutes.do(run_sync_ldap_to_database_thread, db_file)
|
||||||
@ -1,13 +1,12 @@
|
|||||||
from ldapSync import *
|
from ldapSync import schedule_sync_ldap_to_database
|
||||||
from database import *
|
from database import setup_database, print_database_content
|
||||||
from Webserver import run_webServer_thread
|
from Webserver import run_webServer_thread
|
||||||
from env import *
|
from env import DBFILE
|
||||||
import schedule
|
import schedule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setup_database(DBFILE)
|
setup_database(DBFILE)
|
||||||
print_database_content(DBFILE)
|
#print_database_content(DBFILE)
|
||||||
run_webServer_thread()
|
run_webServer_thread()
|
||||||
schedule_sync_ldap_to_database(DBFILE)
|
schedule_sync_ldap_to_database(DBFILE)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user