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
3 changes: 3 additions & 0 deletions docker/addons/bootstrap/ssl/placeholder
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

optional bind-mount placeholder
3 changes: 3 additions & 0 deletions docker/addons/postgres-reader/ssl/placeholder
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

optional bind-mount placeholder
3 changes: 3 additions & 0 deletions docker/addons/ssl/placeholder
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

optional bind-mount placeholder
3 changes: 3 additions & 0 deletions docker/ssl/placeholder
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

optional bind-mount placeholder
30 changes: 16 additions & 14 deletions pkg/sdk/reports.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/absmach/magistrala/pkg/errors"
"github.com/absmach/magistrala/pkg/roles"
)

const (
Expand All @@ -21,20 +22,21 @@ const (

// ReportConfig represents a report configuration.
type ReportConfig struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
DomainID string `json:"domain_id,omitempty"`
Schedule any `json:"schedule,omitempty"`
Config any `json:"config,omitempty"`
Email any `json:"email,omitempty"`
Metrics any `json:"metrics,omitempty"`
ReportTemplate ReportTemplate `json:"report_template,omitempty"`
Status string `json:"status,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
UpdatedBy string `json:"updated_by,omitempty"`
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
DomainID string `json:"domain_id,omitempty"`
Schedule any `json:"schedule,omitempty"`
Config any `json:"config,omitempty"`
Email any `json:"email,omitempty"`
Metrics any `json:"metrics,omitempty"`
ReportTemplate ReportTemplate `json:"report_template,omitempty"`
Status string `json:"status,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
UpdatedBy string `json:"updated_by,omitempty"`
Roles []roles.MemberRoleActions `json:"roles,omitempty"`
}

type ReportTemplate any
Expand Down
32 changes: 17 additions & 15 deletions pkg/sdk/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,29 @@ import (
"net/http"

"github.com/absmach/magistrala/pkg/errors"
"github.com/absmach/magistrala/pkg/roles"
)

const rulesEndpoint = "rules"

// Rule represents a rule configuration.
type Rule struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
DomainID string `json:"domain,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
Tags []string `json:"tags,omitempty"`
InputChannel string `json:"input_channel,omitempty"`
InputTopic string `json:"input_topic,omitempty"`
Logic any `json:"logic,omitempty"`
Outputs any `json:"outputs,omitempty"`
Schedule any `json:"schedule,omitempty"`
Status string `json:"status,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
UpdatedBy string `json:"updated_by,omitempty"`
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
DomainID string `json:"domain,omitempty"`
Metadata Metadata `json:"metadata,omitempty"`
Tags []string `json:"tags,omitempty"`
InputChannel string `json:"input_channel,omitempty"`
InputTopic string `json:"input_topic,omitempty"`
Logic any `json:"logic,omitempty"`
Outputs any `json:"outputs,omitempty"`
Schedule any `json:"schedule,omitempty"`
Status string `json:"status,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
UpdatedBy string `json:"updated_by,omitempty"`
Roles []roles.MemberRoleActions `json:"roles,omitempty"`
}

type Page struct {
Expand Down
81 changes: 54 additions & 27 deletions re/postgres/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,37 +404,64 @@ func (repo *PostgresRepository) ListAllRules(ctx context.Context, pm re.PageMeta

func (repo *PostgresRepository) ListUserRules(ctx context.Context, userID string, pm re.PageMeta) (re.Page, error) {
pm.UserID = userID
clauses := []string{
`(
EXISTS (
SELECT 1
FROM rules_roles rr
JOIN rules_role_members rrm ON rrm.role_id = rr.id
WHERE rr.entity_id = r.id AND rrm.member_id = :user_id
)
OR EXISTS (
SELECT 1
FROM domains_roles dr
JOIN domains_role_members drm ON drm.role_id = dr.id
JOIN domains_role_actions dra ON dra.role_id = dr.id
WHERE dr.entity_id = r.domain_id
AND drm.member_id = :user_id
AND dra.action LIKE 'rule%'
)
)`,
}
clauses = append(clauses, pageRulesQueryConditions(pm)...)

additionalConditions := pageRulesQueryConditions(pm)
additionalWhereClause := ""
if len(additionalConditions) > 0 {
additionalWhereClause = "AND " + strings.Join(additionalConditions, " AND ")
}

orderClause := rulesOrderClause(pm)
pgData := rulesPageData(pm)

whereClause := fmt.Sprintf("WHERE %s", strings.Join(clauses, " AND "))

innerQ := fmt.Sprintf(`
SELECT DISTINCT r.id, r.name, r.domain_id, r.tags, r.input_channel, r.input_topic, r.logic_type, r.logic_value, r.outputs,
r.start_datetime, r.time, r.recurring, r.recurring_period, r.created_at, r.created_by, r.updated_at, r.updated_by, r.status
FROM rules r
%s
`, whereClause)
WITH direct_rules AS (
SELECT r.id, r.name, r.domain_id, r.tags, r.metadata, r.input_channel, r.input_topic,
r.logic_type, r.logic_value, r.outputs, r.start_datetime, r.time,
r.recurring, r.recurring_period, r.created_at, r.created_by, r.updated_at, r.updated_by, r.status,
rr.id AS role_id,
rr."name" AS role_name,
array_remove(array_agg(DISTINCT rra."action"), NULL) AS actions,
'direct' AS access_type,
'' AS access_provider_id,
'' AS access_provider_role_id,
'' AS access_provider_role_name,
CAST(array[] AS text[]) AS access_provider_role_actions
FROM rules_role_members rrm
JOIN rules_roles rr ON rr.id = rrm.role_id
JOIN rules r ON r.id = rr.entity_id
LEFT JOIN rules_role_actions rra ON rra.role_id = rrm.role_id
WHERE rrm.member_id = :user_id
%s
GROUP BY r.id, rr.id, rr."name"
),
domain_rules AS (
SELECT r.id, r.name, r.domain_id, r.tags, r.metadata, r.input_channel, r.input_topic,
r.logic_type, r.logic_value, r.outputs, r.start_datetime, r.time,
r.recurring, r.recurring_period, r.created_at, r.created_by, r.updated_at, r.updated_by, r.status,
'' AS role_id,
'' AS role_name,
CAST(array[] AS text[]) AS actions,
'domain' AS access_type,
d.id AS access_provider_id,
dr.id AS access_provider_role_id,
dr."name" AS access_provider_role_name,
array_agg(DISTINCT dra."action") AS access_provider_role_actions
FROM domains_role_members drm
JOIN domains_role_actions dra ON dra.role_id = drm.role_id
JOIN domains_roles dr ON dr.id = drm.role_id
JOIN domains d ON d.id = dr.entity_id
JOIN rules r ON r.domain_id = d.id
WHERE drm.member_id = :user_id
AND dra.action LIKE 'rule%%'
AND NOT EXISTS (SELECT 1 FROM direct_rules tmp WHERE tmp.id = r.id)
%s
GROUP BY r.id, d.id, dr.id, dr."name"
)
SELECT * FROM direct_rules
UNION ALL
SELECT * FROM domain_rules
`, additionalWhereClause, additionalWhereClause)

