Api functional

root 2021-05-12 21:19:12 +02:00
parent 1ca4325f25
commit d397a41b17
30 changed files with 886 additions and 409 deletions

15
api.yml
View File

@ -4,12 +4,14 @@ networks:
services:
isard-sso-api:
build:
context: /root/gitlab/newdemocartic/digitaldemocratic/isard-sso/docker/api
dockerfile: Dockerfile
args:
DOMAIN: santantoni.duckdns.org
context: /root/gitlab/digitaldemocratic/isard-sso/docker/api
dockerfile: Dockerfile_nginx
target: production
container_name: isard-sso-api
environment:
BUILD_ROOT_PATH: /root/gitlab/newdemocartic/digitaldemocratic/isard-sso
BUILD_ROOT_PATH: /root/gitlab/digitaldemocratic/isard-sso
DATA_FOLDER: /opt/isard-sso/data
DB_FOLDER: /opt/isard-sso/db
DOMAIN: santantoni.duckdns.org
@ -27,18 +29,15 @@ services:
SRC_FOLDER: /opt/isard-sso/src
networks:
isard_net: {}
ports:
- published: 80
target: 7039
restart: unless-stopped
isard-sso-haproxy:
build:
context: /root/gitlab/newdemocartic/digitaldemocratic/isard-sso/docker/haproxy
context: /root/gitlab/digitaldemocratic/isard-sso/docker/haproxy
dockerfile: Dockerfile
target: production
container_name: isard-sso-haproxy
environment:
BUILD_ROOT_PATH: /root/gitlab/newdemocartic/digitaldemocratic/isard-sso
BUILD_ROOT_PATH: /root/gitlab/digitaldemocratic/isard-sso
DATA_FOLDER: /opt/isard-sso/data
DB_FOLDER: /opt/isard-sso/db
DOMAIN: santantoni.duckdns.org

View File

@ -4,4 +4,5 @@ services:
isard-sso-api:
volumes:
- ${BUILD_ROOT_PATH}/docker/api/src:/api:rw
- ${BUILD_ROOT_PATH}/docker/api/default.conf:/etc/nginx/conf.d/default.conf:rw
command: sleep infinity

View File

@ -4,8 +4,10 @@ services:
isard-sso-api:
build:
context: ${BUILD_ROOT_PATH}/docker/api
dockerfile: Dockerfile
dockerfile: Dockerfile_nginx
target: production
args:
DOMAIN: $DOMAIN
container_name: isard-sso-api
restart: unless-stopped
networks:

View File

@ -1,7 +1,7 @@
FROM alpine:3.13.5 as production
MAINTAINER isard <info@isard.com>
RUN apk add --no-cache python3 py3-pip py3-yaml
RUN apk add --no-cache python3 py3-pip
RUN pip3 install --upgrade pip
RUN apk add --no-cache --virtual .build_deps \
build-base \
@ -11,7 +11,7 @@ COPY ./requirements.pip3 /requirements.pip3
RUN pip3 install --no-cache-dir -r requirements.pip3
RUN apk del .build_deps
RUN apk add curl
RUN apk add curl py3-yaml
COPY ./src /api

View File

@ -0,0 +1,28 @@
#FROM alpine:3.13.5 as build
FROM nginx:alpine as production
MAINTAINER isard <info@isard.com>
RUN apk add --no-cache python3 py3-pip
RUN pip3 install --upgrade pip
RUN apk add --no-cache --virtual .build_deps \
build-base \
python3-dev \
libffi-dev
COPY ./requirements.pip3 /requirements.pip3
RUN pip3 install --no-cache-dir -r requirements.pip3
RUN apk del .build_deps
RUN apk add curl py3-yaml
COPY ./src /api
#EXPOSE 7039
#WORKDIR /api
#CMD [ "python3", "start.py" ]
#FROM nginx:alpine as production
COPY default.conf /etc/nginx/conf.d/default.conf
#COPY --from=build /api/api/static /usr/share/nginx/html
ADD entrypoint.sh /docker-entrypoint.d/
RUN chmod 775 /docker-entrypoint.d/entrypoint.sh
#CMD ["entrypoint.sh"]

54
docker/api/default.conf Normal file
View File

@ -0,0 +1,54 @@
upstream api {
server 127.0.0.1:7039 fail_timeout=0;
}
server {
listen 80;
server_name localhost;
root /api/api/static/;
expires max;
log_not_found off;
access_log off;
# location /header/json {
# proxy_pass http://127.0.0.1:7039/header/json;
# expires max;
# log_not_found off;
# access_log off;
# }
location /json {
alias /api/api/static/templates/header.json;
add_header Content-Type application/json;
index header.json;
expires max;
log_not_found off;
access_log off;
}
location /header/html {
alias /api/api/static/templates/header.html;
add_header Content-Type text/html;
index header.html;
expires max;
log_not_found off;
access_log off;
}
location /header/html/nextcloud {
alias /api/api/static/templates/header_nextcloud.html;
add_header Content-Type text/html;
index header_nextcloud.html
expires max;
log_not_found off;
access_log off;
}
location / {
try_files $uri $uri/
expires max;
log_not_found off;
access_log off;
}
}

3
docker/api/entrypoint.sh Normal file
View File

@ -0,0 +1,3 @@
cd /api
python3 start.py &
#nginx -g daemon off

View File

@ -9,7 +9,6 @@ itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
pycparser==2.20
rethinkdb==2.4.7
six==1.15.0
Werkzeug==1.0.1
zope.event==4.4

