initial commit

This commit is contained in:
Bryan Gerlach
2024-09-24 16:04:47 -05:00
commit b401aa531b
30 changed files with 707 additions and 0 deletions

0
db.sqlite3 Normal file
View File

22
manage.py Normal file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rdgen.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

0
rdgen/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

16
rdgen/asgi.py Normal file
View File

@@ -0,0 +1,16 @@
"""
ASGI config for rdgen project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rdgen.settings')
application = get_asgi_application()

130
rdgen/settings.py Normal file
View File

@@ -0,0 +1,130 @@
"""
Django settings for rdgen project.
Generated by 'django-admin startproject' using Django 5.0.3.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""
import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-!(t-!f#6g#sr%yfded9(xha)g+=!6craeez^cp+*&bz_7vdk61'
GHUSER = os.environ.get("GHUSER", '')
GHBEARER = os.environ.get("GHBEARER", '')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rdgenerator',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'rdgen.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'rdgen.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

33
rdgen/urls.py Normal file
View File

@@ -0,0 +1,33 @@
"""
URL configuration for rdgen project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
import django
from rdgenerator import views as views
if django.__version__.split('.')[0]>='4':
from django.urls import re_path as url
else:
from django.conf.urls import url, include
urlpatterns = [
url(r'^$',views.generator_view),
url(r'^generator',views.generator_view),
url(r'^check_for_file',views.check_for_file),
url(r'^download',views.download),
url(r'^creategh',views.create_github_run),
url(r'^updategh',views.update_github_run),
url(r'^startgh',views.startgh),
]

16
rdgen/wsgi.py Normal file
View File

@@ -0,0 +1,16 @@
"""
WSGI config for rdgen project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rdgen.settings')
application = get_wsgi_application()

0
rdgenerator/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
rdgenerator/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
rdgenerator/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class RdgeneratorConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'rdgenerator'

66
rdgenerator/forms.py Normal file
View File

@@ -0,0 +1,66 @@
from django import forms
class GenerateForm(forms.Form):
#Platform
platform = forms.ChoiceField(choices=[('windows','Windows'),('linux','Linux (currently unavailable)'),('android','Android (currently unavailable)')], initial='windows')
#General
exename = forms.CharField(label="Name for EXE file", required=True)
appname = forms.CharField(label="Custom App Name", required=False)
direction = forms.ChoiceField(widget=forms.RadioSelect, choices=[
('incoming', 'Incoming Only'),
('outgoing', 'Outgoing Only'),
('both', 'Bidirectional')
], initial='both')
installation = forms.ChoiceField(label="Disable Installation", choices=[
('installationY', 'No, enable installation'),
('installationN', 'Yes, DISABLE installation')
], initial='installationY')
settings = forms.ChoiceField(label="Disable Settings", choices=[
('settingsY', 'No, enable settings'),
('settingsN', 'Yes, DISABLE settings')
], initial='settingsY')
#Custom Server
serverIP = forms.CharField(label="Host", required=False)
apiServer = forms.CharField(label="API Server", required=False)
key = forms.CharField(label="Key", required=False)
urlLink = forms.CharField(label="Custom URL for links", required=False)
#Visual
iconfile = forms.FileField(label="Custom App Icon (in .png format)", required=False)
logofile = forms.FileField(label="Custom App Logo (in .png format)", required=False)
theme = forms.ChoiceField(choices=[
('light', 'Light'),
('dark', 'Dark'),
('system', 'Follow System')
], initial='system')
themeDorO = forms.ChoiceField(choices=[('default', 'Default'),('override', 'Override')], initial='default')
#Security
passApproveMode = forms.ChoiceField(choices=[('password','Accept sessions via password'),('click','Accept sessions via click'),('password-click','Accepts sessions via both')],initial='password-click')
permanentPassword = forms.CharField(widget=forms.PasswordInput(), required=False)
runasadmin = forms.ChoiceField(choices=[('false','No'),('true','Yes')], initial='false')
denyLan = forms.BooleanField(initial=False, required=False)
enableDirectIP = forms.BooleanField(initial=False, required=False)
#ipWhitelist = forms.BooleanField(initial=False, required=False)
autoClose = forms.BooleanField(initial=False, required=False)
#Permissions
permissionsDorO = forms.ChoiceField(choices=[('default', 'Default'),('override', 'Override')], initial='default')
permissionsType = forms.ChoiceField(choices=[('custom', 'Custom'),('full', 'Full Access'),('view','Screen share')], initial='custom')
enableKeyboard = forms.BooleanField(initial=True, required=False)
enableClipboard = forms.BooleanField(initial=True, required=False)
enableFileTransfer = forms.BooleanField(initial=True, required=False)
enableAudio = forms.BooleanField(initial=True, required=False)
enableTCP = forms.BooleanField(initial=True, required=False)
enableRemoteRestart = forms.BooleanField(initial=True, required=False)
enableRecording = forms.BooleanField(initial=True, required=False)
enableBlockingInput = forms.BooleanField(initial=True, required=False)
enableRemoteModi = forms.BooleanField(initial=False, required=False)
#Other
removeWallpaper = forms.BooleanField(initial=True, required=False)
defaultManual = forms.CharField(widget=forms.Textarea, required=False)
overrideManual = forms.CharField(widget=forms.Textarea, required=False)

View File

6
rdgenerator/models.py Normal file
View File

@@ -0,0 +1,6 @@
from django.db import models
class GithubRun(models.Model):
id = models.IntegerField(verbose_name="ID",primary_key=True)
uuid = models.CharField(verbose_name="uuid", max_length=100)
status = models.CharField(verbose_name="status", max_length=100)

View File

@@ -0,0 +1 @@
<a href='/download?filename={{filename}}&uuid={{uuid}}'>{{filename}}</a>

View File

@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<head>
<title>Server Configuration Form</title>
<style>
.container {
display: grid;
grid-template-columns: 50% 50%;
grid-template-rows: repeat(2, auto); /* Adjust the number of rows as needed */
padding: 20px; /* Adjust the padding value as needed */
max-width: 1000px; /* Set a maximum width for the container */
margin: 0 auto; /* Center the container horizontally */
}
.section {
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 20px;
margin-left: 10px;
margin-right: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Add a subtle box shadow */
border-radius: 5px; /* Add rounded corners for a more 3D effect */
}
label {
font-weight: bold;
}
</style>
</head>
<body>
<form action="/generator" method="post" enctype="multipart/form-data" class="container">
<h2>Select Platform</h2>
<label for="{{ form.platform.id_for_label }}"></label>
{{ form.platform }}<br><br>
<div class="section">
<h2>General</h2>
<label for="{{ form.exename.id_for_label }}">Name of the configuration:</label>
{{ form.exename }}<br><br>
<label for="{{ form.appname.id_for_label }}">Custom Application Name:</label>
{{ form.appname }}<br><br>
<label for="{{ form.direction.id_for_label }}">Connection Type:</label>
{{ form.direction }}<br><br>
<label for="{{ form.installation.id_for_label }}">Disable Installation:</label>
{{ form.installation }}<br><br>
<label for="{{ form.settings.id_for_label }}">Disable Settings:</label>
{{ form.settings }}<br><br>
</div>
<div class="section">
<h2>Custom Server</h2>
<label for="{{ form.serverIP.id_for_label }}">Host:</label>
{{ form.serverIP }}<br><br>
<label for="{{ form.key.id_for_label }}">Key:</label>
{{ form.key }}<br><br>
<label for="{{ form.apiServer.id_for_label }}">API:</label>
{{ form.apiServer }}<br><br>
<label for="{{ form.urlLink.id_for_label }}">Custom URL for links (replaces https://rustdesk.com):</label>
{{ form.urlLink }}<br><br>
</div>
<div class="section">
<h2>Security</h2>
<label for="{{ form.runasadmin.id_for_label }}">Always run as Administrator?</label>
{{ form.runasadmin }}<br><br>
<label for="{{ form.passApproveMode.id_for_label }}">Password Approve mode:</label>
{{ form.passApproveMode }}<br><br>
<label for="{{ form.permanentPassword.id_for_label }}">Set Permanent Password:</label>
{{ form.permanentPassword }} *The password is used as default, but can be changed by the client<br><br>
{{ form.denyLan }}
<label for="{{ form.denyLan.id_for_label }}">Deny LAN discovery</label><br><br>
{{ form.enableDirectIP }}
<label for="{{ form.enableDirectIP.id_for_label }}">Enable direct IP access</label><br><br>
{{ form.autoClose }}
<label for="{{ form.autoClose.id_for_label }}">Automatically close incoming sessions on user inactivity</label><br><br>
</div>
<div class="section">
<h2>Visual</h2>
<label for="{{ form.iconfile.id_for_label }}">Custom App Icon (in .png format)</label>
{{ form.iconfile }}<br><br>
<label for="{{ form.logofile.id_for_label }}">Custom App Logo (in .png format)</label>
{{ form.logofile }}<br><br>
<label for="{{ form.theme.id_for_label }}">Theme:</label>
{{ form.theme }} {{ form.themeDorO }} *Default sets the theme but allows the client to change it, Override sets the theme permanently.<br><br>
</div>
<div class="section">
<h2>Permissions</h2>
The following Permissions can be set as default (the user can change the settins) or override (the settings cannot be changed).<br>
{{ form.permissionsDorO }}
<label for="{{ form.permissionsType.id_for_label }}">Permission type:</label>
{{ form.permissionsType }}<br><br>
{{ form.enableKeyboard }} <label for="{{ form.enableKeyboard.id_for_label }}">Enable keyboard/mouse</label>
{{ form.enableClipboard }} <label for="{{ form.enableClipboard.id_for_label }}">Enable clipboard</label><br>
{{ form.enableFileTransfer }} <label for="{{ form.enableFileTransfer.id_for_label }}">Enable file transfer</label>
{{ form.enableAudio }} <label for="{{ form.enableAudio.id_for_label }}">Enable audio</label><br>
{{ form.enableTCP }} <label for="{{ form.enableTCP.id_for_label }}">Enable TCP tunneling</label>
{{ form.enableRemoteRestart }} <label for="{{ form.enableRemoteRestart.id_for_label }}">Enable remote restart</label><br>
{{ form.enableRecording }} <label for="{{ form.enableRecording.id_for_label }}">Enable recording session</label>
{{ form.enableBlockingInput }} <label for="{{ form.enableBlockingInput.id_for_label }}">Enable blocking user input</label><br>
{{ form.enableRemoteModi }} <label for="{{ form.enableRemoteModi.id_for_label }}">Enable remote configuration modification</label><br><br>
</div>
<div class="section">
<h2>Other</h2>
{{ form.removeWallpaper }} <label for="{{ form.removeWallpaper.id_for_label }}">Remove wallpaper during incoming sessions</label><br><br>
<label for="{{ form.defaultManual.id_for_label }}">Default settings</label><br>
{{ form.defaultManual }}<br><br>
<label for="{{ form.overrideManual.id_for_label }}">Override settings</label><br>
{{ form.overrideManual }}<br><br>
</div>
<div class="section">
<button type="submit">Submit</button> Generate a custom client exe file
</div>
</form>
</body>
</html>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Generating Exe File</title>
</head>
<body>
Please wait...This can take 10-15 minutes (or longer if there are other users).<br><br>
Status: {{status}}
<script>
setTimeout(function() {
window.location.replace('/check_for_file?filename={{filename}}&uuid={{uuid}}');
}, 5000); // 5000 milliseconds = 5 seconds
</script>
</body>
</html>

3
rdgenerator/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

253
rdgenerator/views.py Normal file

File diff suppressed because one or more lines are too long

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
django
requests

19
setup.txt Normal file
View File

@@ -0,0 +1,19 @@
To fully host the client generator yourself, you will need to following:
1) A Github account that has a fork of rustdesk
2) A Github fine-grained access token with permissions for your rustdesk repository
3) An FTP server to upload the generated clients
4) On the server running the client generator:
a) environment variables:
GHUSER="your github username"
GHBEARER="your fine-graned access token"
b) github secrets:
GENURL="example.com:8083"
GEN_FTP_SERVER="ftp.example.com"
GEN_FTP_USER="username"
GEN_FTP_PASSWORD="password"
c) optional github secrets (for signing the code):
WINDOWS_PFX_BASE64
WINDOWS_PFX_PASSWORD
WINDOWS_PFX_SHA1_THUMBPRINT
5) A windows computer or VM that is set up to build rustdesk, and is setup as a self-hosted github runner