Skip to content

Commit

Permalink
Merge pull request #168 from Shield-Cyber/dev
Browse files Browse the repository at this point in the history
Version 3
  • Loading branch information
oliv10 authored Oct 10, 2023
2 parents f548eb4 + f88cb52 commit 4c52e2f
Show file tree
Hide file tree
Showing 38 changed files with 1,130 additions and 381 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
container:
name: Release Dev Container

if: github.event.schedule == '0 0 * * *' || github.event_name == 'workflow_dispatch'
if: github.event.schedule == '0 0 * * *' || github.event_name == 'workflow_dispatch' || github.event_name == 'push'

runs-on: ubuntu-latest

Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
v1.5.0
.env
.pytest_cache
.DS_Store
.DS_Store
v2.7.8
13 changes: 13 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "uvicorn /workspaces/RESTBone/app/main:app --reload",
"problemMatcher": []
}
]
}
2 changes: 1 addition & 1 deletion app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.11.4
FROM python:3.11.4-slim

WORKDIR /opt

Expand Down
22 changes: 16 additions & 6 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import os

if os.getenv("USERNAME") != None:
USERNAME = os.getenv("USERNAME")
else:
USERNAME = "admin"
# Required Env Variables
PROD = None
USERNAME = os.getenv("USERNAME")

# Check Prod Env Var
CHECK_PROD = os.getenv("PROD")
try:
if CHECK_PROD.lower() != "true":
PROD = False
else:
PROD = True
except Exception:
PROD = False

# Optional Env Variables
if os.getenv("PASSWORD") != None:
PASSWORD = os.getenv("PASSWORD")
else:
Expand All @@ -15,12 +25,12 @@
else:
VERSION = '0.0.0'

if os.getenv("DB_HOST") != None:
if os.getenv("REDIS_HOST") != None:
DB_HOST = os.getenv("DB_HOST")
else:
DB_HOST = 'redis-db'

if os.getenv("DB_PORT") != None:
if os.getenv("REDIS_PORT") != None:
DB_PORT = os.getenv("DB_PORT")
else:
DB_PORT = 6379
Expand Down
42 changes: 23 additions & 19 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from app.utils.xml import root as xml_root
import time
from app import routes as RT
from app import DESCRIPTION, LOGGING_PREFIX, VERSION
from app import DESCRIPTION, LOGGING_PREFIX, VERSION, PROD
from app.database import crud as DB

# Logging
Expand All @@ -16,24 +16,27 @@
async def lifespan(app: FastAPI):
LOGGER.info(f"System Starting...")
counter = 0
while True:
if counter >= 60:
LOGGER.critical("Connection to gvmd socket took too long. Forcing system exit.")
raise SystemExit(1)
try:
with Gmp(connection=UnixSocketConnection()) as gmp:
version = xml_root(gmp.get_version())
if version.status != 200:
LOGGER.critical(f"Version check recieved non-200 response. Response: {version.data}")
raise SystemExit(2)
LOGGER.info(f"{version.status}, {version.status_text}. Startup complete and took {counter} second(s).")
break
except SystemExit:
raise SystemExit(2)
except:
LOGGER.warning("Wating 1 second for gvmd socket.")
time.sleep(1)
counter += 1
if PROD:
while True:
if counter >= 60:
LOGGER.critical("Connection to gvmd socket took too long. Forcing system exit.")
raise SystemExit(1)
try:
with Gmp(connection=UnixSocketConnection()) as gmp:
version = xml_root(gmp.get_version())
if version.status != 200:
LOGGER.critical(f"Version check recieved non-200 response. Response: {version.data}")
raise SystemExit(2)
LOGGER.info(f"{version.status}, {version.status_text}. Startup complete and took {counter} second(s).")
break
except SystemExit:
raise SystemExit(2)
except:
LOGGER.warning("Wating 1 second for gvmd socket.")
time.sleep(1)
counter += 1
else:
LOGGER.warning("Prod Mode Disabled: Some functions may not work correctly.")
yield
LOGGER.info("System shutting down...")

Expand All @@ -48,6 +51,7 @@ async def lifespan(app: FastAPI):

