Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions cmd/laas/gen_external_ref_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ package main
import (
"errors"
"fmt"
"log"
"os"

"path/filepath"

"github.com/dave/jennifer/jen"
logger "github.com/fossology/LicenseDb/pkg/log"
"go.uber.org/zap"
"gopkg.in/yaml.v3"
)

Expand All @@ -41,12 +42,12 @@ func main() {

fieldsMetadata, err := os.ReadFile(PATH_EXTERNAL_REF_CONFIG_FILE)
if err != nil {
log.Fatalf("Failed to instantiate json schema for external ref in license: %v", err)
logger.LogFatal("Failed to instantiate json schema for external ref in license", zap.Error(err))
}

err = yaml.Unmarshal(fieldsMetadata, &externalRefFields)
if err != nil {
log.Fatalf("Failed to instantiate json schema for external ref in license: %v", err)
logger.LogFatal("Failed to instantiate json schema for external ref in license", zap.Error(err))
}

// REUSE-IgnoreStart
Expand Down Expand Up @@ -74,7 +75,7 @@ func main() {
err = fmt.Errorf("type %s in external_ref_fields.yaml is not supported", f.Type)
}
if err != nil {
log.Fatalf("Failed to instantiate json schema for external ref in license: %v", err)
logger.LogFatal("Failed to instantiate json schema for external ref in license", zap.Error(err))
return
}
field = field.Tag(map[string]string{"json": fmt.Sprintf("%s,omitempty", f.Name), "swaggerignore": "true"})
Expand Down
36 changes: 28 additions & 8 deletions pkg/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"errors"
"fmt"
"html"
"log"
"net/http"
"os"
"strconv"
Expand Down Expand Up @@ -176,7 +175,9 @@ func CreateOidcUser(c *gin.Context) {
Timestamp: time.Now().Format(time.RFC3339),
}
c.JSON(http.StatusInternalServerError, er)
log.Print("\033[31mError: OIDC environment variables not configured properly\033[0m")
logger.LogError(
"oidc environment variables not configured properly",
)
return
}

