Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c29ea7d
Update tasks.py
ToweringDragoon Mar 7, 2025
b79a32b
Update tasks.py
ToweringDragoon Mar 7, 2025
571b18b
Update models.py
ToweringDragoon Mar 7, 2025
7c63e63
Update factories.py
ToweringDragoon Mar 7, 2025
01ffaec
Update urls.py
ToweringDragoon Mar 7, 2025
39c410f
Update views.py
ToweringDragoon Mar 7, 2025
5328ca3
Update management.html
ToweringDragoon Mar 7, 2025
15475dd
Update update.html
ToweringDragoon Mar 7, 2025
f7ebd8c
Update 0001_initial.py
ToweringDragoon Mar 7, 2025
dcbfff1
Update forms.py
ToweringDragoon Mar 7, 2025
be14b39
Update urls.py
ToweringDragoon Mar 7, 2025
c4ae3f4
Update admin.py
ToweringDragoon Mar 7, 2025
b6f895c
Update views.py
ToweringDragoon Mar 7, 2025
bf078c6
Update tasks.py
ToweringDragoon Mar 7, 2025
68755c0
Update tasks.py
ToweringDragoon Mar 7, 2025
445b00c
Update models.py
ToweringDragoon Mar 7, 2025
59c56ee
Update 0001_initial.py
ToweringDragoon Mar 7, 2025
33decb6
Update tasks.py
ToweringDragoon Mar 7, 2025
06a15fd
Update base.txt
ToweringDragoon Mar 7, 2025
ffd3370
Update urls.py
ToweringDragoon Mar 7, 2025
c2f69f3
Update tasks.py
ToweringDragoon Mar 7, 2025
deec630
Update tasks.py
ToweringDragoon Mar 7, 2025
36e147b
Update tasks.py
ToweringDragoon Mar 7, 2025
fe6ce82
Update tasks.py
ToweringDragoon Mar 7, 2025
42e2b83
Update models.py
ToweringDragoon Mar 10, 2025
888abf8
Update 0001_initial.py
ToweringDragoon Mar 10, 2025
346bec7
Update management.html
ToweringDragoon Mar 10, 2025
9a28d8b
Merge branch 'GhostManager:master' into ToweringDragoon-cloudflare-1
ToweringDragoon Apr 17, 2025
aa156d0
Updated cloudflare and added GCP
ToweringDragoon Apr 17, 2025
603a381
Update base.txt
ToweringDragoon Apr 17, 2025
bc326cc
Update cloud_monitors.py
ToweringDragoon Apr 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ghostwriter/commandcenter/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
ExtraFieldSpec,
GeneralConfiguration,
NamecheapConfiguration,
CloudflareConfiguration,
ReportConfiguration,
SlackConfiguration,
VirusTotalConfiguration,
Expand All @@ -23,6 +24,7 @@
admin.site.register(CloudServicesConfiguration, SingletonModelAdmin)
admin.site.register(CompanyInformation, SingletonModelAdmin)
admin.site.register(NamecheapConfiguration, SingletonModelAdmin)
admin.site.register(CloudflareConfiguration, SingletonModelAdmin)
admin.site.register(SlackConfiguration, SingletonModelAdmin)
admin.site.register(VirusTotalConfiguration, SingletonModelAdmin)
admin.site.register(GeneralConfiguration, SingletonModelAdmin)
Expand Down
15 changes: 15 additions & 0 deletions ghostwriter/commandcenter/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,21 @@ class Migration(migrations.Migration):
"verbose_name": "Namecheap Configuration",
},
),
migrations.CreateModel(
name="CloudflareConfiguration",
fields=[
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("enable", models.BooleanField(default=False)),
("api_key", models.CharField(default="Cloudflare Global API Key", max_length=255)),
("username", models.CharField(default="Account email", max_length=255)),
("account_id", models.CharField(default="Account ID", max_length=255)),
("client_ip", models.CharField(default="Whitelisted IP Address", max_length=255)),
("page_size", models.IntegerField(default=100)),
],
options={
"verbose_name": "Cloudflare Configuration",
},
),
migrations.CreateModel(
name="ReportConfiguration",
fields=[
Expand Down
92 changes: 92 additions & 0 deletions ghostwriter/commandcenter/migrations/0034_add_gcp_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Generated manually to add GCP credential fields

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("commandcenter", "0033_auto_20241204_1810"), # Replace with your actual previous migration
]

operations = [
migrations.AddField(
model_name="cloudservicesconfiguration",
name="gcp_project_id",
field=models.CharField(
max_length=255,
default="your-project-id",
verbose_name="GCP Project ID",
),
),
migrations.AddField(
model_name="cloudservicesconfiguration",
name="gcp_private_key_id",
field=models.CharField(
max_length=255,
default="your-private-key-id",
verbose_name="GCP Private Key ID",
),
),
migrations.AddField(
model_name="cloudservicesconfiguration",
name="gcp_private_key",
field=models.TextField(
default="your-private-key",
verbose_name="GCP Private Key",
),
),
migrations.AddField(
model_name="cloudservicesconfiguration",
name="gcp_client_email",
field=models.CharField(
max_length=255,
default="your-service-account@project.iam.gserviceaccount.com",
verbose_name="GCP Client Email",
),
),
migrations.AddField(
model_name="cloudservicesconfiguration",
name="gcp_client_id",
field=models.CharField(
max_length=255,
default="your-client-id",
verbose_name="GCP Client ID",
),
),
migrations.AddField(
model_name="cloudservicesconfiguration",
name="gcp_auth_uri",
field=models.CharField(
max_length=255,
default="https://accounts.google.com/o/oauth2/auth",
verbose_name="GCP Auth URI",
),
),
migrations.AddField(
model_name="cloudservicesconfiguration",
name="gcp_token_uri",
field=models.CharField(
max_length=255,
default="https://oauth2.googleapis.com/token",
verbose_name="GCP Token URI",
),
),
migrations.AddField(
model_name="cloudservicesconfiguration",
name="gcp_auth_cert_url",
field=models.CharField(
max_length=255,
default="https://www.googleapis.com/oauth2/v1/certs",
verbose_name="GCP Auth Provider Cert URL",
),
),
migrations.AddField(
model_name="cloudservicesconfiguration",
name="gcp_client_cert_url",
field=models.TextField(
default="https://www.googleapis.com/robot/v1/metadata/x509/your-service-account@project.iam.gserviceaccount.com",
verbose_name="GCP Client Cert URL",
),
),
]
52 changes: 52 additions & 0 deletions ghostwriter/commandcenter/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,48 @@ class Meta:
def sanitized_api_key(self):
return sanitize(self.api_key)

class CloudflareConfiguration(SingletonModel):
enable = models.BooleanField(default=False)
api_key = models.CharField(max_length=255, default="Cloudflare API key", help_text="Your Cloudflare API key")
username = models.CharField(max_length=255, default="Account Email", help_text="Your Cloudflare email")
account_id = models.CharField(
"Account ID",
max_length=255,
default="Account ID",
help_text="Your Cloudflare Account ID",
)
client_ip = models.CharField(
"Whitelisted IP Address",
max_length=255,
default="Whitelisted IP Address",
help_text="Your external IP address registered with Cloudflare",
)
page_size = models.IntegerField(
"Page Size",
default=100,
help_text="Maximum number of domains to return (100 is the max allowed)",
)

def __str__(self):
return "Cloudflare Configuration"

class Meta:
verbose_name = "Cloudflare Configuration"

@property
def sanitized_api_key(self):
return sanitize(self.api_key)

def __str__(self):
return "Cloudflare Configuration"

class Meta:
verbose_name = "Cloudflare Configuration"

@property
def sanitized_api_key(self):
return sanitize(self.api_key)


class ReportConfiguration(SingletonModel):
enable_borders = models.BooleanField(default=False, help_text="Enable borders around images in Word documents")
Expand Down Expand Up @@ -281,6 +323,16 @@ class CloudServicesConfiguration(SingletonModel):
default=7,
help_text="Number of days to delay cloud monitoring notifications for teardown",
)
# GCP-Specific Configuration Fields
gcp_project_id = models.CharField("GCP Project ID", max_length=255, default="your-project-id")
gcp_private_key_id = models.CharField("GCP Private Key ID", max_length=255, default="your-private-key-id")
gcp_private_key = models.TextField("GCP Private Key", default="your-private-key")
gcp_client_email = models.CharField("GCP Client Email", max_length=255, default="your-service-account@example.iam.gserviceaccount.com")
gcp_client_id = models.CharField("GCP Client ID", max_length=255, default="your-client-id")
gcp_auth_uri = models.CharField("GCP Auth URI", max_length=255, default="https://accounts.google.com/o/oauth2/auth")
gcp_token_uri = models.CharField("GCP Token URI", max_length=255, default="https://oauth2.googleapis.com/token")
gcp_auth_cert_url = models.CharField("GCP Auth Provider Cert URL", max_length=255, default="https://www.googleapis.com/oauth2/v1/certs")
gcp_client_cert_url = models.TextField("GCP Client Cert URL", default="https://www.googleapis.com/robot/v1/metadata/x509/your-service-account@example.iam.gserviceaccount.com")

