Skip to content

Commit

Permalink
initial commit of the LEI record unit tests and some related fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
caffix committed Feb 18, 2025
1 parent 99af7d7 commit 515861b
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 81 deletions.
56 changes: 52 additions & 4 deletions engine/plugins/api/gleif/lei_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,72 @@ import (
"github.com/owasp-amass/open-asset-model/general"
)

func (g *gleif) getLEIRecord(ident *general.Identifier) (*leiRecord, error) {
func (g *gleif) getLEIRecord(id *general.Identifier) (*leiRecord, error) {
g.rlimit.Take()

u := "https://api.gleif.org/api/v1/lei-records/" + ident.EntityID
u := "https://api.gleif.org/api/v1/lei-records/" + id.EntityID
resp, err := http.RequestWebPage(context.TODO(), &http.Request{URL: u})
if err != nil || resp.Body == "" {
if err != nil || resp.StatusCode != 200 || resp.Body == "" {
return nil, err
}

var result singleResponse
if err := json.Unmarshal([]byte(resp.Body), &result); err != nil {
return nil, err
} else if len(result.Data.ID) == 0 || result.Data.Type != "lei-records" {
} else if result.Data.Type != "lei-records" || result.Data.ID != id.EntityID {
return nil, errors.New("failed to find the LEI record")
}
return &result.Data, nil
}

func (g *gleif) getDirectParent(id *general.Identifier) (*leiRecord, error) {
g.rlimit.Take()

u := "https://api.gleif.org/api/v1/lei-records/" + id.EntityID + "/direct-parent"
resp, err := http.RequestWebPage(context.TODO(), &http.Request{URL: u})
if err != nil || resp.StatusCode != 200 || resp.Body == "" {
return nil, err
}

var result singleResponse
if err := json.Unmarshal([]byte(resp.Body), &result); err != nil {
return nil, err
} else if result.Data.Type != "lei-records" {
return nil, errors.New("failed to find the LEI record")
}
return &result.Data, nil
}

func (g *gleif) getDirectChildren(id *general.Identifier) ([]*leiRecord, error) {
var children []*leiRecord

last := 1
link := "https://api.gleif.org/api/v1/lei-records/" + id.EntityID + "/direct-children"
for i := 1; i <= last && link != ""; i++ {
g.rlimit.Take()

resp, err := http.RequestWebPage(context.TODO(), &http.Request{URL: link})
if err != nil || resp.StatusCode != 200 || resp.Body == "" {
return nil, err
}
link = ""

Check failure on line 68 in engine/plugins/api/gleif/lei_record.go

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest, 1.23.1)

ineffectual assignment to link (ineffassign)

var result multipleResponse
if err := json.Unmarshal([]byte(resp.Body), &result); err != nil {
return nil, err
}

for _, rec := range result.Data {
children = append(children, &rec)
}

link = result.Links.Next
last = result.Meta.Pagination.LastPage
}

return children, nil
}

func (g *gleif) createLEIIdentifier(session et.Session, orgent *dbt.Entity, lei *general.Identifier) (*dbt.Entity, error) {
id, err := session.Cache().CreateAsset(lei)
if err != nil {
Expand Down
64 changes: 64 additions & 0 deletions engine/plugins/api/gleif/lei_record_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright © by Jeff Foley 2017-2025. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
// SPDX-License-Identifier: Apache-2.0

package gleif

import (
"fmt"
"testing"

"github.com/owasp-amass/open-asset-model/general"
"github.com/stretchr/testify/assert"
)

func TestGetLEIRecord(t *testing.T) {
p := NewGLEIF()
g := p.(*gleif)

lei := "ZXTILKJKG63JELOEG630"
id := &general.Identifier{
UniqueID: fmt.Sprintf("%s:%s", general.LEICode, lei),
EntityID: lei,
Type: general.LEICode,
}

record, err := g.getLEIRecord(id)
assert.NoError(t, err)
assert.NotNil(t, record)
assert.Equal(t, "AMAZON.COM, INC.", record.Attributes.Entity.LegalName.Name)
}

func TestGetDirectParent(t *testing.T) {
p := NewGLEIF()
g := p.(*gleif)

lei := "25490065U2GR0UPXFY63"
id := &general.Identifier{
UniqueID: fmt.Sprintf("%s:%s", general.LEICode, lei),
EntityID: lei,
Type: general.LEICode,
}

record, err := g.getDirectParent(id)
assert.NoError(t, err)
assert.NotNil(t, record)
assert.Equal(t, "AMAZON.COM, INC.", record.Attributes.Entity.LegalName.Name)
}

func TestGetDirectChildren(t *testing.T) {
p := NewGLEIF()
g := p.(*gleif)

lei := "ZXTILKJKG63JELOEG630"
id := &general.Identifier{
UniqueID: fmt.Sprintf("%s:%s", general.LEICode, lei),
EntityID: lei,
Type: general.LEICode,
}

children, err := g.getDirectChildren(id)
assert.NoError(t, err)
assert.NotEmpty(t, children)
assert.GreaterOrEqual(t, len(children), 12)
}
3 changes: 3 additions & 0 deletions engine/plugins/api/gleif/org_lei.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ func (g *gleif) updateOrgFromLEIRecord(e *et.Event, orgent *dbt.Entity, lei *lei
for _, other := range lei.Attributes.Entity.OtherNames {
otherNames = append(otherNames, strings.ToLower(other.Name))
}
for _, other := range lei.Attributes.Entity.TransliteratedOtherNames {
otherNames = append(otherNames, strings.ToLower(other.Name))
}
_ = g.addIdentifiersToOrg(e, orgent, general.OrganizationName, otherNames)

o.FoundingDate = lei.Attributes.Entity.CreationDate
Expand Down
79 changes: 6 additions & 73 deletions engine/plugins/api/gleif/related.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@
package gleif

import (
"context"
"encoding/json"
"errors"
"fmt"
"log/slog"
"time"

"github.com/owasp-amass/amass/v4/engine/plugins/support"
et "github.com/owasp-amass/amass/v4/engine/types"
"github.com/owasp-amass/amass/v4/utils/net/http"
dbt "github.com/owasp-amass/asset-db/types"
oam "github.com/owasp-amass/open-asset-model"
"github.com/owasp-amass/open-asset-model/general"
Expand Down Expand Up @@ -98,82 +94,19 @@ func (ro *relatedOrgs) lookup(e *et.Event, ident *dbt.Entity, since time.Time) [
}

func (ro *relatedOrgs) query(e *et.Event, ident *dbt.Entity) []*dbt.Entity {
var orgs []*dbt.Entity

lei := ident.Asset.(*general.Identifier)
leirec, err := ro.plugin.getLEIRecord(lei)
if err != nil || leirec == nil {
return orgs
}

var parent *leiRecord
if link := leirec.Relationships.DirectParent.Links.LEIRecord; link != "" {
ro.plugin.rlimit.Take()

if resp, err := http.RequestWebPage(context.TODO(), &http.Request{URL: link}); err == nil && resp.StatusCode == 200 && resp.Body != "" {
var result singleResponse

if err := json.Unmarshal([]byte(resp.Body), &result); err == nil {
if result.Data.ID != lei.EntityID {
parent = &result.Data
}
} else {
msg := fmt.Sprintf("failed to unmarshal the direct-parent page for LEI - %s: %s", lei.EntityID, err.Error())
e.Session.Log().Error(msg, slog.Group("plugin", "name", ro.plugin.name, "handler", ro.name))
}
}
}

var children []*leiRecord
if link := leirec.Relationships.DirectChildren.Links.Related; link != "" {
last := 1

for i := 1; i <= last && link != ""; i++ {
ro.plugin.rlimit.Take()
id := ident.Asset.(*general.Identifier)

resp, err := http.RequestWebPage(context.TODO(), &http.Request{URL: link})
if err != nil || resp.StatusCode != 200 || resp.Body == "" {
msg := fmt.Sprintf("failed to obtain the direct-children page for LEI - %s: %s", lei.EntityID, err.Error())
e.Session.Log().Error(msg, slog.Group("plugin", "name", ro.plugin.name, "handler", ro.name))
break
}
link = ""

var result multipleResponse
if err := json.Unmarshal([]byte(resp.Body), &result); err != nil {
msg := fmt.Sprintf("failed to unmarshal the direct-children page for LEI - %s: %s", lei.EntityID, err.Error())
e.Session.Log().Error(msg, slog.Group("plugin", "name", ro.plugin.name, "handler", ro.name))
break
}

for _, rec := range result.Data {
children = append(children, &rec)
}

link = result.Links.Next
last = result.Meta.Pagination.LastPage
}
}

return ro.store(e, ident, leirec, parent, children)
parent, _ := ro.plugin.getDirectParent(id)
children, _ := ro.plugin.getDirectChildren(id)
return ro.store(e, ident, parent, children)
}

func (ro *relatedOrgs) store(e *et.Event, ident *dbt.Entity, leirec, parent *leiRecord, children []*leiRecord) []*dbt.Entity {
func (ro *relatedOrgs) store(e *et.Event, ident *dbt.Entity, parent *leiRecord, children []*leiRecord) []*dbt.Entity {
var orgs []*dbt.Entity

orgent := ro.plugin.leiToOrgEntity(e, ident)
if orgent == nil {
var err error
o := &org.Organization{Name: leirec.Attributes.Entity.LegalName.Name}

orgent, err = support.CreateOrgAsset(e.Session, nil, nil, o, ro.plugin.source)
if err != nil {
return orgs
}

orgs = append(orgs, orgent)
ro.plugin.updateOrgFromLEIRecord(e, orgent, leirec)
support.MarkAssetMonitored(e.Session, orgent, ro.plugin.source)
return orgs
}

if parent != nil {
Expand Down
12 changes: 8 additions & 4 deletions engine/plugins/api/gleif/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,14 @@ type leiRecord struct {
Language string `json:"language"`
Type string `json:"type"`
} `json:"otherNames"`
TransliteratedOtherNames []string `json:"transliteratedOtherNames"`
LegalAddress leiAddress `json:"legalAddress"`
HeadquartersAddress leiAddress `json:"headquartersAddress"`
RegisteredAt struct {
TransliteratedOtherNames []struct {
Name string `json:"name"`
Language string `json:"language"`
Type string `json:"type"`
} `json:"transliteratedOtherNames"`
LegalAddress leiAddress `json:"legalAddress"`
HeadquartersAddress leiAddress `json:"headquartersAddress"`
RegisteredAt struct {
ID string `json:"id"`
Other string `json:"other"`
} `json:"registeredAt"`
Expand Down

0 comments on commit 515861b

Please sign in to comment.