7 Commits

Author SHA1 Message Date
Jan Eitzinger
280b16c11c Merge pull request #218 from ClusterCockpit/hotfix
Prepare bugfix release
2023-09-15 16:02:19 +02:00
4b922c575e Prepare bugfix release 2023-09-15 15:59:54 +02:00
Jan Eitzinger
09528ed6b9 Merge pull request #217 from ClusterCockpit/hotfix
fix: adapt roofline render to browser zoomlevel
2023-09-15 12:34:47 +02:00
Christoph Kluge
e61ff01518 fix: adapt roofline render to browser zoomlevel
- make roofline linewidth configurable
2023-09-15 11:09:01 +02:00
Jan Eitzinger
a4c68bf7fe Merge pull request #215 from ClusterCockpit/hotfix
Hotfix
2023-09-08 12:17:49 +02:00
bb1c8cc25d fix: Move name extract from token in else branch 2023-09-08 12:11:49 +02:00
4b06fa788d fix: Fix buggy logic and simplify code if ValidateUser enabled 2023-09-08 11:50:28 +02:00
5 changed files with 74 additions and 69 deletions

View File

@@ -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}'

View File

@@ -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))"`

View File

@@ -6,6 +6,7 @@ package auth
import ( import (
"crypto/ed25519" "crypto/ed25519"
"database/sql"
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
@@ -152,31 +153,35 @@ func (ja *JWTCookieSessionAuthenticator) Login(
claims := token.Claims.(jwt.MapClaims) claims := token.Claims.(jwt.MapClaims)
sub, _ := claims["sub"].(string) sub, _ := claims["sub"].(string)
var name string
if wrap, ok := claims["name"].(map[string]interface{}); ok {
if vals, ok := wrap["values"].([]interface{}); ok {
if len(vals) != 0 {
name = fmt.Sprintf("%v", vals[0])
for i := 1; i < len(vals); i++ {
name += fmt.Sprintf(" %v", vals[i])
}
}
}
}
var roles []string var roles []string
projects := make([]string, 0)
if jc.ValidateUser { 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 // Deny any logins for unknown usernames
if user == nil { if user == nil {
log.Warn("Could not find user from JWT in internal database.") log.Warn("Could not find user from JWT in internal database.")
return nil, errors.New("unknown user") return nil, errors.New("unknown user")
} }
// Take user roles from database instead of trusting the JWT
roles = user.Roles
} else { } else {
var name string
if wrap, ok := claims["name"].(map[string]interface{}); ok {
if vals, ok := wrap["values"].([]interface{}); ok {
if len(vals) != 0 {
name = fmt.Sprintf("%v", vals[0])
for i := 1; i < len(vals); i++ {
name += fmt.Sprintf(" %v", vals[i])
}
}
}
}
// 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
} }

View File

@@ -5,6 +5,7 @@
package auth package auth
import ( import (
"database/sql"
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
@@ -78,31 +79,35 @@ func (ja *JWTSessionAuthenticator) Login(
claims := token.Claims.(jwt.MapClaims) claims := token.Claims.(jwt.MapClaims)
sub, _ := claims["sub"].(string) sub, _ := claims["sub"].(string)
var name string
if wrap, ok := claims["name"].(map[string]interface{}); ok {
if vals, ok := wrap["values"].([]interface{}); ok {
if len(vals) != 0 {
name = fmt.Sprintf("%v", vals[0])
for i := 1; i < len(vals); i++ {
name += fmt.Sprintf(" %v", vals[i])
}
}
}
}
var roles []string var roles []string
projects := make([]string, 0)
if config.Keys.JwtConfig.ValidateUser { 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 // Deny any logins for unknown usernames
if user == nil { if user == nil {
log.Warn("Could not find user from JWT in internal database.") log.Warn("Could not find user from JWT in internal database.")
return nil, errors.New("unknown user") return nil, errors.New("unknown user")
} }
// Take user roles from database instead of trusting the JWT
roles = user.Roles
} else { } else {
var name string
if wrap, ok := claims["name"].(map[string]interface{}); ok {
if vals, ok := wrap["values"].([]interface{}); ok {
if len(vals) != 0 {
name = fmt.Sprintf("%v", vals[0])
for i := 1; i < len(vals); i++ {
name += fmt.Sprintf(" %v", vals[i])
}
}
}
}
// 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(
} }
} }
} }
}
projects := make([]string, 0) if rawprojs, ok := claims["projects"].([]interface{}); ok {
// Java/Grails Issued Token for _, pp := range rawprojs {
// if rawprojs, ok := claims["projects"].([]interface{}); ok { if p, ok := pp.(string); ok {
// for _, pp := range rawprojs { projects = append(projects, p)
// if p, ok := pp.(string); ok { }
// projects = append(projects, p) }
// } } else if rawprojs, ok := claims["projects"]; ok {
// } projects = append(projects, rawprojs.([]string)...)
// } 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,

View File

@@ -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),