View File

@ -13,10 +13,6 @@ class loadConfig():
try:
app.config.setdefault('DOMAIN', os.environ['DOMAIN'])
# app.config.setdefault('LOG_LEVEL', os.environ['LOG_LEVEL'])
# app.config.setdefault('LOG_FILE', 'isard-api.log')
# app.debug=True if os.environ['LOG_LEVEL'] == 'DEBUG' else False
except Exception as e:
log.error(traceback.format_exc())
raise

View File

@ -5,46 +5,61 @@
# Alberto Larraz Dalmases
# License: AGPLv3
import time
from api import app
from api import app as application
from datetime import datetime, timedelta
import pprint
import logging
import traceback
import yaml
import yaml, json
from jinja2 import Environment, FileSystemLoader
class Menu():
def __init__(self):
self.menudict=self.gen_header()
pprint.pprint(self.menudict)
self.write_headers()
None
def gen_header(self):
with open(r'system.yaml') as yml:
system=yaml.load(yml, Loader=yaml.FullLoader)
apps_internal = []
for app in system['apps_internal']:
app['href']='https://'+app['subdomain']+'.'+application.config['DOMAIN']+app['href']
del app['subdomain']
apps_internal.append(app)
with open(r'custom.yaml') as yml:
custom=yaml.load(yml, Loader=yaml.FullLoader)
custom['background_login']='https://api.'+application.config['DOMAIN']+custom['background_login']
custom['logo']='https://api.'+application.config['DOMAIN']+custom['logo']
menudict={**custom,**{'apps_internal':apps_internal}}
menudict['user']={}
menudict['user']['account']='https://sso.'+application.config['DOMAIN']+system['user']['account']
menudict['user']['avatar']='https://sso.'+application.config['DOMAIN']+system['user']['avatar']
menudict['user']['password']='https://sso.'+application.config['DOMAIN']+system['user']['password']
return menudict
def write_headers(self):
env = Environment(loader=FileSystemLoader('api/static/_templates'))
template = env.get_template('apps.html')
output_from_parsed_template = template.render(data=self.menudict)
print(output_from_parsed_template)
with open("api/static/templates/header.html", "w") as fh:
fh.write(output_from_parsed_template)
with open("api/static/templates/header_nextcloud.html", "w") as fh:
fh.write(output_from_parsed_template)
with open("api/static/templates/header_nextcloud.html", "a") as fh:
with open("api/static/_templates/nextcloud.html", "r") as nextcloud:
fh.write(nextcloud.read())
with open("api/static/templates/header.json", "w") as fh:
fh.write(json.dumps(self.menudict))
def get_header(self):
header = { 'logo':'https://api.'+app.config['DOMAIN']+'/img/logo.png',
'backgroud_login': 'https://api.'+app.config['DOMAIN']+'/img/backgroupd.png',
'css': 'https://api.'+app.config['DOMAIN']+'/css/',
'html': '<h1>HTML</h1>',
'colours':{
'primary': 0xAABBCC,
'secondary': 0xDDEEFF,
'backgroud': 0x112233,
},
'user':{
'avatar': 'https://sso.'+app.config['DOMAIN']+'/auth/realms/master/avatar-provider',
'account': 'https://sso.'+app.config['DOMAIN']+'/auth/realms/master/account',
'password': 'https://sso.'+app.config['DOMAIN']+'/auth/realms/master/password',
},
'apps_internal':[{
'shortname': 'appid',
'name': 'Application',
'icon': 'fa-play',
'href': 'https://'},
],
'apps_external':[{
'shortname': 'appid',
'name': 'Application',
'icon': 'fa-play',
'href': 'https://'},],
}
return self.menudict
# with open('menu.yaml', 'w') as yml:
# print(yaml.dump(header, yml, allow_unicode=True))
return header

View File

@ -0,0 +1,45 @@
<div id="navbar-menu-apps">
<div id="menu-apps-btn">
<button type="button" id="dropdownMenuAppsButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<svg id="Menú_Apps" data-name="Menú Apps" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26">
<rect id="Rectángulo_2" data-name="Rectángulo 2" width="6" height="6" fill="#262626"/>
<rect id="Rectángulo_1447" data-name="Rectángulo 1447" width="6" height="6" transform="translate(0 10)" fill="#262626"/>
<rect id="Rectángulo_1450" data-name="Rectángulo 1450" width="6" height="6" transform="translate(0 20)" fill="#262626"/>
<rect id="Rectángulo_1440" data-name="Rectángulo 1440" width="6" height="6" transform="translate(10)" fill="#262626"/>
<rect id="Rectángulo_1446" data-name="Rectángulo 1446" width="6" height="6" transform="translate(10 10)" fill="#262626"/>
<rect id="Rectángulo_1449" data-name="Rectángulo 1449" width="6" height="6" transform="translate(10 20)" fill="#262626"/>
<rect id="Rectángulo_1441" data-name="Rectángulo 1441" width="6" height="6" transform="translate(20)" fill="#262626"/>
<rect id="Rectángulo_1445" data-name="Rectángulo 1445" width="6" height="6" transform="translate(20 10)" fill="#262626"/>
<rect id="Rectángulo_1448" data-name="Rectángulo 1448" width="6" height="6" transform="translate(20 20)" fill="#262626"/>
</svg>
</button>
<div id="dropdownMenuApps" class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton" >
<ul id="app-aapps">
{% for item in data.apps_internal %}
<li class="app {{ item.shorname }}">
<a href="{{ item.href }}" class="app-link" target="_blank">
<div class="icon {{ item.shorname }}">
<i class="{{ item.icon }}" aria-hidden="true"></i>
</div>
<div class="text">{{ item.name }}</div>
</a>
</li>
{% endfor %}
</ul>
<ul id="app-external" class="external-links">
{% for item in data.apps_external %}
<li class="app {{ item.shorname }}">
<a href="{{ item.href }}" class="app-link" target="_blank">
<div class="icon {{ item.shorname }}">
<i class="{{ item.icon }}" aria-hidden="true"></i>
</div>
<div class="text">{{ item.name }}</div>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>

