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
25 changes: 15 additions & 10 deletions models/app-fic.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,32 @@ package models

import (
"encoding/json"
"strings"
)

type AppFIC struct {
FIC json.RawMessage `json:"fic"`
AppId string `json:"appId"`
}

// MarshalJSON uppercases AppId and the embedded fic.id for raw
// (use_raw_object_id) ingest; display-only fic fields are untouched. An empty
// or nil fic is emitted as null to avoid unmarshaling it. Non-mutating.
func (s *AppFIC) MarshalJSON() ([]byte, error) {
output := make(map[string]any)
output["appId"] = s.AppId
type Alias AppFIC
a := Alias(*s)
a.AppId = strings.ToUpper(a.AppId)

if s.FIC == nil {
return nil, nil
}

if fic, err := OmitEmpty(s.FIC); err != nil {
return nil, err
if len(a.FIC) > 0 {
fic, err := OmitEmptyUpper(a.FIC, "id")
if err != nil {
return nil, err
}
a.FIC = fic
} else {
output["fic"] = fic
return json.Marshal(output)
a.FIC = nil
}
return json.Marshal(a)
}

type AppFICs struct {
Expand Down
8 changes: 6 additions & 2 deletions models/app-member.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,24 @@ package models

import (
"encoding/json"
"strings"
)

type AppMember struct {
json.RawMessage
AppId string `json:"appId"`
}

func (s *AppMember) MarshalJSON() ([]byte, error) {
func (s AppMember) MarshalJSON() ([]byte, error) {
var data map[string]any
if err := json.Unmarshal(s.RawMessage, &data); err != nil {
return nil, err
} else {
StripEmptyEntries(data)
data["appId"] = s.AppId
if id, ok := data["id"].(string); ok {
data["id"] = strings.ToUpper(id)
}
data["appId"] = strings.ToUpper(s.AppId)
return json.Marshal(data)
}
}
14 changes: 11 additions & 3 deletions models/app-owner.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@ package models

import (
"encoding/json"
"strings"
)

type AppOwner struct {
Owner json.RawMessage `json:"owner"`
AppId string `json:"appId"`
}

func (s *AppOwner) MarshalJSON() ([]byte, error) {
func (s AppOwner) MarshalJSON() ([]byte, error) {
output := make(map[string]any)
output["appId"] = s.AppId
output["appId"] = strings.ToUpper(s.AppId)

if owner, err := OmitEmpty(s.Owner); err != nil {
if owner, err := OmitEmptyUpper(s.Owner, "id"); err != nil {
return nil, err
} else {
output["owner"] = owner
Expand All @@ -42,3 +43,10 @@ type AppOwners struct {
Owners []AppOwner `json:"owners"`
AppId string `json:"appId"`
}

func (s AppOwners) MarshalJSON() ([]byte, error) {
type Alias AppOwners
a := Alias(s)
a.AppId = strings.ToUpper(a.AppId)
return json.Marshal(a)
}
27 changes: 27 additions & 0 deletions models/app-role-assignments.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
package models

import (
"encoding/json"
"strings"

"github.com/bloodhoundad/azurehound/v2/models/azure"
)

Expand All @@ -26,3 +29,27 @@ type AppRoleAssignment struct {
AppId string `json:"appId"`
TenantId string `json:"tenantId"`
}

func (s AppRoleAssignment) MarshalJSON() ([]byte, error) {
type Alias AppRoleAssignment
a := Alias(s)
a.ResourceId = strings.ToUpper(a.ResourceId)
a.TenantId = strings.ToUpper(a.TenantId)

// PrincipalId is a uuid.UUID and cannot hold an uppercased string, so emit
// it through a map override alongside the aliased fields.
raw, err := json.Marshal(a)
if err != nil {
return nil, err
}

var output map[string]json.RawMessage
if err := json.Unmarshal(raw, &output); err != nil {
return nil, err
}
if _, ok := output["principalId"]; ok {
pid := strings.ToUpper(s.PrincipalId.String())
output["principalId"], _ = json.Marshal(pid)
}
return json.Marshal(output)
}
12 changes: 12 additions & 0 deletions models/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
package models

import (
"encoding/json"
"strings"

"github.com/bloodhoundad/azurehound/v2/models/azure"
)

Expand All @@ -26,3 +29,12 @@ type App struct {
TenantId string `json:"tenantId"`
TenantName string `json:"tenantName"`
}

func (s App) MarshalJSON() ([]byte, error) {
type Alias App
a := Alias(s)
a.Id = strings.ToUpper(a.Id)
a.AppId = strings.ToUpper(a.AppId)
a.TenantId = strings.ToUpper(a.TenantId)
return json.Marshal(a)
}
18 changes: 17 additions & 1 deletion models/automation-account.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@

package models

import "github.com/bloodhoundad/azurehound/v2/models/azure"
import (
"encoding/json"
"strings"

"github.com/bloodhoundad/azurehound/v2/models/azure"
)

type AutomationAccount struct {
azure.AutomationAccount
Expand All @@ -26,3 +31,14 @@ type AutomationAccount struct {
ResourceGroupName string `json:"resourceGroupName"`
TenantId string `json:"tenantId"`
}

func (s AutomationAccount) MarshalJSON() ([]byte, error) {
type Alias AutomationAccount
a := Alias(s)
a.Id = strings.ToUpper(a.Id)
a.SubscriptionId = strings.ToUpper(a.SubscriptionId)
a.ResourceGroupId = strings.ToUpper(a.ResourceGroupId)
a.TenantId = strings.ToUpper(a.TenantId)
a.Identity = UpperManagedIdentity(a.Identity)
return json.Marshal(a)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
31 changes: 30 additions & 1 deletion models/azure-role-assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,44 @@

package models

import "github.com/bloodhoundad/azurehound/v2/models/azure"
import (
"encoding/json"
"strings"

"github.com/bloodhoundad/azurehound/v2/models/azure"
)

type AzureRoleAssignment struct {
Assignee azure.RoleAssignment `json:"assignee"`
ObjectId string `json:"objectId"`
RoleDefinitionId string `json:"roleDefinitionId"`
}

// MarshalJSON uppercases the ObjectId and the Assignee endpoint identifiers so
// the raw (use_raw_object_id) ingest path matches the normalized node ObjectIDs.
// RoleDefinitionId is left untouched because ingest matches it against lowercase
// role-definition constants. The input is not mutated.
func (s AzureRoleAssignment) MarshalJSON() ([]byte, error) {
type Alias AzureRoleAssignment
a := Alias(s)
a.ObjectId = strings.ToUpper(a.ObjectId)
a.Assignee = UpperRoleAssignment(a.Assignee)
return json.Marshal(a)
}

type AzureRoleAssignments struct {
RoleAssignments []AzureRoleAssignment `json:"assignees"`
ObjectId string `json:"objectId"`
}

// MarshalJSON uppercases the top-level ObjectId (the resource id BloodHound
// ingest reads as the RBAC edge target endpoint for the resource-scoped
// role-assignment convertors) so the raw (use_raw_object_id) ingest path matches
// the normalized resource node ObjectIDs. The nested assignees uppercase their
// own identifiers via AzureRoleAssignment.MarshalJSON. The input is not mutated.
func (s AzureRoleAssignments) MarshalJSON() ([]byte, error) {
type Alias AzureRoleAssignments
a := Alias(s)
a.ObjectId = strings.ToUpper(a.ObjectId)
return json.Marshal(a)
}
13 changes: 13 additions & 0 deletions models/azure/descendant-info.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@

package azure

import (
"encoding/json"
"strings"
)

// The properties of the parent management group.
type DescendantParentGroupInfo struct {
// The fully qualified ID for the parent management group.
Expand Down Expand Up @@ -60,3 +65,11 @@ type DescendantInfo struct {
// - /subscriptions
Type string `json:"type,omitempty"`
}

func (s DescendantInfo) MarshalJSON() ([]byte, error) {
type Alias DescendantInfo
a := Alias(s)
a.Id = strings.ToUpper(a.Id)
a.Properties.Parent.Id = strings.ToUpper(a.Properties.Parent.Id)
return json.Marshal(a)
}
18 changes: 17 additions & 1 deletion models/container-registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@

package models

import "github.com/bloodhoundad/azurehound/v2/models/azure"
import (
"encoding/json"
"strings"

"github.com/bloodhoundad/azurehound/v2/models/azure"
)

type ContainerRegistry struct {
azure.ContainerRegistry
Expand All @@ -26,3 +31,14 @@ type ContainerRegistry struct {
ResourceGroupName string `json:"resourceGroupName"`
TenantId string `json:"tenantId"`
}

func (s ContainerRegistry) MarshalJSON() ([]byte, error) {
type Alias ContainerRegistry
a := Alias(s)
a.Id = strings.ToUpper(a.Id)
a.SubscriptionId = strings.ToUpper(a.SubscriptionId)
a.ResourceGroupId = strings.ToUpper(a.ResourceGroupId)
a.TenantId = strings.ToUpper(a.TenantId)
a.Identity = UpperManagedIdentity(a.Identity)
return json.Marshal(a)
}
Comment thread
ktstrader marked this conversation as resolved.
23 changes: 16 additions & 7 deletions models/device-owner.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,32 @@ package models

import (
"encoding/json"
"strings"
)

type DeviceOwner struct {
Owner json.RawMessage `json:"owner"`
DeviceId string `json:"deviceId"`
}

func (s *DeviceOwner) MarshalJSON() ([]byte, error) {
output := make(map[string]any)
output["deviceId"] = s.DeviceId
// MarshalJSON uppercases DeviceId and the embedded owner.id for raw
// (use_raw_object_id) ingest. An empty or nil owner is emitted as null to
// avoid unmarshaling it. Non-mutating.
func (s DeviceOwner) MarshalJSON() ([]byte, error) {
type Alias DeviceOwner
a := Alias(s)
a.DeviceId = strings.ToUpper(a.DeviceId)

if owner, err := OmitEmpty(s.Owner); err != nil {
return nil, err
if len(a.Owner) > 0 {
owner, err := OmitEmptyUpper(a.Owner, "id")
if err != nil {
return nil, err
}
a.Owner = owner
} else {
output["owner"] = owner
return json.Marshal(output)
a.Owner = nil
}
return json.Marshal(a)
}

type DeviceOwners struct {
Expand Down
11 changes: 11 additions & 0 deletions models/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
package models

import (
"encoding/json"
"strings"

"github.com/bloodhoundad/azurehound/v2/models/azure"
)

Expand All @@ -26,3 +29,11 @@ type Device struct {
TenantId string `json:"tenantId"`
TenantName string `json:"tenantName"`
}

func (s Device) MarshalJSON() ([]byte, error) {
type Alias Device
a := Alias(s)
a.Id = strings.ToUpper(a.Id)
a.TenantId = strings.ToUpper(a.TenantId)
return json.Marshal(a)
}
18 changes: 17 additions & 1 deletion models/function-app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@

package models

import "github.com/bloodhoundad/azurehound/v2/models/azure"
import (
"encoding/json"
"strings"

"github.com/bloodhoundad/azurehound/v2/models/azure"
)

type FunctionApp struct {
azure.FunctionApp
Expand All @@ -26,3 +31,14 @@ type FunctionApp struct {
ResourceGroupName string `json:"resourceGroupName"`
TenantId string `json:"tenantId"`
}

func (s FunctionApp) MarshalJSON() ([]byte, error) {
type Alias FunctionApp
a := Alias(s)
a.Id = strings.ToUpper(a.Id)
a.SubscriptionId = strings.ToUpper(a.SubscriptionId)
a.ResourceGroupId = strings.ToUpper(a.ResourceGroupId)
a.TenantId = strings.ToUpper(a.TenantId)
a.Identity = UpperManagedIdentity(a.Identity)
return json.Marshal(a)
}
Loading
Loading