mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-08-02 17:30:36 +02:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
280b16c11c | ||
4b922c575e | |||
|
09528ed6b9 | ||
|
e61ff01518 | ||
|
a4c68bf7fe | ||
bb1c8cc25d | |||
4b06fa788d |
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@ TARGET = ./cc-backend
|
|||||||
VAR = ./var
|
VAR = ./var
|
||||||
CFG = config.json .env
|
CFG = config.json .env
|
||||||
FRONTEND = ./web/frontend
|
FRONTEND = ./web/frontend
|
||||||
VERSION = 1.2.1
|
VERSION = 1.2.2
|
||||||
GIT_HASH := $(shell git rev-parse --short HEAD || echo 'development')
|
GIT_HASH := $(shell git rev-parse --short HEAD || echo 'development')
|
||||||
CURRENT_TIME = $(shell date +"%Y-%m-%d:T%H:%M:%S")
|
CURRENT_TIME = $(shell date +"%Y-%m-%d:T%H:%M:%S")
|
||||||
LD_FLAGS = '-s -X main.date=${CURRENT_TIME} -X main.version=${VERSION} -X main.commit=${GIT_HASH}'
|
LD_FLAGS = '-s -X main.date=${CURRENT_TIME} -X main.version=${VERSION} -X main.commit=${GIT_HASH}'
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# `cc-backend` version 1.2.1
|
# `cc-backend` version 1.2.2
|
||||||
|
|
||||||
Supports job archive version 1 and database version 6.
|
Supports job archive version 1 and database version 6.
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ implementation of ClusterCockpit.
|
|||||||
|
|
||||||
** Breaking changes **
|
** Breaking changes **
|
||||||
|
|
||||||
* The LDAP configuration option user_filter was changed and now should not include
|
* The LDAP configuration option `user_filter` was changed and now should not include
|
||||||
the uid wildcard. Example:
|
the uid wildcard. Example:
|
||||||
- Old: `"user_filter": "(&(objectclass=posixAccount)(uid=*))"`
|
- Old: `"user_filter": "(&(objectclass=posixAccount)(uid=*))"`
|
||||||
- New: `"user_filter": "(&(objectclass=posixAccount))"`
|
- New: `"user_filter": "(&(objectclass=posixAccount))"`
|
||||||
|
@@ -6,6 +6,7 @@ package auth
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
|
"database/sql"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -152,6 +153,22 @@ func (ja *JWTCookieSessionAuthenticator) Login(
|
|||||||
claims := token.Claims.(jwt.MapClaims)
|
claims := token.Claims.(jwt.MapClaims)
|
||||||
sub, _ := claims["sub"].(string)
|
sub, _ := claims["sub"].(string)
|
||||||
|
|
||||||
|
var roles []string
|
||||||
|
projects := make([]string, 0)
|
||||||
|
|
||||||
|
if jc.ValidateUser {
|
||||||
|
var err error
|
||||||
|
user, err = repository.GetUserRepository().GetUser(sub)
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
log.Errorf("Error while loading user '%v'", sub)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deny any logins for unknown usernames
|
||||||
|
if user == nil {
|
||||||
|
log.Warn("Could not find user from JWT in internal database.")
|
||||||
|
return nil, errors.New("unknown user")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
var name string
|
var name string
|
||||||
if wrap, ok := claims["name"].(map[string]interface{}); ok {
|
if wrap, ok := claims["name"].(map[string]interface{}); ok {
|
||||||
if vals, ok := wrap["values"].([]interface{}); ok {
|
if vals, ok := wrap["values"].([]interface{}); ok {
|
||||||
@@ -165,18 +182,6 @@ func (ja *JWTCookieSessionAuthenticator) Login(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var roles []string
|
|
||||||
|
|
||||||
if jc.ValidateUser {
|
|
||||||
// Deny any logins for unknown usernames
|
|
||||||
if user == nil {
|
|
||||||
log.Warn("Could not find user from JWT in internal database.")
|
|
||||||
return nil, errors.New("unknown user")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take user roles from database instead of trusting the JWT
|
|
||||||
roles = user.Roles
|
|
||||||
} else {
|
|
||||||
// Extract roles from JWT (if present)
|
// Extract roles from JWT (if present)
|
||||||
if rawroles, ok := claims["roles"].([]interface{}); ok {
|
if rawroles, ok := claims["roles"].([]interface{}); ok {
|
||||||
for _, rr := range rawroles {
|
for _, rr := range rawroles {
|
||||||
@@ -185,20 +190,6 @@ func (ja *JWTCookieSessionAuthenticator) Login(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// (Ask browser to) Delete JWT cookie
|
|
||||||
deletedCookie := &http.Cookie{
|
|
||||||
Name: jc.CookieName,
|
|
||||||
Value: "",
|
|
||||||
Path: "/",
|
|
||||||
MaxAge: -1,
|
|
||||||
HttpOnly: true,
|
|
||||||
}
|
|
||||||
http.SetCookie(rw, deletedCookie)
|
|
||||||
|
|
||||||
if user == nil {
|
|
||||||
projects := make([]string, 0)
|
|
||||||
user = &schema.User{
|
user = &schema.User{
|
||||||
Username: sub,
|
Username: sub,
|
||||||
Name: name,
|
Name: name,
|
||||||
@@ -215,5 +206,15 @@ func (ja *JWTCookieSessionAuthenticator) Login(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (Ask browser to) Delete JWT cookie
|
||||||
|
deletedCookie := &http.Cookie{
|
||||||
|
Name: jc.CookieName,
|
||||||
|
Value: "",
|
||||||
|
Path: "/",
|
||||||
|
MaxAge: -1,
|
||||||
|
HttpOnly: true,
|
||||||
|
}
|
||||||
|
http.SetCookie(rw, deletedCookie)
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -78,6 +79,22 @@ func (ja *JWTSessionAuthenticator) Login(
|
|||||||
claims := token.Claims.(jwt.MapClaims)
|
claims := token.Claims.(jwt.MapClaims)
|
||||||
sub, _ := claims["sub"].(string)
|
sub, _ := claims["sub"].(string)
|
||||||
|
|
||||||
|
var roles []string
|
||||||
|
projects := make([]string, 0)
|
||||||
|
|
||||||
|
if config.Keys.JwtConfig.ValidateUser {
|
||||||
|
var err error
|
||||||
|
user, err = repository.GetUserRepository().GetUser(sub)
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
log.Errorf("Error while loading user '%v'", sub)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deny any logins for unknown usernames
|
||||||
|
if user == nil {
|
||||||
|
log.Warn("Could not find user from JWT in internal database.")
|
||||||
|
return nil, errors.New("unknown user")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
var name string
|
var name string
|
||||||
if wrap, ok := claims["name"].(map[string]interface{}); ok {
|
if wrap, ok := claims["name"].(map[string]interface{}); ok {
|
||||||
if vals, ok := wrap["values"].([]interface{}); ok {
|
if vals, ok := wrap["values"].([]interface{}); ok {
|
||||||
@@ -91,18 +108,6 @@ func (ja *JWTSessionAuthenticator) Login(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var roles []string
|
|
||||||
|
|
||||||
if config.Keys.JwtConfig.ValidateUser {
|
|
||||||
// Deny any logins for unknown usernames
|
|
||||||
if user == nil {
|
|
||||||
log.Warn("Could not find user from JWT in internal database.")
|
|
||||||
return nil, errors.New("unknown user")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take user roles from database instead of trusting the JWT
|
|
||||||
roles = user.Roles
|
|
||||||
} else {
|
|
||||||
// Extract roles from JWT (if present)
|
// Extract roles from JWT (if present)
|
||||||
if rawroles, ok := claims["roles"].([]interface{}); ok {
|
if rawroles, ok := claims["roles"].([]interface{}); ok {
|
||||||
for _, rr := range rawroles {
|
for _, rr := range rawroles {
|
||||||
@@ -113,23 +118,17 @@ func (ja *JWTSessionAuthenticator) Login(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rawprojs, ok := claims["projects"].([]interface{}); ok {
|
||||||
|
for _, pp := range rawprojs {
|
||||||
|
if p, ok := pp.(string); ok {
|
||||||
|
projects = append(projects, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if rawprojs, ok := claims["projects"]; ok {
|
||||||
|
projects = append(projects, rawprojs.([]string)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
projects := make([]string, 0)
|
|
||||||
// Java/Grails Issued Token
|
|
||||||
// if rawprojs, ok := claims["projects"].([]interface{}); ok {
|
|
||||||
// for _, pp := range rawprojs {
|
|
||||||
// if p, ok := pp.(string); ok {
|
|
||||||
// projects = append(projects, p)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else if rawprojs, ok := claims["projects"]; ok {
|
|
||||||
// for _, p := range rawprojs.([]string) {
|
|
||||||
// projects = append(projects, p)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if user == nil {
|
|
||||||
user = &schema.User{
|
user = &schema.User{
|
||||||
Username: sub,
|
Username: sub,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
let uplot = null
|
let uplot = null
|
||||||
let timeoutId = null
|
let timeoutId = null
|
||||||
|
|
||||||
|
const lineWidth = clusterCockpitConfig.plot_general_lineWidth
|
||||||
|
|
||||||
/* Data Format
|
/* Data Format
|
||||||
* data = [null, [], []] // 0: null-axis required for scatter, 1: Array of XY-Array for Scatter, 2: Optional Time Info
|
* data = [null, [], []] // 0: null-axis required for scatter, 1: Array of XY-Array for Scatter, 2: Optional Time Info
|
||||||
* data[1][0] = [100, 200, 500, ...] // X Axis -> Intensity (Vals up to clusters' flopRateScalar value)
|
* data[1][0] = [100, 200, 500, ...] // X Axis -> Intensity (Vals up to clusters' flopRateScalar value)
|
||||||
@@ -160,7 +162,7 @@
|
|||||||
const padding = u._padding // [top, right, bottom, left]
|
const padding = u._padding // [top, right, bottom, left]
|
||||||
|
|
||||||
u.ctx.strokeStyle = 'black'
|
u.ctx.strokeStyle = 'black'
|
||||||
u.ctx.lineWidth = 2
|
u.ctx.lineWidth = lineWidth
|
||||||
u.ctx.beginPath()
|
u.ctx.beginPath()
|
||||||
|
|
||||||
const ycut = 0.01 * cluster.memoryBandwidth.value
|
const ycut = 0.01 * cluster.memoryBandwidth.value
|
||||||
@@ -171,14 +173,17 @@
|
|||||||
flopRateScalarY = u.valToPos(cluster.flopRateScalar.value, 'y', true),
|
flopRateScalarY = u.valToPos(cluster.flopRateScalar.value, 'y', true),
|
||||||
flopRateSimdY = u.valToPos(cluster.flopRateSimd.value, 'y', true)
|
flopRateSimdY = u.valToPos(cluster.flopRateSimd.value, 'y', true)
|
||||||
|
|
||||||
if (scalarKneeX < width - padding[1]) { // Top horizontal roofline
|
// Debug get zoomLevel from browser
|
||||||
|
// console.log("Zoom", Math.round(window.devicePixelRatio * 100))
|
||||||
|
|
||||||
|
if (scalarKneeX < (width * window.devicePixelRatio) - (padding[1] * window.devicePixelRatio)) { // Top horizontal roofline
|
||||||
u.ctx.moveTo(scalarKneeX, flopRateScalarY)
|
u.ctx.moveTo(scalarKneeX, flopRateScalarY)
|
||||||
u.ctx.lineTo(width - padding[1], flopRateScalarY)
|
u.ctx.lineTo((width * window.devicePixelRatio) - (padding[1] * window.devicePixelRatio), flopRateScalarY)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simdKneeX < width - padding[1]) { // Lower horitontal roofline
|
if (simdKneeX < (width * window.devicePixelRatio) - (padding[1] * window.devicePixelRatio)) { // Lower horitontal roofline
|
||||||
u.ctx.moveTo(simdKneeX, flopRateSimdY)
|
u.ctx.moveTo(simdKneeX, flopRateSimdY)
|
||||||
u.ctx.lineTo(width - padding[1], flopRateSimdY)
|
u.ctx.lineTo((width * window.devicePixelRatio) - (padding[1] * window.devicePixelRatio), flopRateSimdY)
|
||||||
}
|
}
|
||||||
|
|
||||||
let x1 = u.valToPos(0.01, 'x', true),
|
let x1 = u.valToPos(0.01, 'x', true),
|
||||||
|
Reference in New Issue
Block a user