mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 13:29:05 +01:00
Add legal texts. Add parametrized monitoring routes.
This commit is contained in:
parent
c98863f22e
commit
6025bbdecd
@ -6,7 +6,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ClusterCockpit/cc-backend/auth"
|
"github.com/ClusterCockpit/cc-backend/auth"
|
||||||
"github.com/ClusterCockpit/cc-backend/config"
|
"github.com/ClusterCockpit/cc-backend/config"
|
||||||
"github.com/ClusterCockpit/cc-backend/graph"
|
|
||||||
"github.com/ClusterCockpit/cc-backend/templates"
|
"github.com/ClusterCockpit/cc-backend/templates"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
@ -21,7 +20,7 @@ type Route struct {
|
|||||||
Setup func(i InfoType, r *http.Request) InfoType
|
Setup func(i InfoType, r *http.Request) InfoType
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupRoutes(router *mux.Router, resolver *graph.Resolver, routes []Route) {
|
func setupRoutes(router *mux.Router, routes []Route) {
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
router.HandleFunc(route.Route, func(rw http.ResponseWriter, r *http.Request) {
|
router.HandleFunc(route.Route, func(rw http.ResponseWriter, r *http.Request) {
|
||||||
conf, err := config.GetUIConfig(r)
|
conf, err := config.GetUIConfig(r)
|
||||||
|
327
server.go
327
server.go
@ -126,6 +126,50 @@ var programConfig ProgramConfig = ProgramConfig{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupJobRoute(i InfoType, r *http.Request) InfoType {
|
||||||
|
i["id"] = mux.Vars(r)["id"]
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupUserRoute(i InfoType, r *http.Request) InfoType {
|
||||||
|
i["id"] = mux.Vars(r)["id"]
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupClusterRoute(i InfoType, r *http.Request) InfoType {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
i["id"] = vars["cluster"]
|
||||||
|
i["cluster"] = vars["cluster"]
|
||||||
|
from, to := r.URL.Query().Get("from"), r.URL.Query().Get("to")
|
||||||
|
if from != "" || to != "" {
|
||||||
|
i["from"] = from
|
||||||
|
i["to"] = to
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupNodeRoute(i InfoType, r *http.Request) InfoType {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
i["cluster"] = vars["cluster"]
|
||||||
|
i["hostname"] = vars["hostname"]
|
||||||
|
from, to := r.URL.Query().Get("from"), r.URL.Query().Get("to")
|
||||||
|
if from != "" || to != "" {
|
||||||
|
i["from"] = from
|
||||||
|
i["to"] = to
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
var routes []Route = []Route{
|
||||||
|
{"/monitoring/jobs/", "monitoring/jobs.tmpl", "Jobs - ClusterCockpit", true, func(i InfoType, r *http.Request) InfoType { return i }},
|
||||||
|
{"/monitoring/job/{id:[0-9]+}", "monitoring/job.tmpl", "Job <ID> - ClusterCockpit", false, setupJobRoute},
|
||||||
|
{"/monitoring/users/", "monitoring/list.tmpl", "Users - ClusterCockpit", true, func(i InfoType, r *http.Request) InfoType { i["listType"] = "USER"; return i }},
|
||||||
|
{"/monitoring/projects/", "monitoring/list.tmpl", "Projects - ClusterCockpit", true, func(i InfoType, r *http.Request) InfoType { i["listType"] = "PROJECT"; return i }},
|
||||||
|
{"/monitoring/user/{id}", "monitoring/user.tmpl", "User <ID> - ClusterCockpit", true, setupUserRoute},
|
||||||
|
{"/monitoring/systems/{cluster}", "monitoring/systems.tmpl", "Cluster <ID> - ClusterCockpit", false, setupClusterRoute},
|
||||||
|
{"/monitoring/node/{cluster}/{hostname}", "monitoring/node.tmpl", "Node <ID> - ClusterCockpit", false, setupNodeRoute},
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var flagReinitDB, flagStopImmediately, flagSyncLDAP bool
|
var flagReinitDB, flagStopImmediately, flagSyncLDAP bool
|
||||||
var flagConfigFile string
|
var flagConfigFile string
|
||||||
@ -271,7 +315,6 @@ func main() {
|
|||||||
handleGetLogin := func(rw http.ResponseWriter, r *http.Request) {
|
handleGetLogin := func(rw http.ResponseWriter, r *http.Request) {
|
||||||
templates.Render(rw, r, "login.tmpl", &templates.Page{
|
templates.Render(rw, r, "login.tmpl", &templates.Page{
|
||||||
Title: "Login",
|
Title: "Login",
|
||||||
Login: &templates.LoginPage{},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,8 +327,19 @@ func main() {
|
|||||||
|
|
||||||
r.Handle("/playground", graphQLPlayground)
|
r.Handle("/playground", graphQLPlayground)
|
||||||
r.Handle("/login", auth.Login(db)).Methods(http.MethodPost)
|
r.Handle("/login", auth.Login(db)).Methods(http.MethodPost)
|
||||||
|
|
||||||
r.HandleFunc("/login", handleGetLogin).Methods(http.MethodGet)
|
r.HandleFunc("/login", handleGetLogin).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/logout", auth.Logout).Methods(http.MethodPost)
|
r.HandleFunc("/logout", auth.Logout).Methods(http.MethodPost)
|
||||||
|
r.HandleFunc("/imprint", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
templates.Render(rw, r, "imprint.tmpl", &templates.Page{
|
||||||
|
Title: "Imprint",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
r.HandleFunc("/privacy", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
templates.Render(rw, r, "privacy.tmpl", &templates.Page{
|
||||||
|
Title: "Privacy",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
secured := r.PathPrefix("/").Subrouter()
|
secured := r.PathPrefix("/").Subrouter()
|
||||||
if !programConfig.DisableAuthentication {
|
if !programConfig.DisableAuthentication {
|
||||||
@ -319,7 +373,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
monitoringRoutes(secured, resolver)
|
setupRoutes(secured, routes)
|
||||||
api.MountRoutes(secured)
|
api.MountRoutes(secured)
|
||||||
|
|
||||||
r.PathPrefix("/").Handler(http.FileServer(http.Dir(programConfig.StaticFiles)))
|
r.PathPrefix("/").Handler(http.FileServer(http.Dir(programConfig.StaticFiles)))
|
||||||
@ -395,27 +449,6 @@ func main() {
|
|||||||
log.Print("Gracefull shutdown completed!")
|
log.Print("Gracefull shutdown completed!")
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareRoute(r *http.Request) (map[string]interface{}, map[string]interface{}, error) {
|
|
||||||
conf, err := config.GetUIConfig(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
infos := map[string]interface{}{
|
|
||||||
"admin": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if user := auth.GetUser(r.Context()); user != nil {
|
|
||||||
infos["username"] = user.Username
|
|
||||||
infos["admin"] = user.HasRole(auth.RoleAdmin)
|
|
||||||
} else {
|
|
||||||
infos["username"] = false
|
|
||||||
infos["admin"] = false
|
|
||||||
}
|
|
||||||
|
|
||||||
return conf, infos, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildFilterPresets(query url.Values) map[string]interface{} {
|
func buildFilterPresets(query url.Values) map[string]interface{} {
|
||||||
filterPresets := map[string]interface{}{}
|
filterPresets := map[string]interface{}{}
|
||||||
|
|
||||||
@ -465,152 +498,152 @@ func buildFilterPresets(query url.Values) map[string]interface{} {
|
|||||||
return filterPresets
|
return filterPresets
|
||||||
}
|
}
|
||||||
|
|
||||||
func monitoringRoutes(router *mux.Router, resolver *graph.Resolver) {
|
// func monitoringRoutes(router *mux.Router, resolver *graph.Resolver) {
|
||||||
|
|
||||||
router.HandleFunc("/monitoring/jobs/", func(rw http.ResponseWriter, r *http.Request) {
|
// router.HandleFunc("/monitoring/jobs/", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
conf, infos, err := prepareRoute(r)
|
// conf, infos, err := prepareRoute(r)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
// http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
templates.Render(rw, r, "monitoring/jobs.tmpl", &templates.Page{
|
// templates.Render(rw, r, "monitoring/jobs.tmpl", &templates.Page{
|
||||||
Title: "Jobs - ClusterCockpit",
|
// Title: "Jobs - ClusterCockpit",
|
||||||
Config: conf,
|
// Config: conf,
|
||||||
Infos: infos,
|
// Infos: infos,
|
||||||
FilterPresets: buildFilterPresets(r.URL.Query()),
|
// FilterPresets: buildFilterPresets(r.URL.Query()),
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
router.HandleFunc("/monitoring/job/{id:[0-9]+}", func(rw http.ResponseWriter, r *http.Request) {
|
// router.HandleFunc("/monitoring/job/{id:[0-9]+}", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
conf, infos, err := prepareRoute(r)
|
// conf, infos, err := prepareRoute(r)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
// http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
id := mux.Vars(r)["id"]
|
// id := mux.Vars(r)["id"]
|
||||||
job, err := resolver.Query().Job(r.Context(), id)
|
// job, err := resolver.Query().Job(r.Context(), id)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusNotFound)
|
// http.Error(rw, err.Error(), http.StatusNotFound)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
infos["id"] = id
|
// infos["id"] = id
|
||||||
infos["jobId"] = job.JobID
|
// infos["jobId"] = job.JobID
|
||||||
infos["clusterId"] = job.Cluster
|
// infos["clusterId"] = job.Cluster
|
||||||
|
|
||||||
templates.Render(rw, r, "monitoring/job.tmpl", &templates.Page{
|
// templates.Render(rw, r, "monitoring/job.tmpl", &templates.Page{
|
||||||
Title: fmt.Sprintf("Job %d - ClusterCockpit", job.JobID),
|
// Title: fmt.Sprintf("Job %d - ClusterCockpit", job.JobID),
|
||||||
Config: conf,
|
// Config: conf,
|
||||||
Infos: infos,
|
// Infos: infos,
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
router.HandleFunc("/monitoring/users/", func(rw http.ResponseWriter, r *http.Request) {
|
// router.HandleFunc("/monitoring/users/", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
conf, infos, err := prepareRoute(r)
|
// conf, infos, err := prepareRoute(r)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
// http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
infos["listType"] = "USER"
|
// infos["listType"] = "USER"
|
||||||
|
|
||||||
templates.Render(rw, r, "monitoring/list.tmpl", &templates.Page{
|
// templates.Render(rw, r, "monitoring/list.tmpl", &templates.Page{
|
||||||
Title: "Users - ClusterCockpit",
|
// Title: "Users - ClusterCockpit",
|
||||||
Config: conf,
|
// Config: conf,
|
||||||
FilterPresets: buildFilterPresets(r.URL.Query()),
|
// FilterPresets: buildFilterPresets(r.URL.Query()),
|
||||||
Infos: infos,
|
// Infos: infos,
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
router.HandleFunc("/monitoring/projects/", func(rw http.ResponseWriter, r *http.Request) {
|
// router.HandleFunc("/monitoring/projects/", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
conf, infos, err := prepareRoute(r)
|
// conf, infos, err := prepareRoute(r)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
// http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
infos["listType"] = "PROJECT"
|
// infos["listType"] = "PROJECT"
|
||||||
|
|
||||||
templates.Render(rw, r, "monitoring/list.tmpl", &templates.Page{
|
// templates.Render(rw, r, "monitoring/list.tmpl", &templates.Page{
|
||||||
Title: "Projects - ClusterCockpit",
|
// Title: "Projects - ClusterCockpit",
|
||||||
Config: conf,
|
// Config: conf,
|
||||||
FilterPresets: buildFilterPresets(r.URL.Query()),
|
// FilterPresets: buildFilterPresets(r.URL.Query()),
|
||||||
Infos: infos,
|
// Infos: infos,
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
router.HandleFunc("/monitoring/user/{id}", func(rw http.ResponseWriter, r *http.Request) {
|
// router.HandleFunc("/monitoring/user/{id}", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
conf, infos, err := prepareRoute(r)
|
// conf, infos, err := prepareRoute(r)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
// http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
id := mux.Vars(r)["id"]
|
// id := mux.Vars(r)["id"]
|
||||||
// TODO: One could check if the user exists, but that would be unhelpfull if authentication
|
// // TODO: One could check if the user exists, but that would be unhelpfull if authentication
|
||||||
// is disabled or the user does not exist but has started jobs.
|
// // is disabled or the user does not exist but has started jobs.
|
||||||
infos["username"] = id
|
// infos["username"] = id
|
||||||
|
|
||||||
templates.Render(rw, r, "monitoring/user.tmpl", &templates.Page{
|
// templates.Render(rw, r, "monitoring/user.tmpl", &templates.Page{
|
||||||
Title: fmt.Sprintf("User %s - ClusterCockpit", id),
|
// Title: fmt.Sprintf("User %s - ClusterCockpit", id),
|
||||||
Config: conf,
|
// Config: conf,
|
||||||
Infos: infos,
|
// Infos: infos,
|
||||||
FilterPresets: buildFilterPresets(r.URL.Query()),
|
// FilterPresets: buildFilterPresets(r.URL.Query()),
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
router.HandleFunc("/monitoring/systems/", func(rw http.ResponseWriter, r *http.Request) {
|
// router.HandleFunc("/monitoring/systems/", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
// TODO: List all clusters?
|
// // TODO: List all clusters?
|
||||||
http.Redirect(rw, r, "/", http.StatusTemporaryRedirect)
|
// http.Redirect(rw, r, "/", http.StatusTemporaryRedirect)
|
||||||
})
|
// })
|
||||||
|
|
||||||
router.HandleFunc("/monitoring/systems/{cluster}", func(rw http.ResponseWriter, r *http.Request) {
|
// router.HandleFunc("/monitoring/systems/{cluster}", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
conf, infos, err := prepareRoute(r)
|
// conf, infos, err := prepareRoute(r)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
// http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
// vars := mux.Vars(r)
|
||||||
infos["cluster"] = vars["cluster"]
|
// infos["cluster"] = vars["cluster"]
|
||||||
from, to := r.URL.Query().Get("from"), r.URL.Query().Get("to")
|
// from, to := r.URL.Query().Get("from"), r.URL.Query().Get("to")
|
||||||
if from != "" || to != "" {
|
// if from != "" || to != "" {
|
||||||
infos["from"] = from
|
// infos["from"] = from
|
||||||
infos["to"] = to
|
// infos["to"] = to
|
||||||
}
|
// }
|
||||||
|
|
||||||
templates.Render(rw, r, "monitoring/systems.tmpl", &templates.Page{
|
// templates.Render(rw, r, "monitoring/systems.tmpl", &templates.Page{
|
||||||
Title: fmt.Sprintf("Cluster %s - ClusterCockpit", vars["cluster"]),
|
// Title: fmt.Sprintf("Cluster %s - ClusterCockpit", vars["cluster"]),
|
||||||
Config: conf,
|
// Config: conf,
|
||||||
Infos: infos,
|
// Infos: infos,
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
router.HandleFunc("/monitoring/node/{cluster}/{hostname}", func(rw http.ResponseWriter, r *http.Request) {
|
// router.HandleFunc("/monitoring/node/{cluster}/{hostname}", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
conf, infos, err := prepareRoute(r)
|
// conf, infos, err := prepareRoute(r)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
// http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
// vars := mux.Vars(r)
|
||||||
infos["cluster"] = vars["cluster"]
|
// infos["cluster"] = vars["cluster"]
|
||||||
infos["hostname"] = vars["hostname"]
|
// infos["hostname"] = vars["hostname"]
|
||||||
from, to := r.URL.Query().Get("from"), r.URL.Query().Get("to")
|
// from, to := r.URL.Query().Get("from"), r.URL.Query().Get("to")
|
||||||
if from != "" || to != "" {
|
// if from != "" || to != "" {
|
||||||
infos["from"] = from
|
// infos["from"] = from
|
||||||
infos["to"] = to
|
// infos["to"] = to
|
||||||
}
|
// }
|
||||||
|
|
||||||
templates.Render(rw, r, "monitoring/node.tmpl", &templates.Page{
|
// templates.Render(rw, r, "monitoring/node.tmpl", &templates.Page{
|
||||||
Title: fmt.Sprintf("Host %s - ClusterCockpit", vars["hostname"]),
|
// Title: fmt.Sprintf("Host %s - ClusterCockpit", vars["hostname"]),
|
||||||
Config: conf,
|
// Config: conf,
|
||||||
Infos: infos,
|
// Infos: infos,
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
func loadEnv(file string) error {
|
func loadEnv(file string) error {
|
||||||
f, err := os.Open(file)
|
f, err := os.Open(file)
|
||||||
|
205
templates/imprint.tmpl
Normal file
205
templates/imprint.tmpl
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
{{define "navigation"}}
|
||||||
|
{{""}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "content"}}
|
||||||
|
<div class="container" style="margin-top:80px;margin-bottom:80px;">
|
||||||
|
<div class="row legal">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h1>Imprint</h1>
|
||||||
|
|
||||||
|
<h2>Website owner</h2>
|
||||||
|
|
||||||
|
<p>name</p>
|
||||||
|
<address>
|
||||||
|
address
|
||||||
|
</address>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Phone: +49-</li>
|
||||||
|
<li>
|
||||||
|
Fax: +49-</li>
|
||||||
|
<li>
|
||||||
|
E-Mail:
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Represented by</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Your institution
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Notice
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Website Contact (Webmaster)</h3>
|
||||||
|
|
||||||
|
<p>name</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Phone: +49-
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
E-Mail:
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>Responsible controlling authority</h3>
|
||||||
|
|
||||||
|
<address>
|
||||||
|
address
|
||||||
|
</address>
|
||||||
|
<p>
|
||||||
|
Website: </p>
|
||||||
|
|
||||||
|
<h3>ID numbers</h3>
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">VAT identification number</th>
|
||||||
|
<td>xxx</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Tax number</th>
|
||||||
|
<td>xxx</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">DUNS number</th>
|
||||||
|
<td>xxx</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">EORI number</th>
|
||||||
|
<td>xxx</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Bank details:</th>
|
||||||
|
<td>xxx
|
||||||
|
<ul>
|
||||||
|
<li>SWIFT/BIC-Code: </li>
|
||||||
|
<li>IBAN: </li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>Reporting misuse of computers and network resources</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Should you become aware of any kind of misuse of computers or network resources at XXX,
|
||||||
|
<a href="URL">please inform the department responsible for computer security</a> immediately.
|
||||||
|
|
||||||
|
<h2>Copyright</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Unless specified otherwise, all pages of the INSTITUTION
|
||||||
|
website are protected by copyright. This applies in
|
||||||
|
particular to texts, images, charts, and files
|
||||||
|
containing style, sound, video, or animation data; it
|
||||||
|
also includes the design of the website.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Reproduction or use of (parts) of the web pages in
|
||||||
|
electronic or printed form and their publication
|
||||||
|
(including on the Internet) is subject to prior
|
||||||
|
approval.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Press releases, publications, scripts and information
|
||||||
|
on lectures may be reprinted and evaluated provided
|
||||||
|
that the source is indicated. Furthermore, images,
|
||||||
|
charts, and files containing text or other information,
|
||||||
|
may, in part or in their entirety, be subject to the
|
||||||
|
copyright of third parties.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
All registered brands and trademarks mentioned on this
|
||||||
|
website and possibly protected by third parties are
|
||||||
|
subject without restriction to the respective
|
||||||
|
applicable trademark law and the property rights of
|
||||||
|
their respective owners. The mere mention of trademarks
|
||||||
|
on this website does not indicate that they are not
|
||||||
|
protected by third party rights.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Exclusion of liability</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This imprint only belongs to the following website:<br>
|
||||||
|
<strong><em>DOMAIN</em></strong><br> The website owner
|
||||||
|
is not responsible for other websites, that are not
|
||||||
|
listet above.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The operator has compiled and verified all information
|
||||||
|
provided with great care. However, we cannot assume
|
||||||
|
liability or furnish a guarantee that the data is
|
||||||
|
correct, complete or up-to-date, or regarding the
|
||||||
|
quality or constant availability of the information
|
||||||
|
provided.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
We will not be liable for any damages arising from
|
||||||
|
computer viruses or the installation and use of
|
||||||
|
software when accessing or downloading data from this
|
||||||
|
website.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Websites credited to an author reflect the opinions and insights of that author.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The operator expressly reserves the right to change,
|
||||||
|
amend or delete individual web pages, services or the
|
||||||
|
entire website without prior notice or to interrupt or
|
||||||
|
terminate the publication.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Links and references (disclaimer)</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The operator is only responsible for the original
|
||||||
|
content provided in accordance with the applicable
|
||||||
|
laws. This original content is to be distinguished from
|
||||||
|
links to the websites of other operators. Through these
|
||||||
|
references marked as ‘external links’, the
|
||||||
|
operator enables visitors to access ‘third-party
|
||||||
|
content’.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The operator is not responsible for this third-party
|
||||||
|
content as the operator does not initiate the data
|
||||||
|
transmission, does not choose the recipient of the
|
||||||
|
information and does not select or have any influence
|
||||||
|
on the information transmitted. The methods used to
|
||||||
|
provide access and link to this third-party information
|
||||||
|
also do not involve any automatic short-term storage,
|
||||||
|
resulting in a full exclusion of any liability for
|
||||||
|
third-party content on the operator’s part.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
When links to these websites were first incorporated,
|
||||||
|
however, the authors of the relevant websites or the
|
||||||
|
operator’s editors reviewed the external content to
|
||||||
|
ascertain whether it would possibly entail liability
|
||||||
|
under civil or criminal law. Should the operator become
|
||||||
|
aware or be made aware by others that the content of a
|
||||||
|
website linked from this site could constitute a civil
|
||||||
|
or criminal law violation, then the link will be
|
||||||
|
immediately removed as long as this is technically
|
||||||
|
feasible and within reasonable expectation.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Liability for illegal, inaccurate or incomplete content
|
||||||
|
and for damages resulting from the use or non-use of
|
||||||
|
information provided by third parties shall lie
|
||||||
|
exclusively with the respective operators of the
|
||||||
|
linked sites.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
@ -5,6 +5,7 @@
|
|||||||
{{define "stylesheets"}}
|
{{define "stylesheets"}}
|
||||||
<link rel='stylesheet' href='/build/jobs.css'>
|
<link rel='stylesheet' href='/build/jobs.css'>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{define "javascript"}}
|
{{define "javascript"}}
|
||||||
<script>
|
<script>
|
||||||
const filterPresets = {{ .FilterPresets }};
|
const filterPresets = {{ .FilterPresets }};
|
||||||
|
322
templates/privacy.tmpl
Normal file
322
templates/privacy.tmpl
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
{{define "navigation"}}
|
||||||
|
{{""}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "content"}}
|
||||||
|
<div class="container" style="margin-top:80px;margin-bottom:80px;">
|
||||||
|
<div class="row legal">
|
||||||
|
<div class="col-md">
|
||||||
|
<h1>Privacy</h1>
|
||||||
|
<p>
|
||||||
|
INSTITUION is
|
||||||
|
responsible for its websites within the meaning of the
|
||||||
|
General Data Protection Regulation (GDPR) and other
|
||||||
|
national data protection laws as well as other data
|
||||||
|
protection regulations. It is legally represented by
|
||||||
|
its XX. For contact details, please consult the
|
||||||
|
YYY.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The respective INSTITUION institutions are responsible for
|
||||||
|
any content they make available on the websites of
|
||||||
|
INSTITUION. For questions related to specific content,
|
||||||
|
please contact the person responsible as named
|
||||||
|
LINK of this web page.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Name and address of the Data Protection Officer</h2>
|
||||||
|
|
||||||
|
<address>
|
||||||
|
address
|
||||||
|
</address>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Telefon: </span> +49 </li>
|
||||||
|
<li>Fax:</span> +49 </li>
|
||||||
|
<li>E-Mail:</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>General information on data processing</h2>
|
||||||
|
|
||||||
|
<h3>Scope of processing of personal data</h3>
|
||||||
|
<p>
|
||||||
|
We only process our users’ personal data to the extent
|
||||||
|
necessary to provide services, content and a functional
|
||||||
|
website. As a rule, personal data are only processed after
|
||||||
|
the user gives their consent. An exception applies in those
|
||||||
|
cases where it is impractical to obtain the user’s
|
||||||
|
prior consent and the processing of such data is
|
||||||
|
permitted by law.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Legal basis for the processing of personal data</h3>
|
||||||
|
<p>
|
||||||
|
Art. 6 (1) (a) of the EU General Data Protection Regulation
|
||||||
|
(GDPR) forms the legal basis for us to obtain the
|
||||||
|
consent of a data subject for their personal data to be
|
||||||
|
processed.<br> When processing personal data required for
|
||||||
|
the performance of a contract in which the contractual
|
||||||
|
party is the data subject, Art. 6 (1) (b) GDPR forms the
|
||||||
|
legal basis. This also applies if data has to be processed
|
||||||
|
in order to carry out pre-contractual activities.<br> Art.
|
||||||
|
6 (1) (c) GDPR forms the legal basis if personal data has
|
||||||
|
to be processed in order to fulfil a legal obligation on
|
||||||
|
the part of our organisation.<br> Art. 6 (1) (d) GDPR forms
|
||||||
|
the legal basis in the case that vital interests of the
|
||||||
|
data subject or another natural person make the processing
|
||||||
|
of personal data necessary.<br> If data processing is
|
||||||
|
necessary in order to protect the legitimate interests of
|
||||||
|
our organisation or of a third party and if the interests,
|
||||||
|
basic rights and fundamental freedoms of the data subject
|
||||||
|
do not outweigh the interests mentioned above, Art. 6 (1)
|
||||||
|
(f) GDPR forms the legal basis for such data processing.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Deletion of data and storage period</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The personal data of the data subject are deleted or
|
||||||
|
blocked as soon as the reason for storing them ceases
|
||||||
|
to exist. Storage beyond this time period may occur if
|
||||||
|
provided for by European or national legislators in
|
||||||
|
directives under Union legislation, laws or other
|
||||||
|
regulations to which the data controller is subject.
|
||||||
|
Such data are also blocked or deleted if a storage period
|
||||||
|
prescribed by one of the above-named rules expires,
|
||||||
|
unless further storage of the data is necessary for
|
||||||
|
entering into or performing a contract.
|
||||||
|
</p>
|
||||||
|
<h2>Provision of the website and generation of log files</h2>
|
||||||
|
<h3>Description and scope of data processing</h3>
|
||||||
|
<p>
|
||||||
|
Each time our website is accessed, our system
|
||||||
|
automatically collects data and information from
|
||||||
|
the user’s computer system.<br> In this context, the
|
||||||
|
following data are collected:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Address (URL) of the website from which the file was requested
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Name of the retrieved file
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Date and time of the request
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Data volume transmitted
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Access status (file transferred, file not found, etc.)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Description of the type of web browser and/or operating system used
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Anonymised IP address of the requesting computer
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
The data stored are required exclusively for technical or
|
||||||
|
statistical purposes; no comparison with other data or
|
||||||
|
disclosure to third parties occurs, not even in part.
|
||||||
|
The data are stored in our system’s log files. This is not
|
||||||
|
the case for the user’s IP addresses or other data
|
||||||
|
that make it possible to assign the data to a specific
|
||||||
|
user: before data are stored, each dataset is anonymised by
|
||||||
|
changing the IP address. These data are not stored
|
||||||
|
together with other personal data .
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Legal basis for data processing</h3>
|
||||||
|
<p>
|
||||||
|
The legal basis for the temporary storage of data and
|
||||||
|
logfiles is §§ 14, 15 TMG, § 100 Abs. 1 TKG and Art. 4
|
||||||
|
BayDSG following the tasks of Art. 11 BayEGovG and Art. 7
|
||||||
|
and 34 BayHO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Purpose of data processing</h3>
|
||||||
|
<p>
|
||||||
|
The temporary storage of the IP address by the system is
|
||||||
|
necessary in order to deliver the website to the
|
||||||
|
user’s computer. For this purpose, the user’s IP address
|
||||||
|
must remain stored for the duration of the session.<br> The
|
||||||
|
storage of such data in log files takes place in order to
|
||||||
|
ensure the website’s functionality. These data also serve
|
||||||
|
to help us optimise the website and ensure that our IT
|
||||||
|
systems are secure. They are not evaluated for marketing
|
||||||
|
purposes in this respect.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Storage period</h3>
|
||||||
|
<p>
|
||||||
|
Data are deleted as soon as they are no longer necessary
|
||||||
|
for fulfilling the purpose for which they were
|
||||||
|
collected. If data have been collected for the purpose of
|
||||||
|
providing the website, they are deleted at the end of the
|
||||||
|
respective session.<br> If data are stored in log files,
|
||||||
|
they are deleted at the latest after seven days. A longer
|
||||||
|
storage period is possible. In this case, the users’ IP
|
||||||
|
addresses are deleted or masked so that they can no longer
|
||||||
|
be assigned to the client accessing the website.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Options for filing an objection or requesting removal</h3>
|
||||||
|
<p>
|
||||||
|
The collection of data for the purpose of providing the
|
||||||
|
website and the storage of such data in log files is
|
||||||
|
essential to the website’s operation. As a consequence,
|
||||||
|
the user has no possibility to object.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Use of cookies</h2>
|
||||||
|
<h3>Description and scope of data processing</h3>
|
||||||
|
<p>
|
||||||
|
Our website uses cookies. Cookies are text files that are
|
||||||
|
saved in the user’s web browser or by the web browser
|
||||||
|
on the user’s computer system. When a user accesses a
|
||||||
|
website, a cookie can be stored in the user’s operating
|
||||||
|
system. This cookie contains a character string that allows
|
||||||
|
the unique identification of the browser when the
|
||||||
|
website is accessed again.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
We use cookies to make our website more user-friendly. Some
|
||||||
|
parts of our website require that the requesting browser
|
||||||
|
can also be identified after changing pages.<br> During
|
||||||
|
this process, the following data are stored in the cookies
|
||||||
|
and transmitted:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Log-in information (only in the case of protected information that is made available exclusively to FAU members)
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Technical measures are taken to pseudonymise user data
|
||||||
|
collected in this way. This means that the data can no
|
||||||
|
longer be assigned to the user. The data are not stored
|
||||||
|
together with other personal data of the user.<br> When
|
||||||
|
accessing our website, a banner informs users that cookies
|
||||||
|
are used for analysis purposes and makes reference to this
|
||||||
|
data protection policy. In connection with this, users are
|
||||||
|
also instructed how they can block the storage of cookies
|
||||||
|
in their browser settings.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Legal basis for data processing</h3>
|
||||||
|
<p>
|
||||||
|
The legal basis for the temporary storage of data and
|
||||||
|
logfiles is §§ 14, 15 TMG, § 100 Abs. 1 TKG and Art. 4
|
||||||
|
BayDSG following the tasks of Art. 11 BayEGovG and
|
||||||
|
Art. 7 and 34 BayHO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Purpose of data processing</h3>
|
||||||
|
<p>
|
||||||
|
Analysis cookies are used for the purpose of improving the
|
||||||
|
quality of our website and its content. We learn
|
||||||
|
through the analysis cookies how the website is used and in
|
||||||
|
this way can continuously optimise our web presence.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Storage period, options for filing an objection or requesting removal</h3>
|
||||||
|
<p>
|
||||||
|
As cookies are stored on the user’s computer and are
|
||||||
|
transmitted from it to our website, users have full
|
||||||
|
control over the use of cookies. You can deactivate or
|
||||||
|
restrict the transmission of cookies by changing the
|
||||||
|
settings in your web browser. Cookies that are already
|
||||||
|
stored can be deleted at any time. This can also be done
|
||||||
|
automatically. If cookies are deactivated for our
|
||||||
|
website, it may be the case that not all of the website’s
|
||||||
|
functions can be used in full.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>SSL encryption</h2>
|
||||||
|
<p>
|
||||||
|
Our website uses SSL encryption for security reasons and to
|
||||||
|
protect the transmission of confidential information,
|
||||||
|
for example enquiries you send to us as operators of
|
||||||
|
the website. You can recognise an encrypted connection
|
||||||
|
when the browser’s address line changes from
|
||||||
|
<code>http://</code> to <code>https://</code> and a padlock
|
||||||
|
appears in your web browser.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If SSL encryption is activated, the data you transmit to us
|
||||||
|
cannot be read by third parties.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Rights of the data subject</h2>
|
||||||
|
<p>
|
||||||
|
With regard to the processing of your personal
|
||||||
|
data, you as a data subject are entitled to the
|
||||||
|
following rights pursuant to Art. 15 et seq. GDPR:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
You can request information as to whether we process
|
||||||
|
your personal data. If this is the case, you have the
|
||||||
|
right to information about this personal data as well
|
||||||
|
as further information in connection with the
|
||||||
|
processing (Art. 15 GDPR). Please note that this
|
||||||
|
right of access may be restricted or excluded in
|
||||||
|
certain cases (cf. in particular Art. 10 BayDSG).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
In the event that personal data about you is (no
|
||||||
|
longer) accurate or incomplete, you may request that
|
||||||
|
this data be corrected and, if necessary, completed
|
||||||
|
(Art. 16 GDPR).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
If the legal requirements are met, you can demand that
|
||||||
|
your personal data be erased (Art. 17 GDPR) or that
|
||||||
|
the processing of this data be restricted (Art. 18
|
||||||
|
DSGVO). However, the right to erasure pursuant to
|
||||||
|
Art. 17 (1) and (2) GDPR does not apply, inter alia,
|
||||||
|
if the processing of personal data is necessary for the
|
||||||
|
performance of a task carried out in the public
|
||||||
|
interest or in the exercise of official authority
|
||||||
|
or in the exercise of official authority vested (Art.
|
||||||
|
17 para. 3 letter b GDPR).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
If you have given your consent to the processing, you
|
||||||
|
have the right to withdrawal it at any time. The
|
||||||
|
withdrawal will only take effect in the future;
|
||||||
|
this means that the withdrawal does not affect the
|
||||||
|
lawfulness of the processing operations carried out
|
||||||
|
on the basis of the consent up to the withdrawal.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
For reasons arising from your particular situation, you
|
||||||
|
may also object to the processing of your personal
|
||||||
|
data by us at any time (Art. 21 GDPR). If the legal
|
||||||
|
requirements are met, we will subsequently no longer
|
||||||
|
process your personal data.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Insofar as you have consented to the processing of your
|
||||||
|
personal data or have agreed to the performance of
|
||||||
|
the contract and the data processing is carried out
|
||||||
|
automated, you may be entitled to data portability
|
||||||
|
(Art. 20 GDPR).
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
You have the right to lodge a complaint to a
|
||||||
|
supervisory authority within the meaning of Art. 51
|
||||||
|
GDPR about the processing of your personal data. The
|
||||||
|
responsible supervisory authority for XXX
|
||||||
|
authorities is YYY.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
@ -14,22 +14,19 @@ var templates map[string]*template.Template = map[string]*template.Template{}
|
|||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Title string
|
Title string
|
||||||
Login *LoginPage
|
Error string
|
||||||
|
Info string
|
||||||
FilterPresets map[string]interface{}
|
FilterPresets map[string]interface{}
|
||||||
Infos map[string]interface{}
|
Infos map[string]interface{}
|
||||||
Config map[string]interface{}
|
Config map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoginPage struct {
|
|
||||||
Error string
|
|
||||||
Info string
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
templatesDir = "./templates/"
|
templatesDir = "./templates/"
|
||||||
base := template.Must(template.ParseFiles(templatesDir + "base.tmpl"))
|
base := template.Must(template.ParseFiles(templatesDir + "base.tmpl"))
|
||||||
files := []string{
|
files := []string{
|
||||||
"home.tmpl", "404.tmpl", "login.tmpl",
|
"home.tmpl", "404.tmpl", "login.tmpl",
|
||||||
|
"imprint.tmpl", "privacy.tmpl",
|
||||||
"monitoring/jobs.tmpl",
|
"monitoring/jobs.tmpl",
|
||||||
"monitoring/job.tmpl",
|
"monitoring/job.tmpl",
|
||||||
"monitoring/list.tmpl",
|
"monitoring/list.tmpl",
|
||||||
|
Loading…
Reference in New Issue
Block a user