View File

@ -0,0 +1,46 @@
<div id="navbar-nextcloud" class="header-right">
<div id="unified-search"></div>
<div id="notifications"></div>
<div id="contactsmenu">
<div class="icon-contacts menutoggle" tabindex="0" role="button"
aria-haspopup="true" aria-controls="contactsmenu-menu" aria-expanded="false">
<span class="hidden-visually"><?php p($l->t('Contacts'));?></span>
</div>
<div id="contactsmenu-menu" class="menu"
aria-label="<?php p($l->t('Contacts menu'));?>"></div>
</div>
<div id="settings">
<div id="expand" tabindex="0" role="button" class="menutoggle"
aria-label="<?php p($l->t('Settings'));?>"
aria-haspopup="true" aria-controls="expanddiv" aria-expanded="false">
<div class="avatardiv<?php if ($_['userAvatarSet']) {
print_unescaped(' avatardiv-shown');
} else {
print_unescaped('" style="display: none');
} ?>">
<?php if ($_['userAvatarSet']): ?>
<img alt="" width="32" height="32"
src="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 32, 'v' => $_['userAvatarVersion']]));?>"
srcset="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 64, 'v' => $_['userAvatarVersion']]));?> 2x, <?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 128, 'v' => $_['userAvatarVersion']]));?> 4x"
>
<?php endif; ?>
</div>
<div id="expandDisplayName" class="icon-settings-white"></div>
</div>
<nav class="settings-menu" id="expanddiv" style="display:none;"
aria-label="<?php p($l->t('Settings menu'));?>">
<ul>
<?php foreach ($_['settingsnavigation'] as $entry):?>
<li data-id="<?php p($entry['id']); ?>">
<a href="<?php print_unescaped($entry['href']); ?>"
<?php if ($entry["active"]): ?> class="active"<?php endif; ?>>
<img alt="" src="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>">
<?php p($entry['name']) ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
</div>
</div>

View File

@ -1,329 +0,0 @@
<!DOCTYPE html>
<html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" data-locale="<?php p($_['locale']); ?>" >
<head data-user="<?php p($_['user_uid']); ?>" data-user-displayname="<?php p($_['user_displayname']); ?>" data-requesttoken="<?php p($_['requesttoken']); ?>">
<meta charset="utf-8">
<title>
<?php
p(!empty($_['application'])?$_['application'].' - ':'');
p($theme->getTitle());
?>
</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<?php if ($theme->getiTunesAppId() !== '') { ?>
<meta name="apple-itunes-app" content="app-id=<?php p($theme->getiTunesAppId()); ?>">
<?php } ?>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="<?php p((!empty($_['application']) && $_['appid'] != 'files')? $_['application']:$theme->getTitle()); ?>">
<meta name="mobile-web-app-capable" content="yes">
<meta name="theme-color" content="<?php p($theme->getColorPrimary()); ?>">
<link rel="icon" href="<?php print_unescaped(image_path($_['appid'], 'favicon.ico')); /* IE11+ supports png */ ?>">
<link rel="apple-touch-icon" href="<?php print_unescaped(image_path($_['appid'], 'favicon-touch.png')); ?>">
<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path($_['appid'], 'favicon-touch.png')); ?>">
<link rel="mask-icon" sizes="any" href="<?php print_unescaped(image_path($_['appid'], 'favicon-mask.svg')); ?>" color="<?php p($theme->getColorPrimary()); ?>">
<link rel="manifest" href="<?php print_unescaped(image_path($_['appid'], 'manifest.json')); ?>">
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<link rel="stylesheet" href="/themes/digitaldemocratic/core/css/fontawesome/css/all.css">
<link rel="stylesheet" href="/themes/digitaldemocratic/core/css/dd.css">
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" src="/themes/digitaldemocratic/core/js/navbar.js"></script>
<?php emit_css_loading_tags($_); ?>
<?php emit_script_loading_tags($_); ?>
<?php print_unescaped($_['headers']); ?>
</head>
<body id="<?php p($_['bodyid']);?>">
<?php include 'layout.noscript.warning.php'; ?>
<?php foreach ($_['initialStates'] as $app => $initialState) { ?>
<input type="hidden" id="initial-state-<?php p($app); ?>" value="<?php p(base64_encode($initialState)); ?>">
<?php }?>
<a href="#app-content" class="button primary skip-navigation skip-content"><?php p($l->t('Skip to main content')); ?></a>
<a href="#app-navigation" class="button primary skip-navigation"><?php p($l->t('Skip to navigation of app')); ?></a>
<div id="notification-container">
<div id="notification"></div>
</div>
<header role="banner" id="header">
<div id="navbar-logo" class="header-left">
<a href="<?php print_unescaped(link_to('', 'index.php')); ?>"
id="nextcloud">
<img src="/themes/digitaldemocratic/core/img/logo.png" alt="" style="height: 60px;">
</a>
</div>
<div id="navbar-menu-apps">
<div id="menu-apps-btn">
<button type="button" id="dropdownMenuAppsButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<svg id="Menú_Apps" data-name="Menú Apps" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26">
<rect id="Rectángulo_2" data-name="Rectángulo 2" width="6" height="6" fill="#262626"/>
<rect id="Rectángulo_1447" data-name="Rectángulo 1447" width="6" height="6" transform="translate(0 10)" fill="#262626"/>
<rect id="Rectángulo_1450" data-name="Rectángulo 1450" width="6" height="6" transform="translate(0 20)" fill="#262626"/>
<rect id="Rectángulo_1440" data-name="Rectángulo 1440" width="6" height="6" transform="translate(10)" fill="#262626"/>
<rect id="Rectángulo_1446" data-name="Rectángulo 1446" width="6" height="6" transform="translate(10 10)" fill="#262626"/>
<rect id="Rectángulo_1449" data-name="Rectángulo 1449" width="6" height="6" transform="translate(10 20)" fill="#262626"/>
<rect id="Rectángulo_1441" data-name="Rectángulo 1441" width="6" height="6" transform="translate(20)" fill="#262626"/>
<rect id="Rectángulo_1445" data-name="Rectángulo 1445" width="6" height="6" transform="translate(20 10)" fill="#262626"/>
<rect id="Rectángulo_1448" data-name="Rectángulo 1448" width="6" height="6" transform="translate(20 20)" fill="#262626"/>
</svg>
</button>
<div id="dropdownMenuApps" class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton" >
<ul id="app-admin">
<li class="app roles">
<a href="https://sso.escola3.digitaldemocratic.net/auth/admin/" class="app-link" target="_blank">
<div class="icon roles">
<i class="fa fa-user-secret" aria-hidden="true"></i>
</div>
<div class="text">Rols</div>
</a>
</li>
<li class="app evaluation">
<a href="https://bfgh.aplicacions.ensenyament.gencat.cat/bfgh" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-edit"></i>
</div>
<div class="text">Avaluació</div>
</a>
</li>
</ul>
<ul id="app-apps" class="apps">
<li class="app cloud">
<a href="https://moodle.escola3.digitaldemocratic.net" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-graduation-cap"></i>
</div>
<div class="text">Aules</div>
</a>
</li>
<!--
<li class="app email">
<a href="/apps/mail" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-envelope"></i>
</div>
<div class="text">Correu</div>
</a>
</li>
<li class="app search">
<a href="http://duckduckgo.com" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-search" aria-hidden="true"></i>
</div>
<div class="text">Cercar</div>
</a>
</li>
-->
<li class="app create-files">
<a href="/apps/files" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-file-word"></i>
</div>
<div class="text">Arxius</div>
</a>
</li>
<li class="app form-feedback">
<a href="/apps/polls" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-chart-bar"></i>
</div>
<div class="text">Enquestes</div>
</a>
</li>
<li class="app form-feedback">
<a href="/apps/forms" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-check-square"></i>
</div>
<div class="text">Formularis</div>
</a>
</li>
<li class="app chats">
<a href="/apps/spreed" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-comment-dots"></i>
</div>
<div class="text">Xat</div>
</a>
</li>
<!--
<li class="app meet-jitsi">
<a href="http://meet.jit.si" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-video"></i>
</div>
<div class="text">Reunions Jitsi</div>
</a>
</li>
<li class="app meet-bbb">
<a href="https://bbb.digitaldemocratic.net" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-video"></i>
</div>
<div class="text">Reunions BBB</div>
</a>
</li>
-->
<li class="app blogs">
<a href="https://wp.escola3.digitaldemocratic.net/wp-login.php?saml_sso" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-rss" aria-hidden="true"></i>
</div>
<div class="text">Blogs</div>
</a>
</li>
<li class="app contacts">
<a href="/apps/contacts" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-users" aria-hidden="true"></i>
</div>
<div class="text">Contactes</div>
</a>
</li>
<li class="app schedule">
<a href="/apps/calendar" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-calendar" aria-hidden="true"></i>
</div>
<div class="text">Calendari</div>
</a>
</li>
<li class="app tasks">
<a href="/apps/tasks" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-list-ol" aria-hidden="true"></i>
</div>
<div class="text">Tasques</div>
</a>
</li>
<!--
<li class="app evaluation">
<a href="https://moodle.escola3.digitaldemocratic.net" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-edit"></i>
</div>
<div class="text">Avaluació</div>
</a>
</li>
-->
<li class="app photos">
<a href="/apps/photos" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-file-image"></i>
</div>
<div class="text">Fotos</div>
</a>
</li>
<li class="app maps">
<a href="/apps/maps" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-map-marker" aria-hidden="true"></i>
</div>
<div class="text">Mapes</div>
</a>
</li>
<li class="app pad">
<a href="https://pad.escola3.digitaldemocratic.net" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-file-alt"></i>
</div>
<div class="text">Pads</div>
</a>
</li>
</ul>
<ul id="app-external" class="external-links">
<li class="app youtube">
<a href="https://youtube.com" class="app-link" target="_blank">
<div class="icon">
<i class="fab fa-youtube"></i>
</div>
<div class="text">Youtube</div>
</a>
</li>
<li class="app dict">
<a href="http://diccionari.cat" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-book" aria-hidden="true"></i>
</div>
<div class="text">Diccionari</div>
</a>
</li>
<li class="app meet-jitsi">
<a href="http://meet.jit.si" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-video"></i>
</div>
<div class="text">Reunions Jitsi</div>
</a>
</li>
</ul>
</div>
</div>
</div>
<div id="navbar-nextcloud" class="header-right">
<div id="unified-search"></div>
<div id="notifications"></div>
<div id="contactsmenu">
<div class="icon-contacts menutoggle" tabindex="0" role="button"
aria-haspopup="true" aria-controls="contactsmenu-menu" aria-expanded="false">
<span class="hidden-visually"><?php p($l->t('Contacts'));?></span>
</div>
<div id="contactsmenu-menu" class="menu"
aria-label="<?php p($l->t('Contacts menu'));?>"></div>
</div>
<div id="settings">
<div id="expand" tabindex="0" role="button" class="menutoggle"
aria-label="<?php p($l->t('Settings'));?>"
aria-haspopup="true" aria-controls="expanddiv" aria-expanded="false">
<div class="avatardiv<?php if ($_['userAvatarSet']) {
print_unescaped(' avatardiv-shown');
} else {
print_unescaped('" style="display: none');
} ?>">
<?php if ($_['userAvatarSet']): ?>
<img alt="" width="32" height="32"
src="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 32, 'v' => $_['userAvatarVersion']]));?>"
srcset="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 64, 'v' => $_['userAvatarVersion']]));?> 2x, <?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 128, 'v' => $_['userAvatarVersion']]));?> 4x"
>
<?php endif; ?>
</div>
<div id="expandDisplayName" class="icon-settings-white"></div>
</div>
<nav class="settings-menu" id="expanddiv" style="display:none;"
aria-label="<?php p($l->t('Settings menu'));?>">
<ul>
<?php foreach ($_['settingsnavigation'] as $entry):?>
<li data-id="<?php p($entry['id']); ?>">
<a href="<?php print_unescaped($entry['href']); ?>"
<?php if ($entry["active"]): ?> class="active"<?php endif; ?>>
<img alt="" src="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>">
<?php p($entry['name']) ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
</div>
</div>
</header>
<div id="sudo-login-background" class="hidden"></div>
<form id="sudo-login-form" class="hidden" method="POST">
<label>
<?php p($l->t('This action requires you to confirm your password')); ?><br/>
<input type="password" class="question" autocomplete="new-password" name="question" value=" <?php /* Hack against browsers ignoring autocomplete="off" */ ?>"
placeholder="<?php p($l->t('Confirm your password')); ?>" />
</label>
<input class="confirm" value="<?php p($l->t('Confirm')); ?>" type="submit">
</form>
<div id="content" class="app-<?php p($_['appid']) ?>" role="main">
<?php print_unescaped($_['content']); ?>
</div>
</body>
</html>