q := fmt.Sprintf(`
SELECT * FROM (%s) AS sub %s %s;
Expand Down
71 changes: 44 additions & 27 deletions re/postgres/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,40 @@ import (
"github.com/absmach/magistrala/pkg/schedule"
"github.com/absmach/magistrala/re"
"github.com/jackc/pgtype"
"github.com/lib/pq"
)

// dbRule represents the database structure for a Rule.
type dbRule struct {
ID string `db:"id"`
Name string `db:"name"`
DomainID string `db:"domain_id"`
Tags pgtype.TextArray `db:"tags,omitempty"`
Metadata []byte `db:"metadata,omitempty"`
InputChannel string `db:"input_channel"`
InputTopic sql.NullString `db:"input_topic"`
LogicType re.ScriptType `db:"logic_type"`
LogicValue string `db:"logic_value"`
Outputs []byte `db:"outputs"`
StartDateTime sql.NullTime `db:"start_datetime"`
Time sql.NullTime `db:"time"`
Recurring schedule.Recurring `db:"recurring"`
RecurringPeriod uint `db:"recurring_period"`
Status re.Status `db:"status"`
CreatedAt time.Time `db:"created_at"`
CreatedBy string `db:"created_by"`
UpdatedAt time.Time `db:"updated_at"`
UpdatedBy string `db:"updated_by"`
MemberID string `db:"member_id,omitempty"`
Roles json.RawMessage `db:"roles,omitempty"`
ID string `db:"id"`
Name string `db:"name"`
DomainID string `db:"domain_id"`
Tags pgtype.TextArray `db:"tags,omitempty"`
Metadata []byte `db:"metadata,omitempty"`
InputChannel string `db:"input_channel"`
InputTopic sql.NullString `db:"input_topic"`
LogicType re.ScriptType `db:"logic_type"`
LogicValue string `db:"logic_value"`
Outputs []byte `db:"outputs"`
StartDateTime sql.NullTime `db:"start_datetime"`
Time sql.NullTime `db:"time"`
Recurring schedule.Recurring `db:"recurring"`
RecurringPeriod uint `db:"recurring_period"`
Status re.Status `db:"status"`
CreatedAt time.Time `db:"created_at"`
CreatedBy string `db:"created_by"`
UpdatedAt time.Time `db:"updated_at"`
UpdatedBy string `db:"updated_by"`
MemberID string `db:"member_id,omitempty"`
RoleID string `db:"role_id,omitempty"`
RoleName string `db:"role_name,omitempty"`
Actions pq.StringArray `db:"actions,omitempty"`
AccessType string `db:"access_type,omitempty"`
AccessProviderId string `db:"access_provider_id,omitempty"`
AccessProviderRoleId string `db:"access_provider_role_id,omitempty"`
AccessProviderRoleName string `db:"access_provider_role_name,omitempty"`
AccessProviderRoleActions pq.StringArray `db:"access_provider_role_actions,omitempty"`
Roles json.RawMessage `db:"roles,omitempty"`
}

func ruleToDb(r re.Rule) (dbRule, error) {
Expand Down Expand Up @@ -137,12 +146,20 @@ func dbToRule(dto dbRule) (re.Rule, error) {
Recurring: dto.Recurring,
RecurringPeriod: dto.RecurringPeriod,
},
Status: dto.Status,
CreatedAt: dto.CreatedAt,
CreatedBy: dto.CreatedBy,
UpdatedAt: dto.UpdatedAt,
UpdatedBy: dto.UpdatedBy,
Roles: roles,
Status: dto.Status,
CreatedAt: dto.CreatedAt,
CreatedBy: dto.CreatedBy,
UpdatedAt: dto.UpdatedAt,
UpdatedBy: dto.UpdatedBy,
RoleID: dto.RoleID,
RoleName: dto.RoleName,
Actions: []string(dto.Actions),
AccessType: dto.AccessType,
AccessProviderId: dto.AccessProviderId,
AccessProviderRoleId: dto.AccessProviderRoleId,
AccessProviderRoleName: dto.AccessProviderRoleName,
AccessProviderRoleActions: []string(dto.AccessProviderRoleActions),
Roles: roles,
}, nil
}

Expand Down
41 changes: 25 additions & 16 deletions re/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,31 @@ var outputRegistry = map[outputs.OutputType]func() Runnable{
}

type Rule struct {
ID string `json:"id"`
Name string `json:"name"`
DomainID string `json:"domain"`
Metadata Metadata `json:"metadata,omitempty"`
Tags []string `json:"tags,omitempty"`
InputChannel string `json:"input_channel"`
InputTopic string `json:"input_topic"`
Logic Script `json:"logic"`
Outputs Outputs `json:"outputs,omitempty"`
Schedule schedule.Schedule `json:"schedule,omitempty"`
Status Status `json:"status"`
CreatedAt time.Time `json:"created_at"`
CreatedBy string `json:"created_by"`
UpdatedAt time.Time `json:"updated_at"`
UpdatedBy string `json:"updated_by"`
Roles []roles.MemberRoleActions `json:"roles,omitempty"`
ID string `json:"id"`
Name string `json:"name"`
DomainID string `json:"domain"`
Metadata Metadata `json:"metadata,omitempty"`
Tags []string `json:"tags,omitempty"`
InputChannel string `json:"input_channel"`
InputTopic string `json:"input_topic"`
Logic Script `json:"logic"`
Outputs Outputs `json:"outputs,omitempty"`
Schedule schedule.Schedule `json:"schedule,omitempty"`
Status Status `json:"status"`
CreatedAt time.Time `json:"created_at"`
CreatedBy string `json:"created_by"`
UpdatedAt time.Time `json:"updated_at"`
UpdatedBy string `json:"updated_by"`
// Extended
RoleID string `json:"role_id,omitempty"`
RoleName string `json:"role_name,omitempty"`
Actions []string `json:"actions,omitempty"`
AccessType string `json:"access_type,omitempty"`
AccessProviderId string `json:"access_provider_id,omitempty"`
AccessProviderRoleId string `json:"access_provider_role_id,omitempty"`
AccessProviderRoleName string `json:"access_provider_role_name,omitempty"`
AccessProviderRoleActions []string `json:"access_provider_role_actions,omitempty"`
Roles []roles.MemberRoleActions `json:"roles,omitempty"`
}

// EventEncode converts a Rule struct to map[string]any at event producer.
Expand Down
Loading
Loading