Skip to content
Merged
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
4 changes: 3 additions & 1 deletion internal/authn/openid/authn.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ import ( // Package imports
"sync"
"time"

// JWT package
"github.com/golang-jwt/jwt/v4"
grpcauth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
"github.com/hashicorp/go-retryablehttp"
// JWT key sets
"github.com/lestrrat-go/jwx/jwk" // JWT key sets

// Internal packages
"github.com/Permify/permify/internal/config" // internal configuration
base "github.com/Permify/permify/pkg/pb/base/v1" // Base protobuf definitions
) // End of imports

type Authn struct {
// URL of the issuer. This is typically the base URL of the identity provider.
IssuerURL string
Expand Down
4 changes: 0 additions & 4 deletions internal/storage/memory/bundle_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import (

"github.com/Permify/permify/internal/storage"
"github.com/Permify/permify/internal/storage/memory/constants" // Memory storage constants

// Database section
// Database package imports
// Database imports
db "github.com/Permify/permify/pkg/database/memory"
base "github.com/Permify/permify/pkg/pb/base/v1"
)
Expand Down
25 changes: 7 additions & 18 deletions internal/storage/postgres/schema_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,8 @@ func (r *SchemaReader) ReadEntityDefinition(ctx context.Context, tenantID, name,
}

slog.DebugContext(ctx, "executing sql query", slog.Any("query", query), slog.Any("arguments", args))

var def storage.SchemaDefinition
row := r.database.ReadPool.QueryRow(ctx, query, args...)
row := r.database.ReadPool.QueryRow(ctx, query, args...) // Execute query
if err = row.Scan(&def.Name, &def.SerializedDefinition, &def.Version); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return nil, "", utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_SCHEMA_NOT_FOUND)
Expand All @@ -149,8 +148,7 @@ func (r *SchemaReader) ReadEntityDefinition(ctx context.Context, tenantID, name,
return nil, "", utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_INTERNAL)
}

definition, err = schema.GetEntityByName(sch, name)

definition, err = schema.GetEntityByName(sch, name) // Get entity
slog.DebugContext(ctx, "successfully retrieved", slog.Any("schema definition", definition))
return definition, def.Version, err
}
Expand All @@ -171,9 +169,8 @@ func (r *SchemaReader) ReadRuleDefinition(ctx context.Context, tenantID, name, v
}

slog.DebugContext(ctx, "executing sql query", slog.Any("query", query), slog.Any("arguments", args))

var def storage.SchemaDefinition
row := r.database.ReadPool.QueryRow(ctx, query, args...)
row := r.database.ReadPool.QueryRow(ctx, query, args...) // Execute query
if err = row.Scan(&def.Name, &def.SerializedDefinition, &def.Version); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return nil, "", utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_SCHEMA_NOT_FOUND)
Expand All @@ -182,27 +179,22 @@ func (r *SchemaReader) ReadRuleDefinition(ctx context.Context, tenantID, name, v
}

slog.DebugContext(ctx, "successfully retrieved rule definition for", slog.Any("name", name))

var sch *base.SchemaDefinition
sch, err = schema.NewSchemaFromStringDefinitions(false, def.Serialized())
if err != nil {
return nil, "", utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_INTERNAL)
}

definition, err = schema.GetRuleByName(sch, name)

slog.DebugContext(ctx, "successfully created rule definition")

return definition, def.Version, err
return definition, def.Version, err // Return result
}