View File

@ -9,12 +9,20 @@ import time,json
import sys,os
from flask import render_template, Response, request, redirect, url_for, jsonify
# from ..lib.menu import Menu
# menu = Menu()
from ..lib.menu import Menu
menu = Menu()
@app.route('/header/<format>', methods=['GET'])
def api_v2_header(format):
@app.route('/header/<format>/<application>', methods=['GET'])
def api_v2_header(format,application=False):
if application == False:
if format == 'json':
return json.dumps(app.menudict), 200, {'Content-Type': 'application/json'}
if application == False:
return json.dumps(menu.get_header()), 200, {'Content-Type': 'application/json'}
if format == 'html':
return render_template('header.html', data=app.menudict)
if application == False:
return render_template('header.html')
if application == 'nextcloud':
return render_template('header_nextcloud.html')
if application == 'wordpress':
return render_template('header_wordpress.html')

View File

@ -1,22 +0,0 @@
apps_external:
- href: https://
icon: fa-play
name: Application
shortname: appid
apps_internal:
- href: https://
icon: fa-play
name: Application
shortname: appid
backgroud_login: https://api.santantoni.duckdns.org/img/backgroupd.png
colours:
backgroud: 1122867
primary: 11189196
secondary: 14544639
css: https://api.santantoni.duckdns.org/css/
html: <h1>HTML</h1>
logo: https://api.santantoni.duckdns.org/img/logo.png
user:
account: https://sso.santantoni.duckdns.org/auth/realms/master/account
avatar: https://sso.santantoni.duckdns.org/auth/realms/master/avatar-provider
password: https://sso.santantoni.duckdns.org/auth/realms/master/password

View File

@ -6,8 +6,7 @@ monkey.patch_all()
import yaml
from api import app
with open(r'menu.yaml') as yml:
app.menudict=yaml.load(yml, Loader=yaml.FullLoader)
# import pprint
# pprint.pprint(app.yaml)
if __name__ == '__main__':

View File

@ -0,0 +1,65 @@
#!flask/bin/python
# coding=utf-8
import os
import logging as log
from flask import Flask, send_from_directory, render_template
app = Flask(__name__, static_url_path='')
app = Flask(__name__, template_folder='static/templates')
app.url_map.strict_slashes = False
'''
App secret key for encrypting cookies
You can generate one with:
import os
os.urandom(24)
And paste it here.
'''
app.secret_key = "Change this key!//\xf7\x83\xbe\x17\xfa\xa3zT\n\\]m\xa6\x8bF\xdd\r\xf7\x9e\x1d\x1f\x14'"
print('Starting isard-sso api...')
from api.lib.load_config import loadConfig
try:
loadConfig(app)
except:
print('Could not get environment variables...')
'''
Debug should be removed on production!
'''
if app.debug:
log.warning('Debug mode: {}'.format(app.debug))
else:
log.info('Debug mode: {}'.format(app.debug))
'''
Serve static files
'''
@app.route('/templates/<path:path>')
def send_templates(path):
return send_from_directory(os.path.join(app.root_path, 'static/templates'), path)
# @app.route('/static/<path:path>')
# def send_static_js(path):
# return send_from_directory(os.path.join(app.root_path, 'static'), path)
# @app.errorhandler(404)
# def not_found_error(error):
# return render_template('page_404.html'), 404
# @app.errorhandler(500)
# def internal_error(error):
# return render_template('page_500.html'), 500
'''
Import all views
'''
from .views import MenuViews

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python
# coding=utf-8
from api import app
import os, sys
import logging as log
import traceback
class loadConfig():
def __init__(self, app=None):
try:
app.config.setdefault('DOMAIN', os.environ['DOMAIN'])
except Exception as e:
log.error(traceback.format_exc())
raise

