Files
Steve Munene 362a4fc76d MG-370 - Add fine grained access control to rules engine (#402)
* update go mod file

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

* fix rules endpoint tests

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

* fix yaml file

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

* fix build

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

* address comments

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

* remove roles from alarms

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

* change approach for schema combaine

Signed-off-by: Arvindh <arvindh91@gmail.com>

* change approach for schema combaine

Signed-off-by: Arvindh <arvindh91@gmail.com>

* fix permissions for rules

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

* fix authorization file

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

* fix linter

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

* fix linter

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>

---------

Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: Arvindh <arvindh91@gmail.com>
Co-authored-by: Arvindh <arvindh91@gmail.com>
2026-03-05 11:42:51 +01:00

162 lines
4.4 KiB
Go

// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package postgres
import (
"database/sql"
"encoding/json"
"time"
"github.com/absmach/magistrala/pkg/schedule"
"github.com/absmach/magistrala/re"
"github.com/absmach/supermq/pkg/errors"
"github.com/absmach/supermq/pkg/roles"
"github.com/jackc/pgtype"
)
// 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"`
}
func ruleToDb(r re.Rule) (dbRule, error) {
metadata := []byte("{}")
if len(r.Metadata) > 0 {
b, err := json.Marshal(r.Metadata)
if err != nil {
return dbRule{}, errors.Wrap(errors.ErrMalformedEntity, err)
}
metadata = b
}
start := sql.NullTime{Time: r.Schedule.StartDateTime}
if !r.Schedule.StartDateTime.IsZero() {
start.Valid = true
}
t := sql.NullTime{Time: r.Schedule.Time}
if !r.Schedule.Time.IsZero() {
t.Valid = true
}
var tags pgtype.TextArray
if err := tags.Set(r.Tags); err != nil {
return dbRule{}, err
}
outputs, err := json.Marshal(r.Outputs)
if err != nil {
return dbRule{}, errors.Wrap(errors.ErrMalformedEntity, err)
}
return dbRule{
ID: r.ID,
Name: r.Name,
DomainID: r.DomainID,
Tags: tags,
Metadata: metadata,
InputChannel: r.InputChannel,
InputTopic: toNullString(r.InputTopic),
LogicType: r.Logic.Type,
LogicValue: r.Logic.Value,
Outputs: outputs,
StartDateTime: start,
Time: t,
Recurring: r.Schedule.Recurring,
RecurringPeriod: r.Schedule.RecurringPeriod,
Status: r.Status,
CreatedAt: r.CreatedAt,
CreatedBy: r.CreatedBy,
UpdatedAt: r.UpdatedAt,
UpdatedBy: r.UpdatedBy,
}, nil
}
func dbToRule(dto dbRule) (re.Rule, error) {
var metadata re.Metadata
if dto.Metadata != nil {
if err := json.Unmarshal(dto.Metadata, &metadata); err != nil {
return re.Rule{}, errors.Wrap(errors.ErrMalformedEntity, err)
}
}
var tags []string
for _, e := range dto.Tags.Elements {
tags = append(tags, e.String)
}
var outputs re.Outputs
if dto.Outputs != nil {
if err := json.Unmarshal(dto.Outputs, &outputs); err != nil {
return re.Rule{}, errors.Wrap(errors.ErrMalformedEntity, err)
}
}
var roles []roles.MemberRoleActions
if dto.Roles != nil {
if err := json.Unmarshal(dto.Roles, &roles); err != nil {
return re.Rule{}, errors.Wrap(errors.ErrMalformedEntity, err)
}
}
return re.Rule{
ID: dto.ID,
Name: dto.Name,
DomainID: dto.DomainID,
Tags: tags,
Metadata: metadata,
InputChannel: dto.InputChannel,
InputTopic: fromNullString(dto.InputTopic),
Logic: re.Script{
Type: dto.LogicType,
Value: dto.LogicValue,
},
Outputs: outputs,
Schedule: schedule.Schedule{
StartDateTime: dto.StartDateTime.Time,
Time: dto.Time.Time,
Recurring: dto.Recurring,
RecurringPeriod: dto.RecurringPeriod,
},
Status: dto.Status,
CreatedAt: dto.CreatedAt,
CreatedBy: dto.CreatedBy,
UpdatedAt: dto.UpdatedAt,
UpdatedBy: dto.UpdatedBy,
Roles: roles,
}, nil
}
func toNullString(value string) sql.NullString {
if value == "" {
return sql.NullString{Valid: false}
}
return sql.NullString{String: value, Valid: true}
}
func fromNullString(nullString sql.NullString) string {
if !nullString.Valid {
return ""
}
return nullString.String
}