// HeadVersion - Finds the latest version of the schema.
func (r *SchemaReader) HeadVersion(ctx context.Context, tenantID string) (version string, err error) {
ctx, span := internal.Tracer.Start(ctx, "schema-reader.head-version")
defer span.End()

defer span.End() // close span
slog.DebugContext(ctx, "finding the latest version fo the schema for", slog.String("tenant_id", tenantID))

var query string
var args []interface{}
query, args, err = r.database.Builder.
Expand All @@ -211,10 +203,8 @@ func (r *SchemaReader) HeadVersion(ctx context.Context, tenantID string) (versio
if err != nil {
return "", utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_SQL_BUILDER)
}

slog.DebugContext(ctx, "executing sql query", slog.Any("query", query), slog.Any("arguments", args))

row := r.database.ReadPool.QueryRow(ctx, query, args...)
row := r.database.ReadPool.QueryRow(ctx, query, args...) // Execute query
err = row.Scan(&version)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
Expand All @@ -224,8 +214,7 @@ func (r *SchemaReader) HeadVersion(ctx context.Context, tenantID string) (versio
}

slog.DebugContext(ctx, "successfully found the latest schema version", slog.Any("version", version))

return version, nil
return version, nil // Return version
}

// ListSchemas - List all Schemas
Expand Down
7 changes: 3 additions & 4 deletions internal/storage/postgres/tenant_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package postgres

