# Invention Tautology

```python
def private$instance$key():
	return:

def hash$(s):
	if is$string(s):
		return 'components/services/entropy/sha256'(s)

	if is$sequence(s):
		kwd = keywords$()
		r = []

		for x in s:
			r.append(kwd[x])

		return hash$(''.join(r))


ia = call.assets.Itham
db = ia.components.database.code.db$attach$memory(db.value) <- db:
	signature$db:
		signatures(table):
			- owner: string
			- contentId: string
			- signature: string

		masks(table):
			- owner: string
			- mask_name: string


# signing = ia.server.kernel.class.defClass \
# 	('signing', [], signing, db = db) <- signing:

def database$():
	return db


def sign$content(owner, contentId, content):
	sContentId = string(contentId)

	chk = hash$(['key', 'owner', 'contentId', 'content'], \
			key = private$instance$key(), \
			owner = owner, contentId = sContentId, \
			content = content)

	.db.signatures(owner, sContentId, chk).save()

	return mapping(contentId = sContentId, \
				   signature = chk)

def verify$signature(owner, contentId, chk):
	r = false
	for s in .db.signatures.query(mapping(owner = owner, contentId = contentId)):
		# if s.signature == chk:
		# 	return true

		r = s.signature == chk
		break

	return r


def signature$(s):
	return namespace \
		(contentId = s.contentId, \
		 signature = s.signature)

def known$signatures(owner):
	return sequence(map(signature$, .db.signatures \
		.query(mapping(owner = owner))))

def known$signatures$all():
	r = mapping()
	for s in .db.signatures.all():
		r.setdefault(s.owner, []) \
			.append(signature$(s))

	return r


def mask$(owner, mask$name):
	if is$not$none(unmask$(mask$name)):
		raise(value$error, 'Mask name already used')

	.db.masks(owner, mask$name).save()

def unmask$(mask$name):
	r = none
	for m in .db.masks.query(mapping(mask_name = mask$name)):
		r = m.owner
		break

	return r


def generate$contentId(owner):
	scatter$args('owner', ['n', '10'], ['tries', 1000])
	ns = mapping(n = integer(n))

	gen = action(run$python, code, ns) <- code:
		from string import ascii_letters
		from random import choice

		__return = ''.join(choice(ascii_letters) for x in range(n))

	contentId = none

	for x in range(tries):
		contentId = gen()
		s = none

		for s in .db.signatures.query(mapping(owner = owner, contentId = contentId)):
			break

		if is$none(s):
			break

	if is$not$none(contentId):
		return contentId

	raise(value$error, 'Max tries reached (%s)' % tries)


sign(view):
	context(trigger)::
		if request.method == 'POST':
			post = request.POST
			owner = request.user.securityContext(programmer)
			contentId = generate$contentId(owner)

			r = sign$content(owner, contentId, post['content'])
			return 'text/json/dumps'(r)

	template::
		<form method="POST">
			<input type="">
			<input type="file" name="content-file">
			<br /><input type="submit">
			</form>

mask(view):
	context(trigger)::
		if request.method == 'POST':
			owner = request.user.securityContext(programmer)
			mask$(owner, request.POST['mask$name'])

verify(view):
	context(trigger)::
		if is$deep$view(path):
			scatter(path, 'mask', 'contentId', 'signature')
		else:
			if request.method == 'POST':
				post = request.POST
			else:
				post = request.GET

			try: mask = ['mask']
			except key$error:
				owner = post['owner']
			else:
				# assert not 'owner' in request.POST
				owner = unmask$(mask)

			contentId = post['contentId']
			chk = post['signature']

		r = verify$signature(owner, contentId, chk)
		return 'text/json/dumps'(r == true)

	usage:
		function public$sign(mask$name, content)
		{
			$.post('mask', {mask$name}).then

			(() => $.post('sign', {content},
			  function (chk)
			  { $.get(`verify/${mask$name}/${chk.contentId}/{chk.signature}`,
			    (isVerified) => console.log(`Verified: ${isVerified}`)); }));
		}


# {'contentId': 'qYbrkqWHOo', 'signature': 'f9a2b612f3ddddbfb1672ee57ca3364ce56e61c6db2921dec6e7d6a7ca75149b'}
# cmr: jul17th2023-1 fa2312470c69f63eefac7bd86cf6642cb01f70e7a783ce17bc312cbc2ed7310c
```