View File

@ -0,0 +1,46 @@
#!/usr/bin/env python
# coding=utf-8
# Copyright 2017 the Isard-vdi project authors:
# Josep Maria Viñolas Auquer
# Alberto Larraz Dalmases
# License: AGPLv3
import time
from api import app as application
from datetime import datetime, timedelta
import pprint
import logging
import traceback
import yaml
class Menu():
def __init__(self):
self.menudict=self.gen_header()
pprint.pprint(self.menudict)
None
def gen_header(self):
with open(r'system.yaml') as yml:
system=yaml.load(yml, Loader=yaml.FullLoader)
apps_internal = []
for app in system['apps_internal']:
app['href']='https://'+app['subdomain']+'.'+application.config['DOMAIN']+app['href']
del app['subdomain']
apps_internal.append(app)
with open(r'custom.yaml') as yml:
custom=yaml.load(yml, Loader=yaml.FullLoader)
custom['background_login']='https://api.'+application.config['DOMAIN']+custom['background_login']
custom['logo']='https://api.'+application.config['DOMAIN']+custom['logo']
menudict={**custom,**{'apps_internal':apps_internal}}
menudict['user']={}
menudict['user']['account']='https://sso.'+application.config['DOMAIN']+system['user']['account']
menudict['user']['avatar']='https://sso.'+application.config['DOMAIN']+system['user']['avatar']
menudict['user']['password']='https://sso.'+application.config['DOMAIN']+system['user']['password']
return menudict
def get_header(self):
return self.menudict
# with open('menu.yaml', 'w') as yml:
# print(yaml.dump(header, yml, allow_unicode=True))

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,196 @@
#body-user, #body-settings, #body-public {
font-family: 'Montserrat', sans-serif;
color: #262626;
}
#body-user #app-dashboard>h2, #body-settings #app-dashboard>h2, #body-public #app-dashboard>h2 {
color: #262626;
}
#body-user header#header, #body-settings header#header, #body-public header#header {
background-color: white !important;
height: 74px ;
box-shadow: 0 2px 4px #00000014;
border-bottom: 1px solid #262626;
background-image: inherit;
}
#theming-preview-logo, #header #nextcloud {
padding-left: 10px;
}
#header #unified-search svg {
fill: #262626;
width: 35px;
height: 35px;
}
#header .notifications .notifications-button img.svg {
background-color: #262626;
padding: 5px;
border-radius: 18px;
height: 23px;
width: 23px;
margin-left: 10px;
}
#header #contactsmenu {
display: flex;
align-items: center;
}
#header #contactsmenu .icon-contacts {
background-color: #262626;
padding: 5px;
border-radius: 18px;
height: 23px;
width: 23px;
opacity: 1;
margin-left: 10px;
}
#header #settings #expand .avatardiv {
height: 35px;
width: 35px;
}
#header #settings #expand .avatardiv img {
height: 35px;
width: 35px;
margin-left: 10px;
}
#header #unified-search a.header-menu__trigger {
opacity: 1;
}
#header #unified-search a.header-menu__trigger .magnify-icon {
width: 35px;
height: 35px;
}
#body-user div#content, #body-settings div#content, #body-public div#content {
padding-top: 75px;
}
#body-user div#content div#app-dashboard, #body-settings div#content div#app-dashboard, #body-public div#content div#app-dashboard {
background-image: none !important;
background-color: #F0F0F0!important;
}
#body-user div#app-navigation, #body-settings div#app-navigation, #body-public div#app-navigation {
top: 75px;
height: calc(100% - 75px);
color: #262626 !important;
}
#header .header-menu__wrapper[data-v-a58f012a] {
top: 65px;
}
#header #navbar-menu-apps #menu-apps-btn #dropdownMenuAppsButton {
cursor: pointer;
border: none;
background-color: inherit;
padding: 4px;
}
#header div#navbar-menu-apps {
display: flex;
align-items: center;
}
#header #navbar-menu-apps #menu-apps-btn {
margin-right: 20px;
cursor: pointer;
position: relative;
}
#header #navbar-menu-apps #menu-apps-btn #dropdownMenuAppsButton {
cursor: pointer;
border: none;
background-color: inherit;
padding: 4px;
}
#header #navbar-menu-apps .dropdown-menu {
display: none;
position: absolute;
border: 1px solid rgba(0,0,0,.15);
border-radius: 5px;
box-shadow: rgb(0 0 0 / 20%) 0 3px 8px;
margin-top: 15px;
padding: 10px;
max-height: 500px;
overflow-y: scroll;
z-index: 2000;
background-color: white;
top: 33px;
right: -14px;
left: auto;
}
#header #navbar-menu-apps .dropdown-menu ul {
list-style: none;
display: grid;
flex-wrap: wrap;
padding: 15px 2px 0 0;
margin-bottom: 0;
grid-template-columns: 82px 82px 82px;
grid-gap: 12px 2px;
}
#header #navbar-menu-apps .dropdown-menu ul#app-admin {
border-bottom: 1px solid #D9D9D9;
padding-bottom: 4px;
margin-bottom: 6px;
}
#header #navbar-menu-apps .dropdown-menu ul#app-external {
border-top: 1px solid #D9D9D9;
padding-top: 20px;
margin-top: 8px;
}
#header #navbar-menu-apps .dropdown-menu ul li.app a.app-link {
display: flex;
flex-direction: column;
align-items: center;
justify-content: start;
text-align: center;
color: #262626;
text-decoration: none;
}
#header #navbar-menu-apps .dropdown-menu ul li.app a.app-link .icon {
width: 40px;
height: 40px;
background-color: #d5045c;
border-radius: .25rem;
margin-right: 0;
display: flex;
align-items: center;
justify-content: center;
}
#header #navbar-menu-apps .dropdown-menu ul li.app a.app-link .text {
text-align: center;
margin-top: 4px;
height: 26px;
font-size: 13px;
line-height: 15px;
overflow-wrap: anywhere;
}
#header #navbar-menu-apps .dropdown-menu ul li.app a.app-link .icon i {
color: #fff;
font-size: 19px;
}
div#content-vue {
padding-top: 75px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -0,0 +1,5 @@
jQuery(document).ready(function() {
$('#dropdownMenuAppsButton').click(function (e) {
$('#dropdownMenuApps').toggle();
});
});