import (
"context"
"log/slog" // Structured logging

// External dependencies
"github.com/jackc/pgx/v5"
"log/slog"

"github.com/Masterminds/squirrel"
"github.com/jackc/pgx/v5"
// Structured logging

"github.com/Permify/permify/internal"
"github.com/Permify/permify/internal/storage"
Expand Down
51 changes: 24 additions & 27 deletions internal/storage/postgres/utils/version.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
package utils
package utils // Postgres utility functions
import ( // Package imports
"context" // Context
"fmt" // Formatting
"strconv" // String conversion

import (
"context"
"fmt"
"strconv"

"github.com/jackc/pgx/v5/pgxpool"
)

const (
// The earliest supported version of PostgreSQL is 13.8
earliestPostgresVersion = 130008
)

// EnsureDBVersion checks the version of the given database connection and returns an error if the version is not
// supported.
func EnsureDBVersion(db *pgxpool.Pool) (version string, err error) {
err = db.QueryRow(context.Background(), "SHOW server_version_num;").Scan(&version)
if err != nil {
return
}
v, err := strconv.Atoi(version)
if v < earliestPostgresVersion {
err = fmt.Errorf("unsupported postgres version: %s, expected >= %d", version, earliestPostgresVersion)
}
return
}
"github.com/jackc/pgx/v5/pgxpool" // Postgres connection pool
) // End imports
// Version constants
const ( // Version constants
earliestPostgresVersion = 130008 // The earliest supported version of PostgreSQL is 13.8
) // End constants
// EnsureDBVersion checks the version of the given database connection
// and returns an error if the version is not supported.
func EnsureDBVersion(db *pgxpool.Pool) (version string, err error) { // Check database version
err = db.QueryRow(context.Background(), "SHOW server_version_num;").Scan(&version) // Query version
if err != nil { // Query failed
return // Return error
} // Query succeeded
v, err := strconv.Atoi(version) // Convert to int
if v < earliestPostgresVersion { // Check minimum version
err = fmt.Errorf("unsupported postgres version: %s, expected >= %d", version, earliestPostgresVersion) // Version too old
} // Version check done
return // Return version
} // End EnsureDBVersion
6 changes: 3 additions & 3 deletions pkg/attribute/attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ var _ = Describe("attribute", func() {
Attribute: "is_public",
Value: isPublic,
},
error: errors.New("failed to parse boolean: strconv.ParseBool: parsing \"asa\": invalid syntax"),
error: errors.New("failed to parse boolean value: strconv.ParseBool: parsing \"asa\": invalid syntax"),
},
{
target: "organization:1$is_public|boolean[]:asa",
Expand All @@ -162,7 +162,7 @@ var _ = Describe("attribute", func() {
Attribute: "is_public",
Value: isPublic,
},
error: errors.New("failed to parse boolean: strconv.ParseBool: parsing \"asa\": invalid syntax"),
error: errors.New("failed to parse boolean array element: strconv.ParseBool: parsing \"asa\": invalid syntax"),
},
{
target: "organization:1$balance|double:4eew",
Expand All @@ -174,7 +174,7 @@ var _ = Describe("attribute", func() {
Attribute: "balance",
Value: doubleValue,
},
error: errors.New("failed to parse float: strconv.ParseFloat: parsing \"4eew\": invalid syntax"),
error: errors.New("failed to parse float value: strconv.ParseFloat: parsing \"4eew\": invalid syntax"),
},
{
target: "organization:1$balance|double[]:4eew",
Expand Down
3 changes: 1 addition & 2 deletions pkg/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@ import ( // Package imports
"fmt" // Formatting utilities
"os" // OS utilities
"strings" // String manipulation

// External dependencies
"github.com/gookit/color" // Terminal colors
"github.com/olekukonko/tablewriter" // Table rendering
"github.com/spf13/cobra" // Cobra CLI framework
"github.com/spf13/viper" // Configuration management

// Internal packages
"github.com/Permify/permify/internal/config" // Internal config
"github.com/Permify/permify/pkg/cmd/flags" // Command flags
) // End of imports

// NewConfigCommand creates the config inspection command
func NewConfigCommand() *cobra.Command { // Create config command
command := &cobra.Command{ // Command configuration
Expand Down
114 changes: 59 additions & 55 deletions pkg/development/coverage/coverage.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package coverage

import (
"fmt"
"slices"
package coverage // Coverage analysis package
import ( // Package imports
"fmt" // Formatting
"slices" // Slice operations

"github.com/Permify/permify/pkg/attribute"
"github.com/Permify/permify/pkg/development/file"
Expand All @@ -14,11 +13,11 @@ import (

// SchemaCoverageInfo - Schema coverage info
type SchemaCoverageInfo struct {
EntityCoverageInfo []EntityCoverageInfo
TotalRelationshipsCoverage int
TotalAttributesCoverage int
TotalAssertionsCoverage int
}
EntityCoverageInfo []EntityCoverageInfo // Entity coverage details
TotalRelationshipsCoverage int // Total relationships coverage
TotalAttributesCoverage int // Total attributes coverage
TotalAssertionsCoverage int // Total assertions coverage
} // End SchemaCoverageInfo

// EntityCoverageInfo - Entity coverage info
type EntityCoverageInfo struct {
Expand Down Expand Up @@ -91,9 +90,9 @@ func Run(shape file.Shape) SchemaCoverageInfo {
schemaCoverageInfo := SchemaCoverageInfo{}

refs := make([]SchemaCoverage, len(definitions))
for i, en := range definitions {
refs[i] = references(en)
}
for idx, entityDef := range definitions { // Build entity references
refs[idx] = references(entityDef) // Extract references
} // References built

// Iterate through the schema coverage references
for _, ref := range refs {
Expand Down Expand Up @@ -155,13 +154,12 @@ func Run(shape file.Shape) SchemaCoverageInfo {
schemaCoverageInfo.EntityCoverageInfo = append(schemaCoverageInfo.EntityCoverageInfo, entityCoverageInfo)
}

// Calculate and assign the total relationships and assertions coverage to the schemaCoverageInfo
relationshipsCoverage, attributesCoverage, assertionsCoverage := calculateTotalCoverage(schemaCoverageInfo.EntityCoverageInfo)
schemaCoverageInfo.TotalRelationshipsCoverage = relationshipsCoverage
schemaCoverageInfo.TotalAttributesCoverage = attributesCoverage
schemaCoverageInfo.TotalAssertionsCoverage = assertionsCoverage

return schemaCoverageInfo
// Calculate total coverage for relationships, attributes and assertions
relationshipsCoverage, attributesCoverage, assertionsCoverage := calculateTotalCoverage(schemaCoverageInfo.EntityCoverageInfo) // Calculate totals
schemaCoverageInfo.TotalRelationshipsCoverage = relationshipsCoverage // Set total relationships
schemaCoverageInfo.TotalAttributesCoverage = attributesCoverage // Set total attributes
schemaCoverageInfo.TotalAssertionsCoverage = assertionsCoverage // Set total assertions
return schemaCoverageInfo // Return coverage info
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// calculateCoveragePercent - Calculate coverage percentage based on total and uncovered elements
Expand All @@ -179,36 +177,42 @@ func calculateCoveragePercent(totalElements, uncoveredElements []string) int {

// calculateTotalCoverage - Calculate total relationships and assertions coverage
func calculateTotalCoverage(entities []EntityCoverageInfo) (int, int, int) {
totalRelationships := 0
totalCoveredRelationships := 0
totalAttributes := 0
totalCoveredAttributes := 0
totalAssertions := 0
totalCoveredAssertions := 0

// Iterate over each entity in the list
for _, entity := range entities {
totalRelationships++
totalCoveredRelationships += entity.CoverageRelationshipsPercent

totalAttributes++
totalCoveredAttributes += entity.CoverageAttributesPercent

for _, assertionsPercent := range entity.CoverageAssertionsPercent {
totalAssertions++
totalCoveredAssertions += assertionsPercent
}
totalRelationships := 0 // Total relationships counter
totalCoveredRelationships := 0 // Covered relationships counter
totalAttributes := 0 // Total attributes counter
totalCoveredAttributes := 0 // Covered attributes counter
totalAssertions := 0 // Total assertions counter
totalCoveredAssertions := 0 // Covered assertions counter
// Process all entities to calculate coverage
for _, entity := range entities { // Process each entity
totalRelationships++ // Count relationships
totalCoveredRelationships += entity.CoverageRelationshipsPercent // Add covered
totalAttributes++ // Count attributes
totalCoveredAttributes += entity.CoverageAttributesPercent // Add covered attributes
for _, assertionPercent := range entity.CoverageAssertionsPercent { // Process assertions
totalAssertions++ // Increment assertion count
totalCoveredAssertions += assertionPercent // Add covered assertion
} // Assertions processed
} // Entities processed
// Calculate average coverage percentages for all entities (guard zero denominators)
var totalRelationshipsCoverage, totalAttributesCoverage, totalAssertionsCoverage int
if totalRelationships > 0 {
totalRelationshipsCoverage = totalCoveredRelationships / totalRelationships
} else {
totalRelationshipsCoverage = 100
}

// Calculate the coverage percentages
totalRelationshipsCoverage := totalCoveredRelationships / totalRelationships
totalAttributesCoverage := totalCoveredAttributes / totalAttributes
totalAssertionsCoverage := totalCoveredAssertions / totalAssertions

// Return the coverage percentages
return totalRelationshipsCoverage, totalAttributesCoverage, totalAssertionsCoverage
}

if totalAttributes > 0 {
totalAttributesCoverage = totalCoveredAttributes / totalAttributes
} else {
totalAttributesCoverage = 100
}
if totalAssertions > 0 {
totalAssertionsCoverage = totalCoveredAssertions / totalAssertions
} else {
totalAssertionsCoverage = 100
}
return totalRelationshipsCoverage, totalAttributesCoverage, totalAssertionsCoverage // Return totals
} // End calculateTotalCoverage
// References - Get references for a given entity
func references(entity *base.EntityDefinition) (coverage SchemaCoverage) {
// Set the entity name in the coverage struct
Expand Down Expand Up @@ -269,18 +273,18 @@ func relationships(en string, relationships []string) []string {
// attributes - Get attributes for a given entity
func attributes(en string, attributes []string) []string {
attrs := make([]string, len(attributes))
for i, attr := range attributes {
a, err := attribute.Attribute(attr)
for index, attrStr := range attributes { // Iterate attribute strings
a, err := attribute.Attribute(attrStr)
if err != nil {
return []string{}
}
if a.GetEntity().GetType() != en {
continue
}
attrs[i] = fmt.Sprintf("%s#%s", a.GetEntity().GetType(), a.GetAttribute())
}
return attrs
}
attrs[index] = fmt.Sprintf("%s#%s", a.GetEntity().GetType(), a.GetAttribute()) // Format attribute
} // End iteration
return attrs // Return attributes
} // End attributes

// assertions - Get assertions for a given entity
func assertions(en string, checks []file.Check, filters []file.EntityFilter) []string {
Expand Down
Loading