Database Models & Connector
This commit is contained in:
parent
7d0749e562
commit
8ff4aaebbe
35
README.md
35
README.md
@ -1,9 +1,42 @@
|
|||||||
# Overseer
|
# Overseer
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
Overseer is a port scanning web interface. All current and historical results are stored in a database.
|
Overseer is a port scanning web interface. All current and historical results are stored in a database.
|
||||||
|
|
||||||
## Building
|
## Developing
|
||||||
|
|
||||||
|
### Server
|
||||||
|
Ideally from a virtualenv:
|
||||||
|
```
|
||||||
|
python setup.py develop
|
||||||
|
```
|
||||||
|
|
||||||
|
### Client
|
||||||
|
At this point, you have to build the client to appropriately populate the static resources for
|
||||||
|
the Flask server to serve up.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
Overseer consists of a server and client component.
|
||||||
|
|
||||||
|
### Server:
|
||||||
|
Ideally from a virtualenv:
|
||||||
|
```
|
||||||
|
python setup.py install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Client:
|
||||||
|
You must run these commands from the `./src/overseer_client/` directory:
|
||||||
|
```
|
||||||
|
yarn build
|
||||||
|
```
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
|
Ideally from a virtual env:
|
||||||
|
```
|
||||||
|
overseer run
|
||||||
|
```
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
In a production environment, it would be ideal to setup something like nginx to properly forward
|
||||||
|
the `/api/*` routes to the Flask server, and all other endpoints to the static client resources.
|
||||||
|
3
setup.py
3
setup.py
@ -16,6 +16,7 @@ setup(
|
|||||||
},
|
},
|
||||||
install_requires = [
|
install_requires = [
|
||||||
"Flask",
|
"Flask",
|
||||||
"flask_socketio"
|
"flask_socketio",
|
||||||
|
"sqlalchemy",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
import models
|
||||||
|
from datetime import datetime
|
||||||
|
from os import path
|
||||||
|
from sqlalchemy import create_engine, or_, insert, Table, Column, Integer, String, ForeignKey, DateTime
|
||||||
|
from sqlalchemy.orm import declarative_base, Session
|
||||||
|
|
||||||
|
class DatabaseConnector:
|
||||||
|
def __init__(self, data_path):
|
||||||
|
self.engine = create_engine("sqlite+pysqlite:///%s" % path.join(data_path, "overseer.sqlite"), echo=True, future=True)
|
||||||
|
models.Base.metadata.create_all(self.engine)
|
||||||
|
|
||||||
|
def create_scan_result(self, ip_address, scan_results, hostname=None):
|
||||||
|
session = Session(bind=self.engine)
|
||||||
|
|
||||||
|
# Does an existing target exist?
|
||||||
|
scan_target = session.query(models.ScanTarget).filter(or_(
|
||||||
|
models.ScanTarget.ip==ip_address,
|
||||||
|
models.ScanTarget.hostname==hostname,
|
||||||
|
)).first()
|
||||||
|
|
||||||
|
# Nope, create one
|
||||||
|
if not scan_target:
|
||||||
|
scan_target = models.ScanTarget(ip=ip_address, hostname=hostname)
|
||||||
|
session.add(scan_target)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
# Create scan history
|
||||||
|
scan_history = models.ScanHistory(target=scan_target.id, results=",".join(map(str, scan_results)), datetime=datetime.now())
|
||||||
|
session.add(scan_history)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
|
||||||
|
def create_target(self, ip_address, hostname):
|
||||||
|
stmt = insert(models.ScanTarget).values(ip=ip_address, hostname=hostname)
|
||||||
|
compiled = stmt.compile()
|
||||||
|
self.__execute_statement(stmt)
|
||||||
|
return stmt
|
||||||
|
|
||||||
|
|
||||||
|
def __execute_statement(self, stmt):
|
||||||
|
with self.engine.connect() as conn:
|
||||||
|
result = conn.execute(stmt)
|
||||||
|
conn.commit()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# FOR TESTING PURPOSES
|
||||||
|
def main():
|
||||||
|
db = DatabaseConnector("/Users/evanreichard/Development/git/overseer/src/overseer")
|
||||||
|
db.create_scan_result(1234577, [5,6,7,8], "test222.com")
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
37
src/overseer/models.py
Normal file
37
src/overseer/models.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime
|
||||||
|
from sqlalchemy.orm import declarative_base
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
class ScanTarget(Base):
|
||||||
|
__tablename__ = "scan_target"
|
||||||
|
|
||||||
|
# Unique ID
|
||||||
|
id = Column(Integer, primary_key=True, unique=True)
|
||||||
|
|
||||||
|
# Integer representation of an IP Address. Can use SQL queries to filter subnets.
|
||||||
|
ip = Column(Integer, index=True, unique=True)
|
||||||
|
|
||||||
|
# Corresponding hostname.
|
||||||
|
hostname = Column(String, index=True, unique=True)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"ScanTarget(id={self.id!r}, ip={self.ip!r}, hostname={self.hostname!r})"
|
||||||
|
|
||||||
|
class ScanHistory(Base):
|
||||||
|
__tablename__ = "scan_history"
|
||||||
|
|
||||||
|
# Unique ID
|
||||||
|
id = Column(Integer, primary_key=True, unique=True)
|
||||||
|
|
||||||
|
# Scan Target Reference
|
||||||
|
target = Column(Integer, ForeignKey("scan_target.id"))
|
||||||
|
|
||||||
|
# Results
|
||||||
|
results = Column(String)
|
||||||
|
|
||||||
|
# DateTime
|
||||||
|
datetime = Column(DateTime())
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"ScanHistory(id={self.id!r}, target={self.target!r}, results={self.results!r}, datetime={self.datetime!r})"
|
0
src/overseer/scanner.py
Normal file
0
src/overseer/scanner.py
Normal file
@ -11,6 +11,8 @@ yarn serve
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Compiles and minifies for production
|
### Compiles and minifies for production
|
||||||
|
This will automatically populate the overseer server with the appropriate resources in `templates` and `static`
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn build
|
yarn build
|
||||||
```
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user