kopia lustrzana https://gitlab.com/marnanel/chapeau
Porównaj commity
3 Commity
6b5e47807e
...
963a8b2234
Autor | SHA1 | Data |
---|---|---|
Marnanel Thurman | 963a8b2234 | |
Marnanel Thurman | 7f675c7b00 | |
Marnanel Thurman | 6817216d52 |
|
@ -1,12 +1,16 @@
|
||||||
from kepi.daemon import Daemon
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
import kepi.validate
|
||||||
|
|
||||||
logger = logging.getLogger('kepi')
|
logger = logging.getLogger('kepi')
|
||||||
|
logging.basicConfig(
|
||||||
|
level = logging.INFO,
|
||||||
|
stream = sys.stdout,
|
||||||
|
)
|
||||||
|
|
||||||
def daemonise(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
def daemonise(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
||||||
|
|
||||||
|
@ -36,47 +40,48 @@ def daemonise(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
||||||
|
|
||||||
logger.info("Running at PID %s", os.getpid())
|
logger.info("Running at PID %s", os.getpid())
|
||||||
|
|
||||||
def get_config():
|
def load_message(name):
|
||||||
|
if name=='-':
|
||||||
|
f = sys.stdin
|
||||||
|
else:
|
||||||
|
f = open(name, 'r')
|
||||||
|
|
||||||
|
result = json.load(f)
|
||||||
|
|
||||||
|
if f!=sys.stdin:
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='send or receive ActivityPub messages')
|
description='send or receive ActivityPub messages')
|
||||||
parser.add_argument(
|
|
||||||
'--incoming', '-I', action='store_true',
|
|
||||||
help='read an incoming message (rather than a message to send)')
|
|
||||||
parser.add_argument(
|
|
||||||
'--fifo', '-F', default='/var/run/kepi/kepi.fifo',
|
|
||||||
help='filename for control pipe')
|
|
||||||
parser.add_argument(
|
|
||||||
'--pidfile', '-P', default='/var/run/kepi/kepi.pid',
|
|
||||||
help='filename for process ID')
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--spool', '-S', default='/var/spool/kepi',
|
'--spool', '-S', default='/var/spool/kepi',
|
||||||
help='directory to store the messages')
|
help='directory to store the messages')
|
||||||
parser.add_argument(
|
|
||||||
|
subparsers = parser.add_subparsers(
|
||||||
|
dest = 'command',
|
||||||
|
required = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
validate_parser = subparsers.add_parser('validate')
|
||||||
|
|
||||||
|
validate_parser.add_argument(
|
||||||
'input',
|
'input',
|
||||||
help=(
|
help=(
|
||||||
'the file to read ("-" for stdin)'
|
'the file to read ("-" for stdin)'
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.input=='-':
|
if args.command=='validate':
|
||||||
f = sys.stdin
|
message = load_message(args.input)
|
||||||
|
kepi.validate.validate(message)
|
||||||
else:
|
else:
|
||||||
f = open(args.input, 'r')
|
raise NotImplementedError()
|
||||||
|
|
||||||
result = dict(args._get_kwargs())
|
|
||||||
result['message'] = json.load(f)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def main():
|
|
||||||
config = get_config()
|
|
||||||
|
|
||||||
daemon = Daemon(
|
|
||||||
config = config,
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info("Process ended normally.")
|
|
||||||
|
|
||||||
if __name__=='__main__':
|
if __name__=='__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import json
|
||||||
|
import copy
|
||||||
|
|
||||||
|
JSON_EXT = '.json'
|
||||||
|
TEMP_EXT = '.1'
|
||||||
|
|
||||||
|
PRIVATE_KEY_FIELD = 'private-key'
|
||||||
|
|
||||||
|
class User:
|
||||||
|
def __init__(self,
|
||||||
|
filename):
|
||||||
|
self.filename = filename
|
||||||
|
self.details = None
|
||||||
|
self.private_key = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return os.path.splitext(os.path.basename(self.filename))[0]
|
||||||
|
|
||||||
|
def _load_details(self):
|
||||||
|
if self.details is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(self.filename, 'r') as f:
|
||||||
|
self.details = json.load(f)
|
||||||
|
|
||||||
|
def _save_details(self):
|
||||||
|
if self.details is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(self.filename+TEMP_EXT, 'w') as f:
|
||||||
|
json.dump(self.details, f)
|
||||||
|
|
||||||
|
os.path.move(
|
||||||
|
self.filename+TEMP_EXT,
|
||||||
|
self.filename,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __getitem__(self, name):
|
||||||
|
|
||||||
|
if name==PRIVATE_KEY_FIELD:
|
||||||
|
if self.private_key is None:
|
||||||
|
|
||||||
|
username = os.path.splitext(
|
||||||
|
os.path.basename(self.filename))[1]
|
||||||
|
|
||||||
|
with open(os.path.join(
|
||||||
|
os.path.basename(self.filename),
|
||||||
|
'private',
|
||||||
|
'username',
|
||||||
|
), 'r') as f:
|
||||||
|
self.private_key = f.read()
|
||||||
|
|
||||||
|
return self.private_key
|
||||||
|
|
||||||
|
self._load_details()
|
||||||
|
return self.details[name]
|
||||||
|
|
||||||
|
def __setitem__(self, name, value):
|
||||||
|
|
||||||
|
if name==PRIVATE_KEY_FIELD:
|
||||||
|
raise KeyError(f"You can't set {PRIVATE_KEY_FIELD}")
|
||||||
|
|
||||||
|
self._load_details()
|
||||||
|
self.details[name] = value
|
||||||
|
self._save_details()
|
||||||
|
|
||||||
|
def as_dict(self):
|
||||||
|
self._load_details()
|
||||||
|
|
||||||
|
result = copy.copy(self.details)
|
||||||
|
return result
|
||||||
|
|
||||||
|
class Users:
|
||||||
|
def __init__(self,
|
||||||
|
users_dir,
|
||||||
|
):
|
||||||
|
self.users_dir = users_dir
|
||||||
|
|
||||||
|
def __getitem__(self, name):
|
||||||
|
|
||||||
|
if '/' in name or '\\' in name:
|
||||||
|
raise ValueError("Forbidden characters in name.")
|
||||||
|
|
||||||
|
filename = os.path.join(
|
||||||
|
self.users_dir,
|
||||||
|
name,
|
||||||
|
) + JSON_EXT
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.stat(filename)
|
||||||
|
except FileNotFoundError:
|
||||||
|
raise KeyError()
|
||||||
|
|
||||||
|
return User(filename)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
for someone in glob.glob(os.path.join(
|
||||||
|
self.users_dir,
|
||||||
|
'*'+JSON_EXT,
|
||||||
|
)):
|
||||||
|
name = os.path.splitext(
|
||||||
|
os.path.basename(someone)
|
||||||
|
)[0]
|
||||||
|
yield self[name]
|
|
@ -16,6 +16,10 @@ def validate(
|
||||||
Validates a message.
|
Validates a message.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
message = dict([
|
||||||
|
(k.lower(),v) for k,v in message.items()
|
||||||
|
])
|
||||||
|
|
||||||
if 'body' not in message:
|
if 'body' not in message:
|
||||||
raise ValueError("message must contain a body")
|
raise ValueError("message must contain a body")
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
These are public/private key pairs used in testing.
|
|
@ -0,0 +1,48 @@
|
||||||
|
{"@context":["https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://w3id.org/security/v1",
|
||||||
|
{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers",
|
||||||
|
"sensitive":"as:sensitive",
|
||||||
|
"movedTo":{"@id":"as:movedTo",
|
||||||
|
"@type":"@id"},
|
||||||
|
"alsoKnownAs":{"@id":"as:alsoKnownAs",
|
||||||
|
"@type":"@id"},
|
||||||
|
"Hashtag":"as:Hashtag",
|
||||||
|
"ostatus":"http://ostatus.org#",
|
||||||
|
"atomUri":"ostatus:atomUri",
|
||||||
|
"inReplyToAtomUri":"ostatus:inReplyToAtomUri",
|
||||||
|
"conversation":"ostatus:conversation",
|
||||||
|
"toot":"http://joinmastodon.org/ns#",
|
||||||
|
"Emoji":"toot:Emoji",
|
||||||
|
"focalPoint":{"@container":"@list",
|
||||||
|
"@id":"toot:focalPoint"},
|
||||||
|
"featured":{"@id":"toot:featured",
|
||||||
|
"@type":"@id"},
|
||||||
|
"schema":"http://schema.org#",
|
||||||
|
"PropertyValue":"schema:PropertyValue",
|
||||||
|
"value":"schema:value"}],
|
||||||
|
"id":"https://local.example.org/users/fred",
|
||||||
|
"type":"Person",
|
||||||
|
"following":"https://local.example.org/users/fred/following",
|
||||||
|
"followers":"https://local.example.org/users/fred/followers",
|
||||||
|
"inbox":"https://local.example.org/users/fred/inbox",
|
||||||
|
"outbox":"https://local.example.org/users/fred/outbox",
|
||||||
|
"featured":"https://local.example.org/users/fred/collections/featured",
|
||||||
|
"preferredUsername":"fred",
|
||||||
|
"name":"",
|
||||||
|
"summary":"I am not a basset hound.",
|
||||||
|
"url":"https://local.example.org/@fred",
|
||||||
|
"manuallyApprovesFollowers":false,
|
||||||
|
"publicKey":{"id":"https://local.example.org/users/fred#main-key",
|
||||||
|
"owner":"https://local.example.org/users/fred",
|
||||||
|
"publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJtAZt9hgB/7bNozWtv9Er+Pnf\num97oM8cxRlqRqUXZk0wuST9A0eY5EUsN8j3qc6msZjDPSDQELr/U/o+zJLp/B8s\n7x3iHAHGD4LcQ9AbyDqbhX9JZkmwGx6PIVmbMDANmppqLik36V7cov6BuHz1gFpD\nP+iPjem4mph/KLwugQIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||||
|
},
|
||||||
|
"tag":[],
|
||||||
|
"attachment":[],
|
||||||
|
"endpoints":{"sharedInbox":"https://local.example.org/inbox"},
|
||||||
|
"icon":{"type":"Image",
|
||||||
|
"mediaType":"image/png",
|
||||||
|
"url":"https://body.local.example.org/media/accounts/avatars/000/015/322/original/data.png"},
|
||||||
|
"image":{"type":"Image",
|
||||||
|
"mediaType":"image/png",
|
||||||
|
"url":"https://body.local.example.org/media/accounts/headers/000/015/322/original/data.png"}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
{"@context":["https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://w3id.org/security/v1",
|
||||||
|
{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers",
|
||||||
|
"sensitive":"as:sensitive",
|
||||||
|
"movedTo":{"@id":"as:movedTo",
|
||||||
|
"@type":"@id"},
|
||||||
|
"alsoKnownAs":{"@id":"as:alsoKnownAs",
|
||||||
|
"@type":"@id"},
|
||||||
|
"Hashtag":"as:Hashtag",
|
||||||
|
"ostatus":"http://ostatus.org#",
|
||||||
|
"atomUri":"ostatus:atomUri",
|
||||||
|
"inReplyToAtomUri":"ostatus:inReplyToAtomUri",
|
||||||
|
"conversation":"ostatus:conversation",
|
||||||
|
"toot":"http://joinmastodon.org/ns#",
|
||||||
|
"Emoji":"toot:Emoji",
|
||||||
|
"focalPoint":{"@container":"@list",
|
||||||
|
"@id":"toot:focalPoint"},
|
||||||
|
"featured":{"@id":"toot:featured",
|
||||||
|
"@type":"@id"},
|
||||||
|
"schema":"http://schema.org#",
|
||||||
|
"PropertyValue":"schema:PropertyValue",
|
||||||
|
"value":"schema:value"}],
|
||||||
|
"id":"https://local.example.org/users/jim",
|
||||||
|
"type":"Person",
|
||||||
|
"following":"https://local.example.org/users/jim/following",
|
||||||
|
"followers":"https://local.example.org/users/jim/followers",
|
||||||
|
"inbox":"https://local.example.org/users/jim/inbox",
|
||||||
|
"outbox":"https://local.example.org/users/jim/outbox",
|
||||||
|
"featured":"https://local.example.org/users/jim/collections/featured",
|
||||||
|
"preferredUsername":"jim",
|
||||||
|
"name":"",
|
||||||
|
"summary":"His friends were very good to him.",
|
||||||
|
"url":"https://local.example.org/@jim",
|
||||||
|
"manuallyApprovesFollowers":false,
|
||||||
|
"publicKey":{"id":"https://local.example.org/users/jim#main-key",
|
||||||
|
"owner":"https://local.example.org/users/jim",
|
||||||
|
"publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPPJ6uNXzpocC9Z1rue3sgZl/W\nnYHjbtkfQCUpdV9lgmtbOgpZrQos5sIB5QxUx+yRAXmdSRsD2q1Kaeeew5T+pv3h\nJKH4XMNZd2mZf1KAuHjPFBjCRGMUwdEEozSy8ZpDAg+jQ2ro8E7wgZ+wsYatSLbQ\n9SIkceGWqxyhabyIqwIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||||
|
},
|
||||||
|
"tag":[],
|
||||||
|
"attachment":[],
|
||||||
|
"endpoints":{"sharedInbox":"https://local.example.org/inbox"},
|
||||||
|
"icon":{"type":"Image",
|
||||||
|
"mediaType":"image/png",
|
||||||
|
"url":"https://body.local.example.org/media/accounts/avatars/000/015/322/original/data.png"},
|
||||||
|
"image":{"type":"Image",
|
||||||
|
"mediaType":"image/png",
|
||||||
|
"url":"https://body.local.example.org/media/accounts/headers/000/015/322/original/data.png"}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICXwIBAAKBgQDJtAZt9hgB/7bNozWtv9Er+Pnfum97oM8cxRlqRqUXZk0wuST9
|
||||||
|
A0eY5EUsN8j3qc6msZjDPSDQELr/U/o+zJLp/B8s7x3iHAHGD4LcQ9AbyDqbhX9J
|
||||||
|
ZkmwGx6PIVmbMDANmppqLik36V7cov6BuHz1gFpDP+iPjem4mph/KLwugQIDAQAB
|
||||||
|
AoGBAI6sRaQAYCkBzTeWC8E0HmwhN/Z2NKdZL0clb/3JrLtphI5DWBOT/0/5n6hQ
|
||||||
|
aVouBdvJYcowcgZa3zr+FtPW9s9EKswd4M6VEg7Kb7yvd7iD+6Hl/KY5YkpRutJF
|
||||||
|
ZVBt20iJi3xi+5D0BvMImD3nE/Zl2MgAJWIBlRywfDOuKS7BAkEA4hIoq0RAbSgf
|
||||||
|
VBzzWucpZa4o2Ll35tG9X5zQSmEjWuuIxipsiwcuyHURTEG+45TU/AasyDTvqqm6
|
||||||
|
HhG4Z9SpaQJBAORoAzTfuF6Z7I3THSDLQjqWiE10K0qSkrcPf7fMlTdzheQdhS5T
|
||||||
|
A4liwuAkpoRKxpvBw+OvCkgaqr34+Oqo4VkCQQC19kPBxofM1HSS8VJ3IoTRkOLT
|
||||||
|
vkTiBoPUx5VnqNQaRGasik0fgkKHmqK3rFuHNq5PxNehteoKhd6GgWDaQfOxAkEA
|
||||||
|
1KV9rsFGrlSR5qyRJtH11AQH3Ex2bZQuod39I0qF9b1I/0r4jltdJJBdLD8TBIF1
|
||||||
|
jNeGH7j8Uor5QarFW/tk6QJBAMEYab7c1YTagny4nrKoddPfNyjUF2a7HNHTnCQn
|
||||||
|
rbOt963SPr1/dv602FwOzKHAWVw401PfaHWkclEROZTwwEc=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,15 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICXgIBAAKBgQDPPJ6uNXzpocC9Z1rue3sgZl/WnYHjbtkfQCUpdV9lgmtbOgpZ
|
||||||
|
rQos5sIB5QxUx+yRAXmdSRsD2q1Kaeeew5T+pv3hJKH4XMNZd2mZf1KAuHjPFBjC
|
||||||
|
RGMUwdEEozSy8ZpDAg+jQ2ro8E7wgZ+wsYatSLbQ9SIkceGWqxyhabyIqwIDAQAB
|
||||||
|
AoGBAMMfZqDMh+JKhHlROVLWPOYSviYKg2Oq2RANi2/vrXScSYzJpzksLip80yqJ
|
||||||
|
iQTCgME/TEyFqsQEP6mS8ZyQtlUjoz8j6q/9TFvQrWWHRNgiD9bdXFQr0+F9kxr9
|
||||||
|
hdm1h7F5Q0JTGCPwBmL8GXCO8KmbZUMejITNqsIxx3bvzUoRAkEA1Eul1Mwkb/6C
|
||||||
|
cBuG0TPfXwluWdzS37XY+ckuQqgA5Jhj+vQTWbGovA/99W5GHHWsHJwGwcqqJJet
|
||||||
|
c4slKN3GBwJBAPnmXpAO1NiQMlIVohTfjCusypsSiHJXocigJG/DeEuMIHUJebuH
|
||||||
|
r6M7D2ENk7xh/kr3qA6369WokYT+K5Bqnz0CQQDPvApUVUIeeNwoWTcuBOVBeNgL
|
||||||
|
hOKv16Cuo6bpwL3G8jt7OFSrAwZKqBdojvR6Ksc045RVEzw0PFuU4YaGG6UHAkBZ
|
||||||
|
Q9LvfnzFRuzSqWuWLSwyxawxrHMU9PyTX7DkQ1yLD+jgJZxYQmWY1xXtQx5Momxl
|
||||||
|
dwWPDF+vmGEysl/5XDy5AkEAwbbjj3YstPYPnBsAbI0XYHfXxu7aZ+bwPNtH48r3
|
||||||
|
3YPAqM+HO0i2ffHjMJCYfbttWiRJRFVHyp3QO/Wtww4DQQ==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,15 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICXAIBAAKBgQCsGqRZbZV2nljTOW2b77fzpkx9+iqcNgEnlhdgSIjCPvhzwj6c
|
||||||
|
b0O5RVqPu6krvv+Dgiy89Mb0nregdOstUXzn40Yicg1OOHMitrpAQ+4MsotqspfF
|
||||||
|
ZF/Q9qSFom3PxDA55lIHYJJmusVM6bSlrdY8msAsL1BieW7065gtjzv6RQIDAQAB
|
||||||
|
AoGACURx/yLIfpeuPsmD3na9GBCnY805yCmcTE5nudaODq+nX0xhZLkVE3/pjX3U
|
||||||
|
cTeauLEkyZQAtqFpT+mb1Ffj+t3exqK68k7UwCUI23Gtbr5dRUOivWuN75Sf4xFo
|
||||||
|
7vQeSwIot/1PyU7JYXZ9Tq9WMBHcFocCdxu85QSBS40cPIECQQC60bIlj+bN7fvU
|
||||||
|
HoPyQbj1vfjbz6vcoeR6v+YGCiSFrzawOEuJ1xUC7c/uivgJUvKumhrOFfwLac+1
|
||||||
|
Zay2t7khAkEA69X4ft06mfVNo1oM8ly33CO5TKlpFlVPBxEdKMHyZ2ZO1vIK6DsF
|
||||||
|
N67YwYI9OoncTvBucZ+Dy2GU0xUeqtSopQJANhtnsjNUUI49onjYFEDutdW4jsk9
|
||||||
|
6F/HEbokf9lOLJ3LhAw57Ikrn7aKw3biUakBeopNeySo5BFYRBxXgnABoQJBANlf
|
||||||
|
MVoNo1QAy/zCpahGWZlovASzKY9SNjM3TP8iNMGlhQmNswv2SorWeCd0Wec45n1E
|
||||||
|
EyhbdOjjGn+sucWPmZkCQD8ekBtzToRvNZjocFJhZdcWMIAo96XsnTAxREKSmbnG
|
||||||
|
pFHXBWokjDO/rTRbqANocLr0GwFR8UBD70CJLLOCaEg=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,47 @@
|
||||||
|
{"@context":["https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://w3id.org/security/v1",
|
||||||
|
{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers",
|
||||||
|
"sensitive":"as:sensitive",
|
||||||
|
"movedTo":{"@id":"as:movedTo",
|
||||||
|
"@type":"@id"},
|
||||||
|
"alsoKnownAs":{"@id":"as:alsoKnownAs",
|
||||||
|
"@type":"@id"},
|
||||||
|
"Hashtag":"as:Hashtag",
|
||||||
|
"ostatus":"http://ostatus.org#",
|
||||||
|
"atomUri":"ostatus:atomUri",
|
||||||
|
"inReplyToAtomUri":"ostatus:inReplyToAtomUri",
|
||||||
|
"conversation":"ostatus:conversation",
|
||||||
|
"toot":"http://joinmastodon.org/ns#",
|
||||||
|
"Emoji":"toot:Emoji",
|
||||||
|
"focalPoint":{"@container":"@list",
|
||||||
|
"@id":"toot:focalPoint"},
|
||||||
|
"featured":{"@id":"toot:featured",
|
||||||
|
"@type":"@id"},
|
||||||
|
"schema":"http://schema.org#",
|
||||||
|
"PropertyValue":"schema:PropertyValue",
|
||||||
|
"value":"schema:value"}],
|
||||||
|
"id":"https://local.example.org/users/sheila",
|
||||||
|
"type":"Person",
|
||||||
|
"following":"https://local.example.org/users/sheila/following",
|
||||||
|
"followers":"https://local.example.org/users/sheila/followers",
|
||||||
|
"inbox":"https://local.example.org/users/sheila/inbox",
|
||||||
|
"outbox":"https://local.example.org/users/sheila/outbox",
|
||||||
|
"featured":"https://local.example.org/users/sheila/collections/featured",
|
||||||
|
"preferredUsername":"sheila",
|
||||||
|
"name":"",
|
||||||
|
"summary":"What do you think?",
|
||||||
|
"url":"https://local.example.org/@sheila",
|
||||||
|
"manuallyApprovesFollowers":false,
|
||||||
|
"publicKey":{"id":"https://local.example.org/users/sheila#main-key",
|
||||||
|
"owner":"https://local.example.org/users/sheila",
|
||||||
|
"publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsGqRZbZV2nljTOW2b77fzpkx9\n+iqcNgEnlhdgSIjCPvhzwj6cb0O5RVqPu6krvv+Dgiy89Mb0nregdOstUXzn40Yi\ncg1OOHMitrpAQ+4MsotqspfFZF/Q9qSFom3PxDA55lIHYJJmusVM6bSlrdY8msAs\nL1BieW7065gtjzv6RQIDAQAB\n-----END PUBLIC KEY-----\n"},
|
||||||
|
"tag":[],
|
||||||
|
"attachment":[],
|
||||||
|
"endpoints":{"sharedInbox":"https://local.example.org/inbox"},
|
||||||
|
"icon":{"type":"Image",
|
||||||
|
"mediaType":"image/png",
|
||||||
|
"url":"https://body.local.example.org/media/accounts/avatars/000/015/322/original/data.png"},
|
||||||
|
"image":{"type":"Image",
|
||||||
|
"mediaType":"image/png",
|
||||||
|
"url":"https://body.local.example.org/media/accounts/headers/000/015/322/original/data.png"}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
import os
|
||||||
|
from test import *
|
||||||
|
from kepi.users import Users
|
||||||
|
|
||||||
|
USERS_DIR = os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
"example-users",
|
||||||
|
)
|
||||||
|
|
||||||
|
FRED_OUTBOX = 'https://local.example.org/users/fred/outbox'
|
||||||
|
|
||||||
|
def test_users_simple():
|
||||||
|
u = Users(users_dir = USERS_DIR)
|
||||||
|
|
||||||
|
fred = u['fred']
|
||||||
|
assert fred['summary']=='I am not a basset hound.'
|
||||||
|
|
||||||
|
def test_users_dir():
|
||||||
|
u = Users(users_dir = USERS_DIR)
|
||||||
|
|
||||||
|
assert sorted([user.name for user in u])==['fred', 'jim', 'sheila']
|
||||||
|
|
||||||
|
def test_users_dict():
|
||||||
|
u = Users(users_dir = USERS_DIR)
|
||||||
|
fred = u['fred']
|
||||||
|
|
||||||
|
assert fred['outbox'] == FRED_OUTBOX
|
||||||
|
|
||||||
|
fred_dict = fred.as_dict()
|
||||||
|
assert not isinstance(fred, dict)
|
||||||
|
assert isinstance(fred_dict, dict)
|
||||||
|
|
||||||
|
assert fred_dict['outbox'] == FRED_OUTBOX
|
Ładowanie…
Reference in New Issue