Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 0 additions & 6 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@

app = Flask(__name__)




# Setup redirect and hosting of frontend

@app.route('/')
def base():
return render_template('index.html', projecturl=os.environ["DOC_PROJECT_URL"], projectname=os.environ["DOC_PROJECT_NAME"])
Expand Down Expand Up @@ -87,8 +83,6 @@ def swaggerjson():
swagger_json["paths"]["/{}/{}".format(plugin,feature)] = paths
return swagger_json



if __name__ == '__main__':
app.debug = True
app.run(port=8080, host="0.0.0.0")
19 changes: 16 additions & 3 deletions app/plugins/mode/visitor_mode.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import base64
import json
import os
#todo input sanitization
Expand All @@ -9,8 +10,17 @@ def create(id): # POST
return {"error":'Visitormode already exists'}

else:
# Get the directory where the script is located
script_dir = os.path.dirname(os.path.realpath(__file__))

# Construct the full path to the image file
sample_image_path = os.path.join(script_dir, "visitor_mode_sample.png")

with open(sample_image_path, "rb") as image_file:
encoded_sample_image = base64.b64encode(image_file.read()).decode('utf-8')

f = open(configpath, "w+")
content = {"id":"visitormode", "enabled":False}
content = {"id":"visitormode", "is_enabled":False, "base64_placeholder_image": encoded_sample_image}
f.write(json.dumps(content))
f.close()
return {'ok':'Visitor Mode Created'}
Expand All @@ -27,6 +37,9 @@ def read(id=False): # GET
content += [json.loads(mode_content)]
return {'table':content}

elif id == "visitor_mode_image":
return '<html><body style="margin: 0px; height: 100vh; background-position: center; background-size: contain; background-color: black; background-image: url(data:image/png;base64,' + json.loads(open(configpath, "r").read())['base64_placeholder_image'] + '"></body></html>'

else: #return specific mode
configpath = "/data/modes/visitormode"
if os.path.isfile(configpath) == False:
Expand All @@ -38,14 +51,14 @@ def read(id=False): # GET
f.close()
return {'form':json.loads(content)}

def update(id, enabled): # POST
def update(id, is_enabled, base64_placeholder_image): # POST
configpath = "/data/modes/visitormode"
if os.path.isfile(configpath) == False:
return {"error":'Mode does not exist'}

else:
f = open(configpath, "w+")
content = {"id":"visitormode", "enabled":enabled}
content = {"id":"visitormode", "is_enabled":is_enabled, "base64_placeholder_image": base64_placeholder_image}
f.write(json.dumps(content))
f.close()
return {'ok':'Mode config updated'}
Expand Down
Binary file added app/plugins/mode/visitor_mode_sample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 10 additions & 7 deletions app/plugins/traefik/api_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ def read(id=False): # GET
else:
provider = {"http":{"routers": {},"services": {}, "middlewares": {}}}

r = requests.get('http://localhost:8080/plugins/screens/manage_screen')
data = json.loads(r.text)

# add ssp admin panel
provider['http']['routers']['admin'] = {'entryPoints': ['web', 'websecure'], 'service': 'admin', 'rule': 'HOST(`'+os.environ['SSP_DOMAIN']+'`)', 'tls': {'certResolver': 'myresolver'}, 'middlewares': ['ssp-auth']}
provider['http']['services']['admin'] = {'loadBalancer': {"servers": [ {'url': 'http://ssp:8080'} ] } }
Expand All @@ -33,12 +30,18 @@ def read(id=False): # GET
# provider['http']['middlewares']['redirect']={"redirectregex":{"regex":"^(https?://[^/]+/[a-z0-9_]+)$", "replacement":"${1}/"} }
provider['http']['middlewares']['strip'] = {"stripprefixregex":{"regex":"/[a-z0-9_]+"} }

#^(https?://[^/]+/?)$
mode_data = json.loads((requests.get('http://localhost:8080/plugins/mode/visitor_mode')).text)
screen_data = json.loads((requests.get('http://localhost:8080/plugins/screens/manage_screen')).text)

# add configured screens
for screen in data['table']:
for screen in screen_data['table']:
try:
screen_host = re.match("^(https?://[^/]+)/(.*)$", screen['url']).groups()[0]
screen_path = re.match("^(https?://[^/]+)/(.*)$", screen['url']).groups()[1]
if len(mode_data['table']) > 0 and mode_data['table'][0]['is_enabled'] == 'true':
screen_host = 'http://ssp:8080'
screen_path = '/plugins/mode/visitor_mode?id=visitor_mode_image'
else:
screen_host = re.match("^(https?://[^/]+)/(.*)$", screen['url']).groups()[0]
screen_path = re.match("^(https?://[^/]+)/(.*)$", screen['url']).groups()[1]

