epicyon/context.py

823 lines
29 KiB
Python

__filename__ = "inbox.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.3.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Security"
VALID_CONTEXTS = (
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/identity/v1",
"https://w3id.org/security/v1",
"*/apschema/v1.9",
"*/apschema/v1.10",
"*/apschema/v1.21",
"*/apschema/v1.20",
"*/litepub-0.1.jsonld",
"https://litepub.social/litepub/context.jsonld"
)
def get_individual_post_context() -> []:
"""Returns the context for an individual post
"""
return [
'https://www.w3.org/ns/activitystreams',
{
"ostatus": "http://ostatus.org#",
"atomUri": "ostatus:atomUri",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"conversation": "ostatus:conversation",
"sensitive": "as:sensitive",
"toot": "http://joinmastodon.org/ns#",
"votersCount": "toot:votersCount",
"blurhash": "toot:blurhash"
}
]
def has_valid_context(post_json_object: {}) -> bool:
"""Are the links within the @context of a post recognised?
"""
if not post_json_object.get('@context'):
return False
if isinstance(post_json_object['@context'], list):
for url in post_json_object['@context']:
if not isinstance(url, str):
continue
if url not in VALID_CONTEXTS:
wildcard_found = False
for cont in VALID_CONTEXTS:
if cont.startswith('*'):
cont = cont.replace('*', '')
if url.endswith(cont):
wildcard_found = True
break
if not wildcard_found:
print('Unrecognized @context: ' + url)
return False
elif isinstance(post_json_object['@context'], str):
url = post_json_object['@context']
if url not in VALID_CONTEXTS:
wildcard_found = False
for cont in VALID_CONTEXTS:
if cont.startswith('*'):
cont = cont.replace('*', '')
if url.endswith(cont):
wildcard_found = True
break
if not wildcard_found:
print('Unrecognized @context: ' + url)
return False
else:
# not a list or string
return False
return True
def getApschemaV1_9() -> {}:
# https://domain/apschema/v1.9
return {
"@context": {
"zot": "https://hub.disroot.org/apschema#",
"id": "@id",
"type": "@type",
"commentPolicy": "as:commentPolicy",
"meData": "zot:meData",
"meDataType": "zot:meDataType",
"meEncoding": "zot:meEncoding",
"meAlgorithm": "zot:meAlgorithm",
"meCreator": "zot:meCreator",
"meSignatureValue": "zot:meSignatureValue",
"locationAddress": "zot:locationAddress",
"locationPrimary": "zot:locationPrimary",
"locationDeleted": "zot:locationDeleted",
"nomadicLocation": "zot:nomadicLocation",
"nomadicHubs": "zot:nomadicHubs",
"emojiReaction": "zot:emojiReaction",
"expires": "zot:expires",
"directMessage": "zot:directMessage",
"schema": "http://schema.org#",
"PropertyValue": "schema:PropertyValue",
"value": "schema:value",
"magicEnv": {
"@id": "zot:magicEnv",
"@type": "@id"
},
"nomadicLocations": {
"@id": "zot:nomadicLocations",
"@type": "@id"
},
"ostatus": "http://ostatus.org#",
"conversation": "ostatus:conversation",
"diaspora": "https://diasporafoundation.org/ns/",
"guid": "diaspora:guid",
"Hashtag": "as:Hashtag"
}
}
def getApschemaV1_20() -> {}:
# https://domain/apschema/v1.20
return {
"@context":
{
"as": "https://www.w3.org/ns/activitystreams#",
"zot": "https://zap.dog/apschema#",
"toot": "http://joinmastodon.org/ns#",
"ostatus": "http://ostatus.org#",
"schema": "http://schema.org#",
"litepub": "http://litepub.social/ns#",
"sm": "http://smithereen.software/ns#",
"conversation": "ostatus:conversation",
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"oauthRegistrationEndpoint": "litepub:oauthRegistrationEndpoint",
"sensitive": "as:sensitive",
"movedTo": "as:movedTo",
"copiedTo": "as:copiedTo",
"alsoKnownAs": "as:alsoKnownAs",
"inheritPrivacy": "as:inheritPrivacy",
"EmojiReact": "as:EmojiReact",
"commentPolicy": "zot:commentPolicy",
"topicalCollection": "zot:topicalCollection",
"eventRepeat": "zot:eventRepeat",
"emojiReaction": "zot:emojiReaction",
"expires": "zot:expires",
"directMessage": "zot:directMessage",
"Category": "zot:Category",
"replyTo": "zot:replyTo",
"PropertyValue": "schema:PropertyValue",
"value": "schema:value",
"discoverable": "toot:discoverable",
"wall": "sm:wall"
}
}
def getApschemaV1_10() -> {}:
# https://domain/apschema/v1.10
return {
'@context': {
'Hashtag': 'as:Hashtag',
'PropertyValue': 'schema:PropertyValue',
'commentPolicy': 'zot:commentPolicy',
'conversation': 'ostatus:conversation',
'diaspora': 'https://diasporafoundation.org/ns/',
'directMessage': 'zot:directMessage',
'emojiReaction': 'zot:emojiReaction',
'expires': 'zot:expires',
'guid': 'diaspora:guid',
'id': '@id',
'locationAddress': 'zot:locationAddress',
'locationDeleted': 'zot:locationDeleted',
'locationPrimary': 'zot:locationPrimary',
'magicEnv': {'@id': 'zot:magicEnv', '@type': '@id'},
'manuallyApprovesFollowers': 'as:manuallyApprovesFollowers',
'meAlgorithm': 'zot:meAlgorithm',
'meCreator': 'zot:meCreator',
'meData': 'zot:meData',
'meDataType': 'zot:meDataType',
'meEncoding': 'zot:meEncoding',
'meSignatureValue': 'zot:meSignatureValue',
'nomadicHubs': 'zot:nomadicHubs',
'nomadicLocation': 'zot:nomadicLocation',
'nomadicLocations': {'@id': 'zot:nomadicLocations',
'@type': '@id'},
'ostatus': 'http://ostatus.org#',
'schema': 'http://schema.org#',
'type': '@type',
'value': 'schema:value',
'zot': 'https://hubzilla.vikshepa.com/apschema#'
}
}
def getApschemaV1_21() -> {}:
# https://domain/apschema/v1.21
return {
"@context": {
"zot": "https://raitisoja.com/apschema#",
"as": "https://www.w3.org/ns/activitystreams#",
"toot": "http://joinmastodon.org/ns#",
"ostatus": "http://ostatus.org#",
"schema": "http://schema.org#",
"conversation": "ostatus:conversation",
"sensitive": "as:sensitive",
"movedTo": "as:movedTo",
"copiedTo": "as:copiedTo",
"alsoKnownAs": "as:alsoKnownAs",
"inheritPrivacy": "as:inheritPrivacy",
"EmojiReact": "as:EmojiReact",
"commentPolicy": "zot:commentPolicy",
"topicalCollection": "zot:topicalCollection",
"eventRepeat": "zot:eventRepeat",
"emojiReaction": "zot:emojiReaction",
"expires": "zot:expires",
"directMessage": "zot:directMessage",
"Category": "zot:Category",
"replyTo": "zot:replyTo",
"PropertyValue": "schema:PropertyValue",
"value": "schema:value",
"discoverable": "toot:discoverable"
}
}
def get_litepub_social() -> {}:
# https://litepub.social/litepub/context.jsonld
return {
'@context': [
'https://www.w3.org/ns/activitystreams',
'https://w3id.org/security/v1',
{
'Emoji': 'toot:Emoji',
'Hashtag': 'as:Hashtag',
'PropertyValue': 'schema:PropertyValue',
'atomUri': 'ostatus:atomUri',
'conversation': {
'@id': 'ostatus:conversation',
'@type': '@id'
},
'manuallyApprovesFollowers': 'as:manuallyApprovesFollowers',
'ostatus': 'http://ostatus.org#',
'schema': 'http://schema.org',
'sensitive': 'as:sensitive',
'toot': 'http://joinmastodon.org/ns#',
'totalItems': 'as:totalItems',
'value': 'schema:value'
}
]
}
def getLitepubV0_1() -> {}:
# https://domain/schemas/litepub-0.1.jsonld
return {
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"Emoji": "toot:Emoji",
"Hashtag": "as:Hashtag",
"PropertyValue": "schema:PropertyValue",
"atomUri": "ostatus:atomUri",
"conversation": {
"@id": "ostatus:conversation",
"@type": "@id"
},
"discoverable": "toot:discoverable",
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"capabilities": "litepub:capabilities",
"ostatus": "http://ostatus.org#",
"schema": "http://schema.org#",
"toot": "http://joinmastodon.org/ns#",
"value": "schema:value",
"sensitive": "as:sensitive",
"litepub": "http://litepub.social/ns#",
"invisible": "litepub:invisible",
"directMessage": "litepub:directMessage",
"listMessage": {
"@id": "litepub:listMessage",
"@type": "@id"
},
"oauthRegistrationEndpoint": {
"@id": "litepub:oauthRegistrationEndpoint",
"@type": "@id"
},
"EmojiReact": "litepub:EmojiReact",
"ChatMessage": "litepub:ChatMessage",
"alsoKnownAs": {
"@id": "as:alsoKnownAs",
"@type": "@id"
}
}
]
}
def get_v1security_schema() -> {}:
# https://w3id.org/security/v1
return {
"@context": {
"id": "@id",
"type": "@type",
"dc": "http://purl.org/dc/terms/",
"sec": "https://w3id.org/security#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016",
"Ed25519Signature2018": "sec:Ed25519Signature2018",
"EncryptedMessage": "sec:EncryptedMessage",
"GraphSignature2012": "sec:GraphSignature2012",
"LinkedDataSignature2015": "sec:LinkedDataSignature2015",
"LinkedDataSignature2016": "sec:LinkedDataSignature2016",
"CryptographicKey": "sec:Key",
"authenticationTag": "sec:authenticationTag",
"canonicalizationAlgorithm": "sec:canonicalizationAlgorithm",
"cipherAlgorithm": "sec:cipherAlgorithm",
"cipherData": "sec:cipherData",
"cipherKey": "sec:cipherKey",
"created": {"@id": "dc:created", "@type": "xsd:dateTime"},
"creator": {"@id": "dc:creator", "@type": "@id"},
"digestAlgorithm": "sec:digestAlgorithm",
"digestValue": "sec:digestValue",
"domain": "sec:domain",
"encryptionKey": "sec:encryptionKey",
"expiration": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
"expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
"initializationVector": "sec:initializationVector",
"iterationCount": "sec:iterationCount",
"nonce": "sec:nonce",
"normalizationAlgorithm": "sec:normalizationAlgorithm",
"owner": {"@id": "sec:owner", "@type": "@id"},
"password": "sec:password",
"privateKey": {"@id": "sec:privateKey", "@type": "@id"},
"privateKeyPem": "sec:privateKeyPem",
"publicKey": {"@id": "sec:publicKey", "@type": "@id"},
"publicKeyBase58": "sec:publicKeyBase58",
"publicKeyPem": "sec:publicKeyPem",
"publicKeyWif": "sec:publicKeyWif",
"publicKeyService": {
"@id": "sec:publicKeyService", "@type": "@id"
},
"revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"},
"salt": "sec:salt",
"signature": "sec:signature",
"signatureAlgorithm": "sec:signingAlgorithm",
"signatureValue": "sec:signatureValue"
}
}
def get_v1schema() -> {}:
# https://w3id.org/identity/v1
return {
"@context": {
"id": "@id",
"type": "@type",
"cred": "https://w3id.org/credentials#",
"dc": "http://purl.org/dc/terms/",
"identity": "https://w3id.org/identity#",
"perm": "https://w3id.org/permissions#",
"ps": "https://w3id.org/payswarm#",
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"sec": "https://w3id.org/security#",
"schema": "http://schema.org/",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"Group": "https://www.w3.org/ns/activitystreams#Group",
"claim": {"@id": "cred:claim", "@type": "@id"},
"credential": {"@id": "cred:credential", "@type": "@id"},
"issued": {"@id": "cred:issued", "@type": "xsd:dateTime"},
"issuer": {"@id": "cred:issuer", "@type": "@id"},
"recipient": {"@id": "cred:recipient", "@type": "@id"},
"Credential": "cred:Credential",
"CryptographicKeyCredential": "cred:CryptographicKeyCredential",
"about": {"@id": "schema:about", "@type": "@id"},
"address": {"@id": "schema:address", "@type": "@id"},
"addressCountry": "schema:addressCountry",
"addressLocality": "schema:addressLocality",
"addressRegion": "schema:addressRegion",
"comment": "rdfs:comment",
"created": {"@id": "dc:created", "@type": "xsd:dateTime"},
"creator": {"@id": "dc:creator", "@type": "@id"},
"description": "schema:description",
"email": "schema:email",
"familyName": "schema:familyName",
"givenName": "schema:givenName",
"image": {"@id": "schema:image", "@type": "@id"},
"label": "rdfs:label",
"name": "schema:name",
"postalCode": "schema:postalCode",
"streetAddress": "schema:streetAddress",
"title": "dc:title",
"url": {"@id": "schema:url", "@type": "@id"},
"Person": "schema:Person",
"PostalAddress": "schema:PostalAddress",
"Organization": "schema:Organization",
"identityService": {
"@id": "identity:identityService", "@type": "@id"
},
"idp": {"@id": "identity:idp", "@type": "@id"},
"Identity": "identity:Identity",
"paymentProcessor": "ps:processor",
"preferences": {"@id": "ps:preferences", "@type": "@vocab"},
"cipherAlgorithm": "sec:cipherAlgorithm",
"cipherData": "sec:cipherData",
"cipherKey": "sec:cipherKey",
"digestAlgorithm": "sec:digestAlgorithm",
"digestValue": "sec:digestValue",
"domain": "sec:domain",
"expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
"initializationVector": "sec:initializationVector",
"member": {"@id": "schema:member", "@type": "@id"},
"memberOf": {"@id": "schema:memberOf", "@type": "@id"},
"nonce": "sec:nonce",
"normalizationAlgorithm": "sec:normalizationAlgorithm",
"owner": {"@id": "sec:owner", "@type": "@id"},
"password": "sec:password",
"privateKey": {"@id": "sec:privateKey", "@type": "@id"},
"privateKeyPem": "sec:privateKeyPem",
"publicKey": {"@id": "sec:publicKey", "@type": "@id"},
"publicKeyPem": "sec:publicKeyPem",
"publicKeyService": {
"@id": "sec:publicKeyService", "@type": "@id"
},
"revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"},
"signature": "sec:signature",
"signatureAlgorithm": "sec:signatureAlgorithm",
"signatureValue": "sec:signatureValue",
"CryptographicKey": "sec:Key",
"EncryptedMessage": "sec:EncryptedMessage",
"GraphSignature2012": "sec:GraphSignature2012",
"LinkedDataSignature2015": "sec:LinkedDataSignature2015",
"accessControl": {"@id": "perm:accessControl", "@type": "@id"},
"writePermission": {"@id": "perm:writePermission", "@type": "@id"}
}
}
def get_activitystreams_schema() -> {}:
# https://www.w3.org/ns/activitystreams
return {
"@context": {
"@vocab": "_:",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"as": "https://www.w3.org/ns/activitystreams#",
"ldp": "http://www.w3.org/ns/ldp#",
"vcard": "http://www.w3.org/2006/vcard/ns#",
"id": "@id",
"type": "@type",
"Accept": "as:Accept",
"Activity": "as:Activity",
"IntransitiveActivity": "as:IntransitiveActivity",
"Add": "as:Add",
"Announce": "as:Announce",
"Application": "as:Application",
"Arrive": "as:Arrive",
"Article": "as:Article",
"Audio": "as:Audio",
"Block": "as:Block",
"Collection": "as:Collection",
"CollectionPage": "as:CollectionPage",
"Relationship": "as:Relationship",
"Create": "as:Create",
"Delete": "as:Delete",
"Dislike": "as:Dislike",
"Document": "as:Document",
"Event": "as:Event",
"Follow": "as:Follow",
"Flag": "as:Flag",
"Group": "as:Group",
"Ignore": "as:Ignore",
"Image": "as:Image",
"Invite": "as:Invite",
"Join": "as:Join",
"Leave": "as:Leave",
"Like": "as:Like",
"Link": "as:Link",
"Mention": "as:Mention",
"Note": "as:Note",
"Object": "as:Object",
"Offer": "as:Offer",
"OrderedCollection": "as:OrderedCollection",
"OrderedCollectionPage": "as:OrderedCollectionPage",
"Organization": "as:Organization",
"Page": "as:Page",
"Person": "as:Person",
"Place": "as:Place",
"Profile": "as:Profile",
"Question": "as:Question",
"Reject": "as:Reject",
"Remove": "as:Remove",
"Service": "as:Service",
"TentativeAccept": "as:TentativeAccept",
"TentativeReject": "as:TentativeReject",
"Tombstone": "as:Tombstone",
"Undo": "as:Undo",
"Update": "as:Update",
"Video": "as:Video",
"View": "as:View",
"Listen": "as:Listen",
"Read": "as:Read",
"Move": "as:Move",
"Travel": "as:Travel",
"IsFollowing": "as:IsFollowing",
"IsFollowedBy": "as:IsFollowedBy",
"IsContact": "as:IsContact",
"IsMember": "as:IsMember",
"subject": {
"@id": "as:subject",
"@type": "@id"
},
"relationship": {
"@id": "as:relationship",
"@type": "@id"
},
"actor": {
"@id": "as:actor",
"@type": "@id"
},
"attributedTo": {
"@id": "as:attributedTo",
"@type": "@id"
},
"attachment": {
"@id": "as:attachment",
"@type": "@id"
},
"bcc": {
"@id": "as:bcc",
"@type": "@id"
},
"bto": {
"@id": "as:bto",
"@type": "@id"
},
"cc": {
"@id": "as:cc",
"@type": "@id"
},
"context": {
"@id": "as:context",
"@type": "@id"
},
"current": {
"@id": "as:current",
"@type": "@id"
},
"first": {
"@id": "as:first",
"@type": "@id"
},
"generator": {
"@id": "as:generator",
"@type": "@id"
},
"icon": {
"@id": "as:icon",
"@type": "@id"
},
"image": {
"@id": "as:image",
"@type": "@id"
},
"inReplyTo": {
"@id": "as:inReplyTo",
"@type": "@id"
},
"items": {
"@id": "as:items",
"@type": "@id"
},
"instrument": {
"@id": "as:instrument",
"@type": "@id"
},
"orderedItems": {
"@id": "as:items",
"@type": "@id",
"@container": "@list"
},
"last": {
"@id": "as:last",
"@type": "@id"
},
"location": {
"@id": "as:location",
"@type": "@id"
},
"next": {
"@id": "as:next",
"@type": "@id"
},
"object": {
"@id": "as:object",
"@type": "@id"
},
"oneOf": {
"@id": "as:oneOf",
"@type": "@id"
},
"anyOf": {
"@id": "as:anyOf",
"@type": "@id"
},
"closed": {
"@id": "as:closed",
"@type": "xsd:dateTime"
},
"origin": {
"@id": "as:origin",
"@type": "@id"
},
"accuracy": {
"@id": "as:accuracy",
"@type": "xsd:float"
},
"prev": {
"@id": "as:prev",
"@type": "@id"
},
"preview": {
"@id": "as:preview",
"@type": "@id"
},
"replies": {
"@id": "as:replies",
"@type": "@id"
},
"result": {
"@id": "as:result",
"@type": "@id"
},
"audience": {
"@id": "as:audience",
"@type": "@id"
},
"partOf": {
"@id": "as:partOf",
"@type": "@id"
},
"tag": {
"@id": "as:tag",
"@type": "@id"
},
"target": {
"@id": "as:target",
"@type": "@id"
},
"to": {
"@id": "as:to",
"@type": "@id"
},
"url": {
"@id": "as:url",
"@type": "@id"
},
"altitude": {
"@id": "as:altitude",
"@type": "xsd:float"
},
"content": "as:content",
"contentMap": {
"@id": "as:content",
"@container": "@language"
},
"name": "as:name",
"nameMap": {
"@id": "as:name",
"@container": "@language"
},
"duration": {
"@id": "as:duration",
"@type": "xsd:duration"
},
"endTime": {
"@id": "as:endTime",
"@type": "xsd:dateTime"
},
"height": {
"@id": "as:height",
"@type": "xsd:nonNegativeInteger"
},
"href": {
"@id": "as:href",
"@type": "@id"
},
"hreflang": "as:hreflang",
"latitude": {
"@id": "as:latitude",
"@type": "xsd:float"
},
"longitude": {
"@id": "as:longitude",
"@type": "xsd:float"
},
"mediaType": "as:mediaType",
"published": {
"@id": "as:published",
"@type": "xsd:dateTime"
},
"radius": {
"@id": "as:radius",
"@type": "xsd:float"
},
"rel": "as:rel",
"startIndex": {
"@id": "as:startIndex",
"@type": "xsd:nonNegativeInteger"
},
"startTime": {
"@id": "as:startTime",
"@type": "xsd:dateTime"
},
"summary": "as:summary",
"summaryMap": {
"@id": "as:summary",
"@container": "@language"
},
"totalItems": {
"@id": "as:totalItems",
"@type": "xsd:nonNegativeInteger"
},
"units": "as:units",
"updated": {
"@id": "as:updated",
"@type": "xsd:dateTime"
},
"width": {
"@id": "as:width",
"@type": "xsd:nonNegativeInteger"
},
"describes": {
"@id": "as:describes",
"@type": "@id"
},
"formerType": {
"@id": "as:formerType",
"@type": "@id"
},
"deleted": {
"@id": "as:deleted",
"@type": "xsd:dateTime"
},
"inbox": {
"@id": "ldp:inbox",
"@type": "@id"
},
"outbox": {
"@id": "as:outbox",
"@type": "@id"
},
"following": {
"@id": "as:following",
"@type": "@id"
},
"followers": {
"@id": "as:followers",
"@type": "@id"
},
"streams": {
"@id": "as:streams",
"@type": "@id"
},
"preferredUsername": "as:preferredUsername",
"endpoints": {
"@id": "as:endpoints",
"@type": "@id"
},
"uploadMedia": {
"@id": "as:uploadMedia",
"@type": "@id"
},
"proxyUrl": {
"@id": "as:proxyUrl",
"@type": "@id"
},
"liked": {
"@id": "as:liked",
"@type": "@id"
},
"oauthAuthorizationEndpoint": {
"@id": "as:oauthAuthorizationEndpoint",
"@type": "@id"
},
"oauthTokenEndpoint": {
"@id": "as:oauthTokenEndpoint",
"@type": "@id"
},
"provideClientKey": {
"@id": "as:provideClientKey",
"@type": "@id"
},
"signClientKey": {
"@id": "as:signClientKey",
"@type": "@id"
},
"sharedInbox": {
"@id": "as:sharedInbox",
"@type": "@id"
},
"Public": {
"@id": "as:Public",
"@type": "@id"
},
"source": "as:source",
"likes": {
"@id": "as:likes",
"@type": "@id"
},
"shares": {
"@id": "as:shares",
"@type": "@id"
},
"alsoKnownAs": {
"@id": "as:alsoKnownAs",
"@type": "@id"
}
}
}