Database Models & Connector
This commit is contained in:
		
							parent
							
								
									7d0749e562
								
							
						
					
					
						commit
						8ff4aaebbe
					
				
							
								
								
									
										35
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								README.md
									
									
									
									
									
								
							@ -1,9 +1,42 @@
 | 
			
		||||
# Overseer
 | 
			
		||||
 | 
			
		||||
## Description
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
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 = [
 | 
			
		||||
        "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
 | 
			
		||||
This will automatically populate the overseer server with the appropriate resources in `templates` and `static`
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
yarn build
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user