def __str__(self):
return "Cloud Services Configuration"
Expand Down
11 changes: 11 additions & 0 deletions ghostwriter/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,17 @@ class Meta:
page_size = 100


class CloudflareConfigurationFactory(factory.django.DjangoModelFactory):
class Meta:
model = "commandcenter.CloudflareConfiguration"

enable = Faker("boolean")
api_key = Faker("credit_card_number")
username = Faker("user_name")
api_username = Faker("user_name")
client_ip = Faker("ipv4_private")
page_size = 100

class ReportConfigurationFactory(factory.django.DjangoModelFactory):
class Meta:
model = "commandcenter.ReportConfiguration"
Expand Down
46 changes: 46 additions & 0 deletions ghostwriter/home/templates/home/management.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
{% get_solo "commandcenter.CompanyInformation" as company_config %}
{% get_solo "commandcenter.CloudServicesConfiguration" as cloud_config %}
{% get_solo "commandcenter.NamecheapConfiguration" as namecheap_config %}
{% get_solo "commandcenter.CloudflareConfiguration" as cloudflare_config %}
{% get_solo "commandcenter.ReportConfiguration" as report_config %}
{% get_solo "commandcenter.SlackConfiguration" as slack_config %}
{% get_solo "commandcenter.VirusTotalConfiguration" as vt_config %}
Expand Down Expand Up @@ -136,6 +137,37 @@ <h2>API & Notification Configurations</h2>
<td class="text-justify">Disabled</td>
</tr>
{% endif %}
{% if cloudflare_config.enable %}
<tr>
<td class="text-left icon toggle-on-icon">Cloudflare API Enabled</td>
<td class="text-justify">{{ cloudflare_config.enable }}</td>
</tr>
<tr>
<td class="text-left icon laptop-icon">Cloudflare Whitelisted IP</td>
<td class="text-justify">{{ cloudflare_config.client_ip }}</td>
</tr>
<tr>
<td class="text-left icon key-icon">Cloudflare API Key</td>
<td class="text-justify">{{ cloudflare_config.sanitized_api_key }}</td>
</tr>
<tr>
<td class="text-left icon user-icon">Cloudflare Email</td>
<td class="text-justify">{{ cloudflare_config.username }}</td>
</tr>
<tr>
<td class="text-left icon user-gear-icon">Cloudflare Account ID</td>
<td class="text-justify">{{ cloudflare_config.account_id }}</td>
</tr>
<tr>
<td class="text-left icon hash-icon">Cloudflare Page Size</td>
<td class="text-justify">{{ cloudflare_config.page_size }}</td>
</tr>
{% else %}
<tr>
<td class="text-left icon toggle-off-icon">Cloudflare API Enabled</td>
<td class="text-justify">Disabled</td>
</tr>
{% endif %}