View File

@ -0,0 +1,208 @@
<div id="navbar-menu-apps">
<div id="menu-apps-btn">
<button type="button" id="dropdownMenuAppsButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<svg id="Menú_Apps" data-name="Menú Apps" xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26">
<rect id="Rectángulo_2" data-name="Rectángulo 2" width="6" height="6" fill="#262626"/>
<rect id="Rectángulo_1447" data-name="Rectángulo 1447" width="6" height="6" transform="translate(0 10)" fill="#262626"/>
<rect id="Rectángulo_1450" data-name="Rectángulo 1450" width="6" height="6" transform="translate(0 20)" fill="#262626"/>
<rect id="Rectángulo_1440" data-name="Rectángulo 1440" width="6" height="6" transform="translate(10)" fill="#262626"/>
<rect id="Rectángulo_1446" data-name="Rectángulo 1446" width="6" height="6" transform="translate(10 10)" fill="#262626"/>
<rect id="Rectángulo_1449" data-name="Rectángulo 1449" width="6" height="6" transform="translate(10 20)" fill="#262626"/>
<rect id="Rectángulo_1441" data-name="Rectángulo 1441" width="6" height="6" transform="translate(20)" fill="#262626"/>
<rect id="Rectángulo_1445" data-name="Rectángulo 1445" width="6" height="6" transform="translate(20 10)" fill="#262626"/>
<rect id="Rectángulo_1448" data-name="Rectángulo 1448" width="6" height="6" transform="translate(20 20)" fill="#262626"/>
</svg>
</button>
<div id="dropdownMenuApps" class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton" >
<ul id="app-admin">
<li class="app roles">
<a href="https://sso.escola3.digitaldemocratic.net/auth/admin/" class="app-link" target="_blank">
<div class="icon roles">
<i class="fa fa-user-secret" aria-hidden="true"></i>
</div>
<div class="text">Rols</div>
</a>
</li>
<li class="app evaluation">
<a href="https://bfgh.aplicacions.ensenyament.gencat.cat/bfgh" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-edit"></i>
</div>
<div class="text">Avaluació</div>
</a>
</li>
</ul>
<ul id="app-apps" class="apps">
<li class="app cloud">
<a href="https://moodle.escola3.digitaldemocratic.net" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-graduation-cap"></i>
</div>
<div class="text">Aules</div>
</a>
</li>
<!--
<li class="app email">
<a href="/apps/mail" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-envelope"></i>
</div>
<div class="text">Correu</div>
</a>
</li>
<li class="app search">
<a href="http://duckduckgo.com" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-search" aria-hidden="true"></i>
</div>
<div class="text">Cercar</div>
</a>
</li>
-->
<li class="app create-files">
<a href="/apps/files" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-file-word"></i>
</div>
<div class="text">Arxius</div>
</a>
</li>
<li class="app form-feedback">
<a href="/apps/polls" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-chart-bar"></i>
</div>
<div class="text">Enquestes</div>
</a>
</li>
<li class="app form-feedback">
<a href="/apps/forms" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-check-square"></i>
</div>
<div class="text">Formularis</div>
</a>
</li>
<li class="app chats">
<a href="/apps/spreed" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-comment-dots"></i>
</div>
<div class="text">Xat</div>
</a>
</li>
<!--
<li class="app meet-jitsi">
<a href="http://meet.jit.si" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-video"></i>
</div>
<div class="text">Reunions Jitsi</div>
</a>
</li>
<li class="app meet-bbb">
<a href="https://bbb.digitaldemocratic.net" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-video"></i>
</div>
<div class="text">Reunions BBB</div>
</a>
</li>
-->
<li class="app blogs">
<a href="https://wp.escola3.digitaldemocratic.net/wp-login.php?saml_sso" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-rss" aria-hidden="true"></i>
</div>
<div class="text">Blogs</div>
</a>
</li>
<li class="app contacts">
<a href="/apps/contacts" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-users" aria-hidden="true"></i>
</div>
<div class="text">Contactes</div>
</a>
</li>
<li class="app schedule">
<a href="/apps/calendar" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-calendar" aria-hidden="true"></i>
</div>
<div class="text">Calendari</div>
</a>
</li>
<li class="app tasks">
<a href="/apps/tasks" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-list-ol" aria-hidden="true"></i>
</div>
<div class="text">Tasques</div>
</a>
</li>
<!--
<li class="app evaluation">
<a href="https://moodle.escola3.digitaldemocratic.net" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-edit"></i>
</div>
<div class="text">Avaluació</div>
</a>
</li>
-->
<li class="app photos">
<a href="/apps/photos" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-file-image"></i>
</div>
<div class="text">Fotos</div>
</a>
</li>
<li class="app maps">
<a href="/apps/maps" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-map-marker" aria-hidden="true"></i>
</div>
<div class="text">Mapes</div>
</a>
</li>
<li class="app pad">
<a href="https://pad.escola3.digitaldemocratic.net" class="app-link" target="_blank">
<div class="icon">
<i class="far fa-file-alt"></i>
</div>
<div class="text">Pads</div>
</a>
</li>
</ul>
<ul id="app-external" class="external-links">
<li class="app youtube">
<a href="https://youtube.com" class="app-link" target="_blank">
<div class="icon">
<i class="fab fa-youtube"></i>
</div>
<div class="text">Youtube</div>
</a>
</li>
<li class="app dict">
<a href="http://diccionari.cat" class="app-link" target="_blank">
<div class="icon">
<i class="fa fa-book" aria-hidden="true"></i>
</div>
<div class="text">Diccionari</div>
</a>
</li>
<li class="app meet-jitsi">
<a href="http://meet.jit.si" class="app-link" target="_blank">
<div class="icon">
<i class="fas fa-video"></i>
</div>
<div class="text">Reunions Jitsi</div>
</a>
</li>
</ul>
</div>
</div>
</div>