provider['http']['routers']['router_'+screen['id']] = {'entryPoints':['web', 'websecure'], 'service':'service_'+screen['id'], 'rule':'HOST(`'+screen['id']+'.'+os.environ["SSP_DOMAIN"]+'`)', 'middlewares':['service_'+screen['id']], 'tls':{'certResolver':'myresolver'}}
provider['http']['services']['service_'+screen['id']] = {"loadBalancer":{"servers":[{'url':screen_host}], "passHostHeader": False } }
Expand Down
39 changes: 29 additions & 10 deletions app/static/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Helper Functions
String.prototype.niceify = function() {
return this.replace('_', ' ').replace(/\b[a-z]/g, function(letter) {
return this.replaceAll('_', ' ').replace(/\b[a-z]/g, function(letter) {
return letter.toUpperCase();
});
}
Expand Down Expand Up @@ -44,11 +44,19 @@ function start_feature_read(plugin, feature, id) {
tablecode = '<div class="input-group mt-2"><input type="text" class="form-control" placeholder="New ID" aria-label="data" aria-describedby="arg1-button" id="arg1"><button class="btn btn-outline-secondary" type="button" id="new_button" onclick="start_feature_create(\''+plugin+'\', \''+feature+'\', document.getElementById(\'arg1\').value)">NEW</button></div>'
document.getElementById("results").innerHTML = tablecode
}
else {
else
dev_visiter_mode
tablecode = '<table class="table"><thead><tr><th></th><th></th>'
Object.keys(data['table'][0]).forEach((element) => tablecode+='<th scope="col">'+element+'</th>');
Object.keys(data['table'][0]).forEach((element) => tablecode+='<th scope="col">'+element.niceify()+'</th>');
tablecode += '</tr></thead><tbody>'
data['table'].forEach((element) => tablecode+='<tr><td><a onclick="start_feature_read(\''+plugin+'\', \''+feature+'\', \''+element['id']+'\')">Edit</a></td><td><a onclick="start_feature_delete(\''+plugin+'\', \''+feature+'\', \''+element['id']+'\')">Delete</a></td><td>'+Object.values(element).join('</td><td>')+'</td></tr>');
data['table'].forEach((element) => {
for(let key in element) {
if (key.startsWith('base64_')) {
element[key] = '<img src="data:image/png;base64,' + element[key] + '" style="max-width: 100px; max-height: 100px;">';
}
}
tablecode += '<tr><td><a onclick="start_feature_read(\''+plugin+'\', \''+feature+'\', \''+element['id']+'\')">Edit</a></td><td><a onclick="start_feature_delete(\''+plugin+'\', \''+feature+'\', \''+element['id']+'\')">Delete</a></td><td>'+Object.values(element).join('</td><td>')+'</td></tr>'
});
// tablecode+='<tr><td>NEW</td>';
// Object.keys(data['table'][0]).forEach((element) => tablecode+='<td></td>');
// tablecode += '<td></td></tr>'
Expand All @@ -60,19 +68,30 @@ function start_feature_read(plugin, feature, id) {

if ("form" in data){
formcode = '<form id="form" onsubmit="return false;">'
Object.keys(data['form']).forEach((element) => formcode+='<div class="mb-3"><label for="form_'+element+'" class="form-label">'+element+'</label><input type="text" class="form-control" name="'+element+'" id="form_'+element+'" '+((element=='id')?('readonly'):(''))+'></div>');
Object.keys(data['form']).forEach((element) => {
let input_elem = '';
if (element.startsWith('is_')) {
input_elem = '<select class="form-control" name="'+element+'" id="form_'+element+'"><option value="false">false</option><option value="true">true</option></select>';
}
else {
input_elem = '<input type="text" class="form-control" name="'+element+'" id="form_'+element+'" '+((element=='id')?('readonly'):(''))+'>';
}

formcode += '<div class="mb-3"><label for="form_'+element+'" class="form-label">'+element+'</label>'+input_elem+'</div>'
});

formcode += '<div class="mb-3"><button type="submit" class="btn btn-primary" onclick="start_feature_update(\''+plugin+'\', \''+feature+'\', $(\'#form\').serialize());start_feature_read(\''+plugin+'\', \''+feature+'\',\'\')">Save</button></div>'
formcode += '</form>'

document.getElementById("results").innerHTML = formcode

Object.values(data['form']).forEach(function callback(value, index) {
$('#form_'+Object.keys(data['form'])[index]).val(value);
Object.entries(data['form']).forEach(function([key, value], index) {
if (key.startsWith('is_')) {
$('#form_' + key).val(value.toString()); // Ensure value is a string
} else {
$('#form_' + key).val(value); // Apply to the key, not the index
}
});



}


Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ services:
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--providers.http.endpoint=http://ssp:8080/plugins/traefik/api_provider?id=api"
- "--providers.http.pollInterval=60s"
- "--providers.http.pollInterval=30s"
- "--certificatesresolvers.myresolver.acme.email=your-email@example.com"
- "--certificatesresolvers.myresolver.acme.storage=/data/acme.json"
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
Expand Down