app.include_router(RT.AUTHENTICATION)
app.include_router(RT.CREDENTIAL)
app.include_router(RT.SCHEDULE)
app.include_router(RT.VERSION)
app.include_router(RT.SCANNER)
app.include_router(RT.REPORT)
Expand Down
3 changes: 1 addition & 2 deletions app/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
python-gvm==23.5.1
fastapi==0.100.0
python-multipart==0.0.6
uvicorn[standard]==0.22.0
uvicorn[standard]==0.23.1
passlib[bcrypt]==1.7.4
python-jose[cryptography]==3.3.0
# sqlalchemy==2.0.15
redis[hiredis]==4.6.0
25 changes: 13 additions & 12 deletions app/routes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from .authentication import ROUTER as AUTHENTICATION
from .credential import ROUTER as CREDENTIAL
from .version import ROUTER as VERSION
from .scanner import ROUTER as SCANNER
from .report import ROUTER as REPORT
from .target import ROUTER as TARGET
from .feed import ROUTER as FEED
from .port import ROUTER as PORT
from .scan import ROUTER as SCAN
from .user import ROUTER as USER
from .ping import ROUTER as PING
from .task import ROUTER as TASK
from .authentication.authentication import ROUTER as AUTHENTICATION
from .credential.credential import ROUTER as CREDENTIAL
from .schedule.schedule import ROUTER as SCHEDULE
from .version.version import ROUTER as VERSION
from .scanner.scanner import ROUTER as SCANNER
from .report.report import ROUTER as REPORT
from .target.target import ROUTER as TARGET
from .feed.feed import ROUTER as FEED
from .port.port import ROUTER as PORT
from .scan.scan import ROUTER as SCAN
from .user.user import ROUTER as USER
from .ping.ping import ROUTER as PING
from .task.task import ROUTER as TASK
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ async def describe_auth(
try:
return XMLResponse(gmp.describe_auth())
except Exception as err:
return ErrorResponse(err)
LOGGER.error(f"GMP Error: {err}")
return ErrorResponse("Internal Server Error")

@ROUTER.get("/is_authenticated", response_class=XMLResponse)
async def is_authenticated(
Expand All @@ -75,7 +76,8 @@ async def is_authenticated(
response = str(gmp.is_authenticated())
return XMLResponse(f'<is_authenticated_response status="200" status_text="{response}"/>')
except Exception as err:
return ErrorResponse(err)
LOGGER.error(f"GMP Error: {err}")
return ErrorResponse("Internal Server Error")

@ROUTER.patch("/modify_auth", response_class=XMLResponse)
async def modify_auth(
Expand All @@ -98,4 +100,5 @@ async def modify_auth(
try:
return XMLResponse(gmp.modify_auth(group_name=group_name, auth_conf_settings=auth_conf_settings))
except Exception as err:
return ErrorResponse(err)
LOGGER.error(f"GMP Error: {err}")
return ErrorResponse("Internal Server Error")
1 change: 1 addition & 0 deletions app/routes/authentication/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from dataclasses import dataclass
81 changes: 32 additions & 49 deletions app/routes/credential.py → app/routes/credential/credential.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from typing import Annotated, Optional
import logging

from . import models as Models

ENDPOINT = "credential"

LOGGER = logging.getLogger(f"{LOGGING_PREFIX}.{ENDPOINT}")
Expand All @@ -22,23 +24,10 @@

### ROUTES ###

@ROUTER.post("/create/credential")
@ROUTER.post("/create")
def create_credential(
current_user: Annotated[Auth.User, Depends(Auth.get_current_active_user)],
name: str,
credential_type: CredentialType,
comment: Optional[str] = None,
allow_insecure: Optional[bool] = False,
certificate: Annotated[str, Body()] = None,
key_phrase: Annotated[str, Body()] = None,
private_key: Annotated[str, Body()] = None,
login: Annotated[str, Body()] = None,
password: Annotated[str, Body()] = None,
auth_algorithm: Optional[SnmpAuthAlgorithm] = None,
community: Annotated[str, Body()] = None,
privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None,
privacy_password: Annotated[str, Body()] = None,
public_key: Annotated[str, Body()] = None,
Base: Models.CreateCredential
):
"""Create a new credential
Expand Down Expand Up @@ -77,17 +66,18 @@ def create_credential(
with Gmp(connection=UnixSocketConnection()) as gmp:
gmp.authenticate(username=current_user.username, password=Auth.get_admin_password())
try:
return gmp.create_credential(name=name,credential_type=credential_type,comment=comment,allow_insecure=allow_insecure,certificate=certificate,key_phrase=key_phrase,private_key=private_key,login=login,password=password,auth_algorithm=auth_algorithm,community=community,privacy_algorithm=privacy_algorithm,privacy_password=privacy_password,public_key=public_key)
return gmp.create_credential(name=Base.name,credential_type=Base.credential_type,comment=Base.comment,allow_insecure=Base.allow_insecure,certificate=Base.certificate,key_phrase=Base.key_phrase,private_key=Base.private_key,login=Base.login,password=Base.password,auth_algorithm=Base.auth_algorithm,community=Base.community,privacy_algorithm=Base.privacy_algorithm,privacy_password=Base.privacy_password,public_key=Base.public_key)
except Exception as err:
return ErrorResponse(err)
LOGGER.error(f"GMP Error: {err}")
return ErrorResponse("Internal Server Error")

@ROUTER.get("/get/credential")
@ROUTER.get("/get/{credential_id}")
def get_credential(
current_user: Annotated[Auth.User, Depends(Auth.get_current_active_user)],
credential_id: str,
scanners: Optional[bool] = None,
targets: Optional[bool] = None,
credential_format: Optional[CredentialFormat] = None,
scanners: bool = None,
targets: bool = None,
credential_format: CredentialFormat = None,
):
"""Request a single credential
Expand All @@ -106,16 +96,17 @@ def get_credential(
try:
return gmp.get_credential(credential_id=credential_id,scanners=scanners,targets=targets,credential_format=credential_format)
except Exception as err:
return ErrorResponse(err)
LOGGER.error(f"GMP Error: {err}")
return ErrorResponse("Internal Server Error")

@ROUTER.get("/get/credentials")
def get_credentials(
current_user: Annotated[Auth.User, Depends(Auth.get_current_active_user)],
filter_string: Optional[str] = None,
filter_id: Optional[str] = None,
scanners: Optional[bool] = None,
trash: Optional[bool] = None,
targets: Optional[bool] = None,
filter_string: str = None,
filter_id: str = None,
scanners: bool = None,
trash: bool = None,
targets: bool = None,
):
"""Request a list of credentials
Expand All @@ -135,9 +126,10 @@ def get_credentials(
try:
return gmp.get_credentials(filter_string=filter_string,filter_id=filter_id,scanners=scanners,trash=trash,targets=targets)
except Exception as err:
return ErrorResponse(err)
LOGGER.error(f"GMP Error: {err}")
return ErrorResponse("Internal Server Error")

@ROUTER.post("/clone/credential")
@ROUTER.post("/clone/{credential_id}")
def clone_credential(
current_user: Annotated[Auth.User, Depends(Auth.get_current_active_user)],
credential_id: str
Expand All @@ -156,13 +148,14 @@ def clone_credential(
try:
return gmp.clone_credential(credential_id=credential_id)
except Exception as err:
return ErrorResponse(err)
LOGGER.error(f"GMP Error: {err}")
return ErrorResponse("Internal Server Error")

@ROUTER.delete("/delete/credential")
@ROUTER.delete("/delete/{credential_id}")
def delete_credential(
current_user: Annotated[Auth.User, Depends(Auth.get_current_active_user)],
credential_id: str,
ultimate: Optional[bool] = False
ultimate: bool = False
):
"""Deletes an existing credential
Expand All @@ -176,25 +169,14 @@ def delete_credential(
try:
return gmp.delete_credential(credential_id=credential_id, ultimate=ultimate)
except Exception as err:
return ErrorResponse(err)
LOGGER.error(f"GMP Error: {err}")
return ErrorResponse("Internal Server Error")

@ROUTER.patch("/modify/credential")
@ROUTER.patch("/modify/{credential_id}")
def modify_credential(
current_user: Annotated[Auth.User, Depends(Auth.get_current_active_user)],
credential_id: str,
name: Optional[str] = None,
comment: Optional[str] = None,
allow_insecure: Optional[bool] = None,
certificate: Annotated[str, Body()] = None,
key_phrase: Annotated[str, Body()] = None,
private_key: Annotated[str, Body()] = None,
login: Annotated[str, Body()] = None,
password: Annotated[str, Body()] = None,
auth_algorithm: Optional[SnmpAuthAlgorithm] = None,
community: Annotated[str, Body()] = None,
privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None,
privacy_password: Annotated[str, Body()] = None,
public_key: Annotated[str, Body()] = None,
Base: Models.ModifyCredential
):
"""Modifies an existing credential.
Expand All @@ -221,6 +203,7 @@ def modify_credential(
with Gmp(connection=UnixSocketConnection()) as gmp:
gmp.authenticate(username=current_user.username, password=Auth.get_admin_password())
try:
return gmp.modify_credential(name=name,credential_id=credential_id,comment=comment,allow_insecure=allow_insecure,certificate=certificate,key_phrase=key_phrase,private_key=private_key,login=login,password=password,auth_algorithm=auth_algorithm,community=community,privacy_algorithm=privacy_algorithm,privacy_password=privacy_password,public_key=public_key)
return gmp.modify_credential(credential_id=credential_id,name=Base.name,credential_type=Base.credential_type,comment=Base.comment,allow_insecure=Base.allow_insecure,certificate=Base.certificate,key_phrase=Base.key_phrase,private_key=Base.private_key,login=Base.login,password=Base.password,auth_algorithm=Base.auth_algorithm,community=Base.community,privacy_algorithm=Base.privacy_algorithm,privacy_password=Base.privacy_password,public_key=Base.public_key)
except Exception as err:
return ErrorResponse(err)
LOGGER.error(f"GMP Error: {err}")
return ErrorResponse("Internal Server Error")
Loading

0 comments on commit 4c52e2f

Please sign in to comment.