Skip to content
Snippets Groups Projects
Commit 351b22ec authored by Alexis POYEN's avatar Alexis POYEN
Browse files

Feat : allow to update CSP

Was needed to download mabox GL dependencies
parent 425de039
No related branches found
No related tags found
No related merge requests found
......@@ -7,7 +7,7 @@ import (
"os"
"strconv"
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/middlewares"
"forge.grandlyon.com/gestion-des-assemblees/elections/pkg/middlewares"
)
const literralContentType = "Content-Type"
......
......@@ -6,7 +6,7 @@ import (
"forge.grandlyon.com/gestion-des-assemblees/elections/internal/auth"
"forge.grandlyon.com/gestion-des-assemblees/elections/internal/models"
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/middlewares"
"forge.grandlyon.com/gestion-des-assemblees/elections/pkg/middlewares"
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/common"
)
......@@ -47,6 +47,6 @@ func CreateRootMux(port int, staticDir string) RootMux {
mainMux.Handle("/", middlewares.NoCache(http.FileServer(&common.FallBackWrapper{Assets: http.Dir(staticDir)})))
// Put it together into the main handler
mux := http.NewServeMux()
mux.Handle(hostname+"/", middlewares.WebSecurity(mainMux, "*."+hostname+":*", false))
mux.Handle(hostname+"/", middlewares.WebSecurity(mainMux, "*."+hostname+":* *.mapbox.com *.grandlyon.com ", false))
return RootMux{mux, &m}
}
......@@ -11,7 +11,7 @@ import (
"syscall"
"time"
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/middlewares"
"forge.grandlyon.com/gestion-des-assemblees/elections/pkg/middlewares"
"forge.grandlyon.com/systemes-dinformation/project-template/sdk-go/pkg/tokens"
"forge.grandlyon.com/gestion-des-assemblees/elections/internal/mocks"
......
package middlewares
import (
"fmt"
"net/http"
"strconv"
)
// Cors enables CORS Request on server (for development purposes)
func Cors(next http.Handler, allowedOrigin string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", allowedOrigin)
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, PROPFIND, MKCOL, MOVE, COPY")
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, XSRF-TOKEN, Authorization, Depth, Destination")
w.Header().Set("Access-Control-Allow-Credentials", "true")
next.ServeHTTP(w, req)
})
}
// WebSecurity adds good practices security headers on http responses
func WebSecurity(next http.Handler, source string, allowEvalInlineScript bool) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Strict-Transport-Security", "max-age=63072000")
var inline string
if allowEvalInlineScript {
inline = "'unsafe-inline' 'unsafe-eval'"
}
w.Header().Set("Content-Security-Policy", fmt.Sprintf("default-src %[1]v 'self'; img-src %[1]v 'self' data: blob:; script-src %[1]v 'self' %[2]v; style-src %[1]v 'self' 'unsafe-inline'; frame-src %[1]v; frame-ancestors %[1]v; worker-src blob: ;child-src blob: ;", source, inline))
//w.Header().Set("X-Frame-Options", "SAMEORIGIN") // Works fine with chrome but is not obsoleted by frame-src in firefox 72.0.2
w.Header().Set("X-XSS-Protection", "1; mode=block")
w.Header().Set("Referrer-Policy", "strict-origin")
w.Header().Set("X-Content-Type-Options", "nosniff")
next.ServeHTTP(w, req)
})
}
// NoCache disable caching
func NoCache(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Cache-Control", "no-store, must-revalidate")
next.ServeHTTP(w, req)
})
}
// GetFullHostname returns the full hostname of the server
func GetFullHostname(hostname string, port int) string {
if port == 80 || port == 443 {
return "https://" + hostname
}
return "https://" + hostname + ":" + strconv.Itoa(port)
}
This diff is collapsed.
// Imports
import * as PartyModel from "/services/model/party-model.js";
import * as AreaModel from "/services/model/area-model.js";
export async function mount(parent) {
const mapComponent = new MapComponent(parent);
return mapComponent;
}
class MapComponent {
constructor(parent) {
this.parent = parent;
this.PartyModel = PartyModel.getPartyModel();
this.AreaModel = AreaModel.getAreaModel();
}
async displayMapAreas() {
console.log("mount area map")
await this.initMap("/assets/maps/area.json", this.colorAreas);
}
async displayMapSections() {
console.log("mount section map")
await this.initMap("/assets/maps/section.json", this.colorSections);
}
async initMap(mapFile, colorationFunction) {
// Create datasource
const request = new XMLHttpRequest();
request.open("GET", mapFile, false);
request.send(null);
let dataSource = JSON.parse(request.responseText);
// Add parties and colors to datasource
dataSource = await colorationFunction(dataSource);
document.getElementById("map-component").innerHTML = "";
// Create a popup, but don't add it to the map yet.
let popup = new mapboxgl.Popup({
closeButton: false,
});
const map = new mapboxgl.Map({
container: "map-component", // container id
style: "/assets/mapbox/vector.json", // stylesheet location
center: [4.9, 45.75], // starting position [lng, lat]
zoom: 9.7, // starting zoom
});
// map.on("load", function () {
// map.addSource("data-source", {
// type: "geojson",
// data: dataSource,
// });
// map.addLayer(
// {
// id: "winners-fills",
// type: "fill",
// source: "data-source",
// layout: {},
// paint: {
// "fill-color": { type: "identity", property: "color" },
// "fill-opacity": 0.5,
// "fill-outline-color": "black",
// },
// },
// "place_label_city"
// );
// map.addLayer({
// id: "winners-names",
// type: "symbol",
// source: "data-source",
// filter: ["all"],
// layout: {
// "text-field": "{partyName}",
// "text-font": ["titiliumweb-regular"],
// },
// });
// });
}
async colorAreas(dataSource) {}
async colorSections(dataSource) {}
}
......@@ -6,6 +6,7 @@ import * as AreaModel from "/services/model/area-model.js";
import * as Scroller from "/services/common/scroller.js";
import * as ResultsFlow from "/components/visualization/results-flow.js";
import * as ResultsDetaileds from "/components/visualization/results-detaileds.js";
import * as ResultsMap from "/components/visualization/results-map.js";
export async function mount(where, parent) {
const resultZoneComponent = new ResultZoneComponent(parent);
......@@ -91,6 +92,7 @@ class ResultZoneComponent {
`;
this.ResultsFlow = await ResultsFlow.mount(this);
this.ResultsDetaileds = await ResultsDetaileds.mount(this);
this.ResultsMap = await ResultsMap.mount(this);
this.scroller = Scroller.scrollInit(
"news-flow",
document.getElementById("auto-scroll")
......@@ -136,6 +138,9 @@ class ResultZoneComponent {
let resultHandler = this;
document.getElementById("map-section").parentElement.className =
"column is-full";
console.log(this.ResultsMap);
if (this.parent.zone === "areas") this.ResultsMap.displayMapAreas();
else this.ResultsMap.displayMapSections();
document.getElementById("zoom-map").addEventListener("click", function () {
resultHandler.unZoom();
});
......@@ -215,6 +220,9 @@ class ResultZoneComponent {
<i class="fa fa-expand-arrows-alt"></i>
</span>`;
if (this.parent.zone === "areas") this.ResultsMap.displayMapAreas();
else this.ResultsMap.displayMapSections();
this.handleDom();
}
......
......@@ -104,12 +104,14 @@ class ResultComponent {
await this.hideGeneralSection();
document.getElementById("sections").setAttribute("class", "");
document.getElementById("areas").setAttribute("class", "is-active");
this.resultsZone.ResultsMap.displayMapAreas();
});
document.getElementById("sections").addEventListener("click", async () => {
resultHandler.zone = "sections";
await this.hideGeneralSection();
document.getElementById("areas").setAttribute("class", "");
document.getElementById("sections").setAttribute("class", "is-active");
this.resultsZone.ResultsMap.displayMapSections();
});
let radioButtons = document.getElementsByName("filter");
......
<!DOCTYPE html>
<html lang="en" class="has-navbar-fixed-top">
<head>
<title>Elections</title>
......@@ -9,6 +10,11 @@
<link rel="stylesheet" href="assets/bulma.min.css" />
<link rel="stylesheet" href="assets/animate.css" />
<link rel="stylesheet" href="style.css" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
<link
rel="stylesheet"
href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css"
/>
<script defer src="assets/fontawesome/brands.min.js"></script>
<script defer src="assets/fontawesome/solid.min.js"></script>
<script defer src="assets/fontawesome/fontawesome.min.js"></script>
......@@ -16,7 +22,12 @@
</head>
<body>
<!-- Navbar -->
<nav id="navbar" class="navbar is-dark is-fixed-top" role="navigation" aria-label="main navigation"></nav>
<nav
id="navbar"
class="navbar is-dark is-fixed-top"
role="navigation"
aria-label="main navigation"
></nav>
<!-- Main content-->
<section class="section" id="main" style="margin-bottom: 230px;"></section>
......@@ -29,7 +40,12 @@
<div class="navbar-brand">
<div class="navbar-item">
<div class="buttons">
<a class="button is-danger" href="https://forge.grandlyon.com/gestion-des-assemblees/elections" target="_blank" rel="noopener noreferrer">
<a
class="button is-danger"
href="https://forge.grandlyon.com/gestion-des-assemblees/elections"
target="_blank"
rel="noopener noreferrer"
>
<span class="icon">
<svg
class="svg-inline--fa fa-gitlab fa-w-16"
......@@ -45,8 +61,8 @@
<path
fill="currentColor"
d="M105.2 24.9c-3.1-8.9-15.7-8.9-18.9 0L29.8 199.7h132c-.1 0-56.6-174.8-56.6-174.8zM.9 287.7c-2.6 8 .3 16.9 7.1 22l247.9 184-226.2-294zm160.8-88l94.3 294 94.3-294zm349.4 88l-28.8-88-226.3 294 247.9-184c6.9-5.1 9.7-14 7.2-22zM425.7 24.9c-3.1-8.9-15.7-8.9-18.9 0l-56.6 174.8h132z"
></path></svg
>
></path>
</svg>
</span>
</a>
</div>
......
......@@ -211,4 +211,12 @@ select {
.clickable {
cursor: pointer;
}
\ No newline at end of file
}
#map-section {
height: 70vh;
}
#map-component {
height: 100%;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment