From 247eb2dde7a20fe23ecf170e347de2780be5b6e4 Mon Sep 17 00:00:00 2001
From: John-Mark Gurney <jmg@funkthat.com>
Date: Thu, 5 Sep 2019 17:49:51 -0700
Subject: [PATCH] add Persona and various tests for it..

---
 ui/Makefile                |  4 +--
 ui/cli.py                  | 66 ++++++++++++++++++++++++++++++++++++--
 ui/fixtures/genfixtures.py |  4 ++-
 3 files changed, 69 insertions(+), 5 deletions(-)

diff --git a/ui/Makefile b/ui/Makefile
index 5da86c0..88e411c 100644
--- a/ui/Makefile
+++ b/ui/Makefile
@@ -1,6 +1,6 @@
 MODULES=cli.py kleintest.py mtree.py server.py
 
-test: fixtures/sample.data.pasn1 fixtures/sample.mtree
+test: fixtures/sample.data.pasn1 fixtures/sample.persona.pasn1 fixtures/sample.mtree
 	(. ./p/bin/activate && \
 		(ls $(MODULES) | entr sh -c 'python -m coverage run -m unittest $(basename $(MODULES)) && coverage report -m --omit=p/\*'))
 
@@ -9,7 +9,7 @@ env:
 	(. ./p/bin/activate && \
 		pip install -r requirements.txt)
 
-fixtures/sample.data.pasn1: fixtures/genfixtures.py
+fixtures/sample.data.pasn1 fixtures/sample.persona.pasn1: fixtures/genfixtures.py
 	(. ./p/bin/activate && cd fixtures && PYTHONPATH=.. python genfixtures.py )
 
 fixtures/sample.mtree: fixtures/mtree.dir
diff --git a/ui/cli.py b/ui/cli.py
index 708cfc3..ff96630 100644
--- a/ui/cli.py
+++ b/ui/cli.py
@@ -48,7 +48,7 @@ class MDBase(object):
 	_common_optional = [ 'overlay_refs' ]
 	_common_names = set(_common_properties + _generated_properties.keys())
 
-	def __init__(self, obj):
+	def __init__(self, obj={}):
 		obj = copy.deepcopy(obj)
 		if 'type' not in obj:
 			obj['type'] = self._type
@@ -117,6 +117,13 @@ class MDBase(object):
 class MetaData(MDBase):
 	_type = 'metadata'
 
+class Identity(MDBase):
+	_type = 'identity'
+
+	# Identites don't need a created by
+	_common_properties = [ x for x in MDBase._common_properties if x != 'created_by_ref' ]
+	_common_optional = [ 'name', 'pubkey' ]
+
 def _trytodict(o):
 	if isinstance(o, uuid.UUID):
 		return 'unicode', str(o)
@@ -127,6 +134,45 @@ def _trytodict(o):
 
 _asn1coder = pasn1.ASN1DictCoder(coerce=_trytodict)
 
+class Persona(object):
+	'''The object that represents a persona, or identity.  It will
+	create the proper identity object, serialize for saving keys,
+	create objects for that persona and other management.'''
+
+	def __init__(self, identity=None):
+		if identity is None:
+			self._identity = Identity()
+		else:
+			self._identity = identity
+
+		self._created_by_ref = self._identity.uuid
+
+	def get_identity(self):
+		return self._identity
+
+	def store(self, fname):
+		with open(fname, 'w') as fp:
+			obj = {
+				'identity': self._identity,
+			}
+			fp.write(_asn1coder.dumps(obj))
+
+	@classmethod
+	def load(cls, fname):
+		with open(fname) as fp:
+			objs = _asn1coder.loads(fp.read())
+
+		return cls(Identity(objs['identity']))
+
+	def by_file(self, fname):
+		'''Return a metadata object for the file named fname.'''
+
+		fid = FileObject.make_id(fname)
+
+		fobj = FileObject.from_file(fname, self._created_by_ref)
+
+		return fobj
+
 class ObjectStore(object):
 	'''A container to store for the various Metadata objects.'''
 
@@ -343,12 +389,14 @@ if __name__ == '__main__':	# pragma: no cover
 	main()
 
 class _TestCases(unittest.TestCase):
-	created_by_ref = '867c7563-79ae-435c-a265-9d8509cefac5'
 	def setUp(self):
 		d = os.path.realpath(tempfile.mkdtemp())
 		self.basetempdir = d
 		self.tempdir = os.path.join(d, 'subdir')
 
+		persona = Persona.load(os.path.join('fixtures', 'sample.persona.pasn1'))
+		self.created_by_ref = persona.get_identity().uuid
+
 		shutil.copytree(os.path.join('fixtures', 'testfiles'),
 		   self.tempdir)
 
@@ -458,6 +506,20 @@ class _TestCases(unittest.TestCase):
 		# that is has the overlays property
 		self.assertEqual(odict['overlay_refs'], [ bid ])
 
+	def test_persona(self):
+		# that a newly created persona
+		persona = Persona()
+
+		# has an identity object
+		idobj = persona.get_identity()
+
+		# that a file object created by it
+		testfname = os.path.join(self.tempdir, 'test.txt')
+		testobj = persona.by_file(testfname)
+
+		# has the correct created_by_ref
+		self.assertEqual(testobj.created_by_ref, idobj.uuid)
+
 	def test_objectstore(self):
 		objst = ObjectStore.load(os.path.join('fixtures', 'sample.data.pasn1'))
 
diff --git a/ui/fixtures/genfixtures.py b/ui/fixtures/genfixtures.py
index fba0fec..004957a 100644
--- a/ui/fixtures/genfixtures.py
+++ b/ui/fixtures/genfixtures.py
@@ -2,7 +2,8 @@ import pasn1
 import cli
 import datetime
 
-cbr = '867c7563-79ae-435c-a265-9d8509cefac5'
+persona = cli.Persona()
+cbr = persona.get_identity().uuid
 objst = cli.ObjectStore(cbr)
 map(objst.loadobj,
 	[
@@ -19,3 +20,4 @@ map(objst.loadobj,
 )
 
 objst.store('sample.data.pasn1')
+persona.store('sample.persona.pasn1')