Expand Down Expand Up @@ -213,7 +214,11 @@ func CreateOidcUser(c *gin.Context) {

keyset, err := Jwks.Lookup(context.Background(), os.Getenv("JWKS_URI"))
if err != nil {
log.Print("\033[31mError: Failed jwk.Cache lookup from the oidc provider's URL\033[0m")
logger.LogError(
"failed jwk cache lookup from oidc provider",
zap.Error(err),
)

er := models.LicenseError{
Status: http.StatusInternalServerError,
Message: "Something went wrong",
Expand Down Expand Up @@ -242,7 +247,10 @@ func CreateOidcUser(c *gin.Context) {
}

if keyError {
log.Printf("\033[31mError: Token verification failed due to invalid alg header key field \033[0m")
logger.LogError(
"token verification failed",
zap.String("reason", "invalid alg header key field"),
)
er := models.LicenseError{
Status: http.StatusUnauthorized,
Message: "Please check your credentials and try again",
Expand All @@ -263,12 +271,18 @@ func CreateOidcUser(c *gin.Context) {
Timestamp: time.Now().Format(time.RFC3339),
}
c.JSON(http.StatusUnauthorized, er)
log.Printf("\033[31mError: Token verification failed \033[0m")
logger.LogError(
"token verification failed",
zap.String("stage", "jws_verify"),
)
return
}

parsedToken, err := jwt.Parse([]byte(tokenString), jwt.WithValidate(true), jwt.WithVerify(false))
if err != nil {
logger.LogError(
"token parsing failed",
zap.Error(err),
)
er := models.LicenseError{
Status: http.StatusUnauthorized,
Message: "Please check your credentials and try again",
Expand All @@ -290,7 +304,10 @@ func CreateOidcUser(c *gin.Context) {
Timestamp: time.Now().Format(time.RFC3339),
}
c.JSON(http.StatusUnauthorized, er)
log.Printf("\033[31mError: Issuer '%s' not supported\033[0m", iss)
logger.LogError(
"issuer not supported",
zap.String("issuer", iss),
)
return
}

Expand All @@ -313,7 +330,10 @@ func CreateOidcUser(c *gin.Context) {
Timestamp: time.Now().Format(time.RFC3339),
}
c.JSON(http.StatusUnauthorized, er)
log.Printf("\033[31mError: %s\033[0m", errMessage)
logger.LogError(
"error occurred",
zap.String("message", errMessage),
)
return
}
level := "USER"
Expand Down
105 changes: 75 additions & 30 deletions pkg/utils/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"os"
"reflect"
Expand All @@ -28,8 +27,10 @@ import (
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
"go.uber.org/zap"

"github.com/fossology/LicenseDb/pkg/db"
logger "github.com/fossology/LicenseDb/pkg/log"
"github.com/fossology/LicenseDb/pkg/models"
"github.com/fossology/LicenseDb/pkg/validations"
)
Expand Down Expand Up @@ -138,7 +139,6 @@ func InsertOrUpdateLicenseOnImport(lic *models.LicenseImportDTO, userId uuid.UUI
return errors.New(message)
}
newLicense = license

if *oldLicense.Text != *newLicense.Text {
if !*oldLicense.TextUpdatable {
message = "Field `text_updatable` needs to be true to update the text"
Expand Down Expand Up @@ -205,14 +205,19 @@ func InsertOrUpdateLicenseOnImport(lic *models.LicenseImportDTO, userId uuid.UUI
} else if lic.Shortname != nil {
erroredElem = *lic.Shortname
}
red := "\033[31m"
reset := "\033[0m"
log.Printf("%s%s: %s%s", red, erroredElem, message, reset)

logger.LogError(
"License import failed",
zap.String("license_id_or_shortname", erroredElem),
zap.String("message", message),
)
} else {
green := "\033[32m"
reset := "\033[0m"
log.Printf("%sImport for license '%s' successful%s", green, (*lic.Id).String(), reset)
logger.LogInfo(
"License import successful",
zap.String("license_id", (*lic.Id).String()),
)
}

return message, importStatus
}

Expand Down Expand Up @@ -306,8 +311,13 @@ func PerformObligationMapActions(tx *gorm.DB, userId uuid.UUID, obligation *mode

return createObligationMapChangelog(tx, userId, newLicenseAssociations, oldLicenseAssociations, obligation)
}); err != nil {
logger.LogError("Failed to update obligation-license mapping",
zap.String("obligation_id", obligation.Id.String()),
zap.Error(err),
)
errs = append(errs, err)
}

return newLicenseAssociations, errs
}

Expand Down Expand Up @@ -501,33 +511,51 @@ func CreateObClassification(obClassification *models.ObligationClassification, u
// Populatedb populates the database with license data from a JSON file.
func Populatedb(datafile string) {
var licenses []models.LicenseJson

// Read the content of the data file.
byteResult, err := os.ReadFile(datafile)
if err != nil {
log.Fatalf("Unable to read JSON file: %v", err)
logger.LogFatal("Unable to read JSON file", zap.Error(err))

}

// Unmarshal the JSON file data into a slice of LicenseJson structs.
if err := json.Unmarshal(byteResult, &licenses); err != nil {
log.Fatalf("error reading from json file: %v", err)
logger.LogFatal("Error unmarshalling JSON file", zap.Error(err))
}

// Fetch SUPER_ADMIN user
user := models.User{}
level := "SUPER_ADMIN"

if err := db.DB.Where(&models.User{UserLevel: &level}).First(&user).Error; err != nil {
log.Fatalf("Failed to find a super admin")
logger.LogFatal(
"Failed to find a super admin",
zap.String("level", level),
zap.Error(err),
)

}
Comment on lines 513 to 538
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace LogError + return with LogFatal. This code runs during startup, and if it fails the backend should not continue running in a partially initialized state.


for _, license := range licenses {
result := license.Converter()

if err := validations.Validate.Struct(&result); err != nil {
red := "\033[31m"
reset := "\033[0m"
log.Printf("%s%s: %s%s", red, *result.Shortname, fmt.Sprintf("field '%s' failed validation: %s\n", err.(validator.ValidationErrors)[0].Field(), err.(validator.ValidationErrors)[0].Tag()), reset)
valErr := err.(validator.ValidationErrors)[0]
logger.LogError(
"License validation failed",
zap.String("shortname", *result.Shortname),
zap.String("field", valErr.Field()),
zap.String("tag", valErr.Tag()),
zap.Error(err),
)
continue
}

_, _ = InsertOrUpdateLicenseOnImport(&result, user.Id)
}

// Default obligation types
DEFAULT_OBLIGATION_TYPES := []*models.ObligationType{
{Type: "OBLIGATION"},
{Type: "RISK"},
Expand All @@ -539,16 +567,20 @@ func Populatedb(datafile string) {
err, status := CreateObType(obType, user.Id)

if status == CREATED || status == CONFLICT {
green := "\033[32m"
reset := "\033[0m"
log.Printf("%s%s: %s%s", green, obType.Type, "Obligation type created successfully", reset)
logger.LogInfo(
"Obligation type created successfully",
zap.String("type", obType.Type),
)
} else {
red := "\033[31m"
reset := "\033[0m"
log.Printf("%s%s: %s%s", red, obType.Type, err.Error(), reset)
logger.LogError(
"Obligation type creation failed",
zap.String("type", obType.Type),
zap.Error(err),
)
}
}

// Default obligation classifications
DEFAULT_OBLIGATION_CLASSIFICATIONS := []*models.ObligationClassification{
{Classification: "GREEN", Color: "#00FF00"},
{Classification: "WHITE", Color: "#FFFFFF"},
Expand All @@ -560,13 +592,16 @@ func Populatedb(datafile string) {
err, status := CreateObClassification(obClassification, user.Id)

if status == CREATED || status == CONFLICT {
green := "\033[32m"
reset := "\033[0m"
log.Printf("%s%s: %s%s", green, obClassification.Classification, "Obligation classification created successfully", reset)
logger.LogInfo(
"Obligation classification created successfully",
zap.String("classification", obClassification.Classification),
)
} else {
red := "\033[31m"
reset := "\033[0m"
log.Printf("%s%s: %s%s", red, obClassification.Classification, err.Error(), reset)
logger.LogError(
"Obligation classification creation failed",
zap.String("classification", obClassification.Classification),
zap.Error(err),
)
}
}
}
Expand All @@ -581,15 +616,23 @@ func SetSimilarityThreshold() {
if parsed, err := strconv.ParseFloat(thresholdStr, 64); err == nil {
threshold = parsed
} else {
log.Printf("Invalid SIMILARITY_THRESHOLD '%s', using default %.1f", thresholdStr, defaultThreshold)
logger.LogWarn("Invalid SIMILARITY_THRESHOLD, using default",
zap.String("thresholdStr", thresholdStr),
zap.Float64("defaultThreshold", defaultThreshold),
)
}
} else {
log.Printf("SIMILARITY_THRESHOLD not set, using default %.1f", defaultThreshold)
logger.LogInfo("SIMILARITY_THRESHOLD not set, using default",
zap.Float64("defaultThreshold", defaultThreshold),
)
}

query := fmt.Sprintf("SET pg_trgm.similarity_threshold = %f", threshold)
if err := db.DB.Exec(query).Error; err != nil {
log.Println("Failed to set similarity threshold:", err)
Copy link
Copy Markdown
Contributor

@ChayanDass ChayanDass Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log the query execution error, with the previous log message

logger.LogError(
"Failed to set similarity threshold",
zap.Error(err),
)
}
}

Expand Down Expand Up @@ -664,7 +707,9 @@ func GetAuditEntity(c *gin.Context, audit *models.Audit) error {
return err
}
default:
// no action
logger.LogWarn("Unknown audit type",
zap.String("type", audit.Type),
)
}
return nil
}
Expand Down
Loading