View File

@ -0,0 +1,46 @@
<div id="navbar-nextcloud" class="header-right">
<div id="unified-search"></div>
<div id="notifications"></div>
<div id="contactsmenu">
<div class="icon-contacts menutoggle" tabindex="0" role="button"
aria-haspopup="true" aria-controls="contactsmenu-menu" aria-expanded="false">
<span class="hidden-visually"><?php p($l->t('Contacts'));?></span>
</div>
<div id="contactsmenu-menu" class="menu"
aria-label="<?php p($l->t('Contacts menu'));?>"></div>
</div>
<div id="settings">
<div id="expand" tabindex="0" role="button" class="menutoggle"
aria-label="<?php p($l->t('Settings'));?>"
aria-haspopup="true" aria-controls="expanddiv" aria-expanded="false">
<div class="avatardiv<?php if ($_['userAvatarSet']) {
print_unescaped(' avatardiv-shown');
} else {
print_unescaped('" style="display: none');
} ?>">
<?php if ($_['userAvatarSet']): ?>
<img alt="" width="32" height="32"
src="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 32, 'v' => $_['userAvatarVersion']]));?>"
srcset="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 64, 'v' => $_['userAvatarVersion']]));?> 2x, <?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 128, 'v' => $_['userAvatarVersion']]));?> 4x"
>
<?php endif; ?>
</div>
<div id="expandDisplayName" class="icon-settings-white"></div>
</div>
<nav class="settings-menu" id="expanddiv" style="display:none;"
aria-label="<?php p($l->t('Settings menu'));?>">
<ul>
<?php foreach ($_['settingsnavigation'] as $entry):?>
<li data-id="<?php p($entry['id']); ?>">
<a href="<?php print_unescaped($entry['href']); ?>"
<?php if ($entry["active"]): ?> class="active"<?php endif; ?>>
<img alt="" src="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>">
<?php p($entry['name']) ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
</div>
</div>

View File

@ -0,0 +1,28 @@
#!flask/bin/python
# coding=utf-8
from api import app
import logging as log
import traceback
from uuid import uuid4
import time,json
import sys,os
from flask import render_template, Response, request, redirect, url_for, jsonify
from ..lib.menu import Menu
menu = Menu()
@app.route('/header/<format>', methods=['GET'])
@app.route('/header/<format>/application', methods=['GET'])
def api_v2_header(format,application=False):
if application == False:
if format == 'json':
if application == False:
return json.dumps(menu.get_header()), 200, {'Content-Type': 'application/json'}
if format == 'html':
if application == False:
return render_template('header.html', data=menu.get_header())
if application == 'nextcloud':
return render_template('header_nextcloud.html', data=menu.get_header())
if application == 'wordpress':
return render_template('header_wordpress.html', data=menu.get_header())

View File

@ -0,0 +1,13 @@
#!flask/bin/python
# coding=utf-8
from gevent import monkey
monkey.patch_all()
import yaml
from api import app
# import pprint
# pprint.pprint(app.yaml)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7039, debug=False) #, logger=logger, engineio_logger=engineio_logger)

View File

@ -64,7 +64,8 @@ backend be_api
acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found
http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host
http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto
server api isard-sso-api:7039 check port 7039 inter 5s rise 2 fall 10 resolvers mydns init-addr none
server api isard-sso-api:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none
#server api isard-sso-api:7039 check port 7039 inter 5s rise 2 fall 10 resolvers mydns init-addr none
backend be_ipa
mode http