<!-- Spacer -->
<tr>
Expand Down Expand Up @@ -165,6 +197,14 @@ <h2>API & Notification Configurations</h2>
<td class="text-left icon do-icon">Digital Ocean API Key</td>
<td class="text-justify">{{ cloud_config.sanitized_do_api_key }}</td>
</tr>
<tr>
<td class="text-left icon do-icon">GCP Project ID</td>
<td class="text-justify">{{ cloud_config.gcp_project_id }}</td>
</tr>
<tr>
<td class="text-left icon do-icon">GCP Private Key ID</td>
<td class="text-justify">{{ cloud_config.gcp_private_key_id }}</td>
</tr>
{% else %}
<tr>
<td class="text-left icon toggle-off-icon">Cloud Monitoring Enabled</td>
Expand Down Expand Up @@ -309,12 +349,18 @@ <h6>Test Configurations</h6>
<button type="submit" class="js-queue-task btn btn-primary" queue-task-url="{% url 'home:ajax_test_do' %}"
queue-task-csrf-token="{{ csrf_token }}">Test Digital Ocean
</button>
<button type="submit" class="js-queue-task btn btn-primary" queue-task-url="{% url 'home:ajax_test_gcp' %}"
queue-task-csrf-token="{{ csrf_token }}">Test GCP
</button>
</div>

<div class="btn-group mr-2" role="group" aria-label="API Tests">
<button class="js-queue-task btn btn-primary" queue-task-url="{% url 'home:ajax_test_namecheap' %}"
queue-task-csrf-token="{{ csrf_token }}">Test Namecheap API
</button>
<button class="js-queue-task btn btn-primary" queue-task-url="{% url 'home:ajax_test_cloudflare' %}"
queue-task-csrf-token="{{ csrf_token }}">Test Cloudflare API
</button>
<button class="js-queue-task btn btn-primary" queue-task-url="{% url 'home:ajax_test_virustotal' %}"
queue-task-csrf-token="{{ csrf_token }}">Test VirusTotal API
</button>
Expand Down
10 changes: 10 additions & 0 deletions ghostwriter/home/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,21 @@
views.TestDOConnection.as_view(),
name="ajax_test_do",
),
path(
"ajax/management/test/gcp",
views.TestGCPConnection.as_view(),
name="ajax_test_gcp",
),
path(
"ajax/management/test/namecheap",
views.TestNamecheapConnection.as_view(),
name="ajax_test_namecheap",
),
path(
"ajax/management/test/cloudflare",
views.TestCloudflareConnection.as_view(),
name="ajax_test_cloudflare",
),
path(
"ajax/management/test/slack",
views.TestSlackConnection.as_view(),
Expand Down
Loading