Echo example
This simple echo example accepts any input entity and returns a new Entity with the same display value. The Transform is only runnable on Phrase entities. This example is the most simple type of transform expecting a single input entity and returning a single output entity.
from maltego.server import register_transform
from maltego.entities import Phrase
@register_transform(display_name='Echo [Maltego Examples]')
async def transform(entity: Phrase) -> Phrase:
return Phrase(entity.value)Hello Person
This simple echo example accept a person as input entity and returns a Phrase with a greeting to that person. The transform will only be executable on Person entities.
from maltego.server import register_transform
from maltego.entities import Phrase, Person
@register_transform(display_name='Hello Person [Maltego Examples]')
async def greet(entity: Person) -> Phrase:
return Phrase(f"Hello {entity.value}")Union Inputs
This example shows how it is possible to define a single transform on multiple inputs. If a user selects either a Person or a Phrase entity in a graph, the transform can be executed.
from typing import Union
from maltego.server import register_transform
from maltego.entities import Phrase, Person
@register_transform(
display_name="Phrase or Person Input [Maltego Examples]"
)
async def transform_union(input_entity: Union[Phrase, Person]) -> Union[Phrase, Person]:
return Person(input_entity.value)List input
In this example we expects a list as the transform input instead of a single entity. If a user selects multiple entities of type Phrase and runs this transform all of those entities are exposed to the transform function.
from typing import List
from maltego.server import register_transform
from maltego.entities import Phrase
@register_transform(
display_name="List Input [Maltego Examples]"
)
async def transform_list(input_entities: List[Phrase]) -> Phrase:
return Phrase(str(len(input_entities)))List output
In this example we return a list instead of a single entity. In the graph, all returned entities are linked to the input entity.
from typing import List
from maltego.server import register_transform
from maltego.entities import Phrase
@register_transform(
display_name="List Output [Maltego Examples]"
)
async def transform_list(input_entity: Phrase) -> List[Phrase]:
return [Phrase(input_entity.value + f"_{i}") for i in range(0, 3)]Async Generator
It is also possible to use a async generators with the yield keyword to create new entities asynchronously. In the following example a new Phrase entity is created each second and returned to the user as they get created.
This allows to e. g. query or monitor slow API's and populate the graph anytime we receive a new result.
from typing import List
from maltego.server import register_transform
from maltego.entities import Phrase
import asyncio
@register_transform(
display_name="Async output [Maltego Examples]"
)
async def transform_list(input_entity: Phrase) -> List[Phrase]:
for i in range(1, 10):
yield Phrase(str(i))
await asyncio.sleep(1)Transform Settings
This example visualize how transform settings can be used to gather additional input on a transform execution.
Transform settings support different data types. It is further possible to define default values and whether the setting is nullable.
For a complete guide to the available setting options, see the Transform Settings article.
from maltego.server import register_transform, TransformSetting
from maltego.entities import Phrase
@register_transform(
display_name="Settings Test [Maltego Examples]"
settings=[
TransformSetting(
name="str",
display_name="Test string Transform Setting",
type="string"
),
TransformSetting(
name="double",
display_name="Test double Transform Setting",
type="double"
),
TransformSetting(
name="int", display_name="Test int Transform Setting", type="int"
),
TransformSetting(
name="boolean", display_name="Test boolean Transform Setting", type="boolean"
),
TransformSetting(
name="date", display_name="Test date Transform Setting", type="date"
),
TransformSetting(
name="datetime", display_name="Test datetime Transform Setting", type="datetime"
),
TransformSetting(
name="daterange", display_name="Test daterange Transform Setting", type="daterange"
),
],
)
async def transform_all_settings(input_entity: Phrase, settings) -> Phrase:
output_entity = Phrase(input_entity.value)
output_entity.add_display_field("settings", str(settings))
return output_entityGraph Transforms
Simple Graph
from maltego.server import register_transform, MaltegoGraph
from maltego.entities import Phrase
@register_transform(
display_name="Graph-in Any Input [Maltego Examples]",
)
async def transform_graph(graph: MaltegoGraph) -> MaltegoGraph:
previous_entity = graph.add_entity(Phrase("new_entity"))
for i in range(0, 5):
entity = graph.add_entity(Phrase(f"new_entity_{i}"))
graph.add_link(previous_entity, entity)
previous_entity = entity
return graphGraph With Entity Condition
from maltego.server import register_transform, MaltegoGraph
from maltego.entities import Phrase
@register_transform(
display_name="Phrase Graph-in [Maltego Examples]",
)
async def transform_graph_phrase(graph: MaltegoGraph[Phrase]) -> MaltegoGraph:
graph.add_entity(Phrase(str(len(graph.entities))))
return graphGraph With Entity Condition Union
from typing import Union
from maltego.server import register_transform, MaltegoGraph
from maltego.entities import Phrase, Person
@register_transform(
display_name="Graph-in Phrase and Person [Maltego Examples]",
)
async def transform_graph_phrase_person(graph: MaltegoGraph[Union[Phrase, Person]]) -> MaltegoGraph:
graph.add_entity(Phrase(str(len(graph.entities))))
return graphEntity Property Constraints Transforms
This section demonstrates how to define basic input constraints for Maltego transforms. These examples illustrate different ways to match entities and properties based on simple conditions.
Example 1: Matching Entities with a Specific Entity Type, Property Name, Property Value
This example matches entities of type "Alias" that have a property with the name "alias" and a value starting with "johndoe".
@register_transform(
input_constraint=EntitySatisfiesAll(
constraints=[
EntityTypeConstraint(entity_type="maltego.Alias"),
EntityHasPropertySatisfying(
constraint=PropertySatisfiesAll(
constraints=[
PropertyValueStringMatch(
value="johndoe",
ignore_case=True,
match_type=ConstraintStringMatchType.STARTSWITH,
),
PropertyNameEquals(value="alias"),
]
)
),
]
)
)
def match_alias(input_entity: MaltegoEntity):
# transform implementation hereExample 2: Matching Entities with Any Property Name
This example matches entities in a graph that have at least one property with the name "alias".
@register_transform(
input_constraint=EntitySatisfiesAll(
constraints=[
EntityHasPropertySatisfying(
constraint=PropertySatisfiesAll(
constraints=[
PropertyNameEquals(value="alias"),
)
)
),
]
)
)
def match_property_name(input_graph: MaltegoGraph):
# transform implementation hereExample 3: Matching Entities Using Regex
This example matches "Domain" entities with a property called "fqdn" that matches a regex pattern.
@register_transform(
input_constraint=EntitySatisfiesAll(
constraints=[
EntityHasPropertySatisfying(
constraint=PropertySatisfiesAll(
constraints=[
PropertyValueMatchesRegex(
regex=r"^(?!-)[A-Za-z0-9-]{1,63}\.[A-Za-z]{2,6}$"
)
]
)
)
]
)
)
def match_domain_regex(input_entity: Domain):
# transform implementation hereExample 4: Excluding Entities with a Specific Property
This example matches entities that do not have a property named "alias" with the value "admin".
from maltego.server import register_transform
from maltego.server.constraints import EntitySatisfiesNone, EntityHasPropertySatisfying, PropertyValueEquals
from maltego.model import MaltegoEntity
@register_transform(
input_constraint=EntitySatisfiesNone(
constraints=[
EntityHasPropertySatisfying(
constraint=PropertySatisfiesAll(
constraints=[
PropertyNameEquals(value="alias"),
PropertyValueEquals(value="admin")
]
)
)
]
)
)
def exclude_admin_username(input_entity: MaltegoEntity):
# transform implementation here