Exemplo n.º 1
0
	def get_credential(self, credential_id, mode) :
		""" get a credential as a json_ld
		"""
		credential = Claim()
		credential.get_by_topic_name(mode.relay_workspace_contract, None, self.workspace_contract, credential_id, mode)
		print(credential.__dict__)
		return json.dumps(credential.claim_value, ensure_ascii=False)
Exemplo n.º 2
0
	def store_credential(self, signed_credential, mode) :
		""" store credential encrypted to the repository
		signed_credential is json or dict
		return document_id
		"""
		if not isinstance(signed_credential, dict) :
			signed_credential = json.loads(signed_credential)
		credential = Claim()
		return credential.relay_add(self.workspace_contract, signed_credential['id'], signed_credential, 'private', mode)
Exemplo n.º 3
0
	def publish_credential(self, signed_credential, mode) :
		""" add credential to the repository
		signed_credential is json or dict
		return link to display the credential
		"""
		if not isinstance(signed_credential, dict) :
			signed_credential = json.loads(signed_credential)
		credential = Claim()
		credential_id = credential.relay_add(self.workspace_contract, signed_credential['id'], signed_credential, 'public', mode)
		if credential_id :
			return 'https://talao.co/certificate/?certificate_id=' + self.did + ':claim:' + credential_id
		else :
			return None
Exemplo n.º 4
0
def show_certificate(mode):
	"""
	# display experience certificate for anybody. Stand alone routine
	# #route /guest/certificate
	# @route /certificate/
	"""
	menu = session.get('menu', dict())
	viewer = 'guest' if not session.get('username') else 'user'

	try  :
		certificate_id = request.args['certificate_id']
		method = certificate_id.split(':')[1]

		# translator for repository claim
		if method in ['web', 'tz', 'ethr'] :
			did = 'did:' + method + ':' + certificate_id.split(':')[2]
			private_key = '0x' + PBKDF2(did.encode(), SALT, 32, count=1000000, hmac_hash_module=SHA512).hex()
			address = helpers.ethereum_pvk_to_address(private_key)
			workspace_contract = ownersToContracts(address, mode)
			claim_id = certificate_id.split(':')[4]
			credential = Claim()
			credential.get_by_id( mode.relay_workspace_contract, None, workspace_contract, claim_id, mode)
			return jsonify(credential.claim_value)

		# standard
		elif method == 'talao' :
			try :
				doc_id = int(certificate_id.split(':')[5])
				identity_workspace_contract = '0x'+ certificate_id.split(':')[3]
			except :
				content = json.dumps({'message' : 'request malformed'})
				return Response(content, status=406, mimetype='application/json')
		else :
			content = json.dumps({'message' : 'method not supported'})
			return Response(content, status=406, mimetype='application/json')

	except :
		content = json.dumps({'message' : 'request malformed'})
		return Response(content, status=406, mimetype='application/json')

	try :
		self_claim = certificate_id.split(':')[6]
	except:
		self_claim = None

	if session.get('certificate_id') != request.args['certificate_id'] :
		certificate = Document('certificate')
		if not certificate.relay_get(identity_workspace_contract, doc_id, mode) :
			content = json.dumps({'message' : 'This credential does not exist or it has been deleted'})
			return Response(content, status=406, mimetype='application/json')
		if certificate.privacy != 'public' :
			content = json.dumps({'message' : 'This credential is private'})
			return Response(content, status=406, mimetype='application/json')
		session['displayed_certificate'] = certificate.__dict__

	if self_claim == "experience" :
		description = session['displayed_certificate']['description'].replace('\r\n','<br>')

		my_badge = ''
		for skill in session['displayed_certificate']['skills'] :
			skill_to_display = skill.replace(" ", "").capitalize().strip(',')
			my_badge +=  """<span class="badge badge-pill badge-secondary" style="margin: 4px; padding: 8px;"> """+ skill_to_display + """</span>"""
		return render_template('./certificate/self_claim.html',
							**menu,
							type = 'Experience',
							certificate_id= certificate_id,
							company = session['displayed_certificate']['company']['name'],
							email = session['displayed_certificate']['company']['contact_email'],
							tel = session['displayed_certificate']['company']['contact_phone'],
							contact_name = session['displayed_certificate']['company']['contact_name'],
							start_date = session['displayed_certificate']['start_date'],
							end_date = session['displayed_certificate']['end_date'],
							description = description,
							badge = my_badge,
							viewer=viewer,
							title = session['displayed_certificate']['title'],
							)

	if self_claim == "skills" :
		description = ""
		print (session['displayed_certificate'])
		for skill in session['displayed_certificate']['description'] :
			description += skill["skill_name"] + " "
		return render_template('./certificate/self_claim.html',
							**menu,
							type = 'Skill',
							certificate_id= certificate_id,
							description = description,
							viewer=viewer,
							)

	if self_claim == "education" :
		description = session['displayed_certificate']['description'].replace('\r\n','<br>')

		my_badge = ''
		for skill in session['displayed_certificate']['skills'] :
			skill_to_display = skill.replace(" ", "").strip(',')
			if skill_to_display :
				my_badge = my_badge + """<span class="badge badge-pill badge-secondary" style="margin: 4px; padding: 8px;"> """+ skill_to_display.capitalize() + """</span>"""
		return render_template('./certificate/self_claim.html',
							**menu,
							type = 'Education',
							certificate_id= certificate_id,
							company = session['displayed_certificate']['organization']['name'],
							email = session['displayed_certificate']['organization']['contact_email'],
							tel = session['displayed_certificate']['organization']['contact_phone'],
							contact_name = session['displayed_certificate']['organization']['contact_name'],
							start_date = session['displayed_certificate']['start_date'],
							end_date = session['displayed_certificate']['end_date'],
							description = description,
							badge = my_badge,
							viewer=viewer,
							title = session['displayed_certificate']['title'],
							link = session['displayed_certificate']['certificate_link']
							)

	# Experience Credential Display
	if session['displayed_certificate']['credentialSubject']['credentialCategory'] == 'experience' :
		yellow_star = "color: rgb(251,211,5); font-size: 12px;" # yellow
		black_star = "color: rgb(0,0,0);font-size: 12px;" # black

		# Icon "fa-star" treatment
		score = []
		context = dict()
		score.append(int(session['displayed_certificate']['credentialSubject']['reviewRecommendation']['reviewRating']['ratingValue']))
		score.append(int(session['displayed_certificate']['credentialSubject']['reviewDelivery']['reviewRating']['ratingValue']))
		score.append(int(session['displayed_certificate']['credentialSubject']['reviewSchedule']['reviewRating']['ratingValue']))
		score.append(int(session['displayed_certificate']['credentialSubject']['reviewCommunication']['reviewRating']['ratingValue']))
		for q in range(0,4) :
			for i in range(0,score[q]) :
				context["star"+str(q)+str(i)] = yellow_star
			for i in range(score[q],5) :
				context ["star"+str(q)+str(i)] = black_star

		if session['displayed_certificate']['credentialSubject']['skills'] :
			skills = session['displayed_certificate']['credentialSubject']['skills']
			my_badge = ""
			for skill in skills :
				if skill['description'] :
					my_badge += """<span class="badge badge-pill badge-secondary" style="margin: 4px; padding: 8px;"> """+ skill['description'].strip(' ').capitalize() + """</span>"""
		else :
			my_badge = ""

		# if there is no signature one uses Picasso signature
		signature = session['displayed_certificate']['credentialSubject']['managerSignature']
		if not signature :
			signature = 'QmS9TTtjw1Fr5oHkbW8gcU7TnnmDvnFVUxYP9BF36kgV7u'

		# if there is no logo one uses default logo
		logo = session['displayed_certificate']['credentialSubject']['companyLogo']
		if not logo  :
			logo = 'QmXKeAgNZhLibNjYJFHCiXFvGhqsqNV2sJCggzGxnxyhJ5'

		# upload signature and logo on server
		if not path.exists(mode.uploads_path + signature) :
			url = 'https://gateway.pinata.cloud/ipfs/'+ signature
			response = requests.get(url, stream=True)
			with open(mode.uploads_path + signature, 'wb') as out_file:
				shutil.copyfileobj(response.raw, out_file)
			del response

		if not path.exists(mode.uploads_path + logo) :
			url = 'https://gateway.pinata.cloud/ipfs/'+ logo
			response = requests.get(url, stream=True)
			with open(mode.uploads_path + logo, 'wb') as out_file:
				shutil.copyfileobj(response.raw, out_file)
			del response

		return render_template('./certificate/experience_certificate.html',
							**menu,
							managerName=session['displayed_certificate']['credentialSubject']['managerName'],
							companyName=session['displayed_certificate']['credentialSubject']['companyName'],
							badge=my_badge,
							title = session['displayed_certificate']['credentialSubject']['title'],
							subject_name = session['displayed_certificate']['credentialSubject']['name'],
							description=session['displayed_certificate']['credentialSubject']['description'],
							start_date=session['displayed_certificate']['credentialSubject']['startDate'],
							end_date=session['displayed_certificate']['credentialSubject']['endDate'],
							signature=signature,
							logo=logo,
							certificate_id=certificate_id,
							viewer=viewer,
							**context)

	# Recommendation Certificate Display
	if session['displayed_certificate']['type'] == 'recommendation' :
		issuer_picture = session['displayed_certificate'].get('logo')
		if session['displayed_certificate']['issuer']['category'] == 1001 :
			issuer_picture = session['displayed_certificate'].get('picture')
		else :
			issuer_picture = session['displayed_certificate'].get('logo')

		issuer_title = "" if not session['displayed_certificate'].get('title')  else session['displayed_certificate']['title']
		if issuer_picture  :
			if not path.exists(mode.uploads_path + issuer_picture) :
				logging.info('picture already on disk')
				url='https://gateway.pinata.cloud/ipfs/'+ issuer_picture
				response = requests.get(url, stream=True)
				with open(mode.uploads_path + issuer_picture, 'wb') as out_file:
					shutil.copyfileobj(response.raw, out_file)
				del response

		description = """ " """ + session['displayed_certificate']['description'] + """ " """
		return render_template('./certificate/recommendation_certificate.html',
							**menu,
							#identity_firstname=identity_profil['firstname'],
							#identity_lastname=identity_profil['lastname'],
							description=description,
							issuer_picture=issuer_picture,
							issuer_title=issuer_title,
							issuer_firstname=session['displayed_certificate']['issuer']['firstname'] if session['displayed_certificate']['issuer']['category']== 1001 else "",
							issuer_lastname=session['displayed_certificate']['issuer']['lastname']if session['displayed_certificate']['issuer']['category']== 1001 else "",
							relationship=session['displayed_certificate']['relationship'],
							certificate_id=certificate_id,
							#identity_username=identity_username,
							#issuer_username=issuer_username,
							viewer=viewer
							)

	# Skill Certificate Display
	if session['displayed_certificate']['type'] == 'skill' :
		issuer_picture = session['displayed_certificate'].get('picture')
		issuer_title = "" if not session['displayed_certificate'].get('title') else session['displayed_certificate']['title']

		description = session['displayed_certificate']['description'].replace('\r\n','<br>')

		signature = session['displayed_certificate']['signature']
		logo = session['displayed_certificate']['logo']
		# if there is no signature one uses Picasso signature
		if not signature  :
			signature = 'QmS9TTtjw1Fr5oHkbW8gcU7TnnmDvnFVUxYP9BF36kgV7u'
		# if there is no logo one uses default logo
		if not logo  :
			logo = 'QmXKeAgNZhLibNjYJFHCiXFvGhqsqNV2sJCggzGxnxyhJ5'

		if not path.exists(mode.uploads_path + signature) :
				url = 'https://gateway.pinata.cloud/ipfs/'+ signature
				response = requests.get(url, stream=True)
				with open(mode.uploads_path + signature, 'wb') as out_file:
					shutil.copyfileobj(response.raw, out_file)
				del response

		if not path.exists(mode.uploads_path + logo) :
			url = 'https://gateway.pinata.cloud/ipfs/'+ logo
			response = requests.get(url, stream=True)
			with open(mode.uploads_path + logo, 'wb') as out_file:
				shutil.copyfileobj(response.raw, out_file)
			del response

		return render_template('./certificate/skill_certificate.html',
							**menu,
							manager= session['displayed_certificate']['manager'],
							#identity_firstname=identity_profil['firstname'],
							#identity_lastname=identity_profil['lastname'],
							#identity_name =identity_profil['firstname'] + ' ' + identity_profil['lastname'],
							description=description,
							issuer_picture=issuer_picture,
							signature=signature,
							logo=logo,
							certificate_id=certificate_id,
							title=session['displayed_certificate']['title'],
							#issuer_name=session['displayed_certificate']['issuer']['name'],
							viewer=viewer
							)
	# agreement certificate display
	if session['displayed_certificate']['type'] == 'agreement':
		description = session['displayed_certificate']['description'].replace('\r\n','<br>')

		signature = session['displayed_certificate']['issued_by'].get('signature')
		logo = session['displayed_certificate']['issued_by'].get('logo')

		# if there is no signature or no logo , view is reduced see html else we download file rom ipfs if needed
		if signature and logo :
			if not path.exists(mode.uploads_path + signature) :
				url = 'https://gateway.pinata.cloud/ipfs/'+ signature
				response = requests.get(url, stream=True)
				with open(mode.uploads_path + signature, 'wb') as out_file:
					shutil.copyfileobj(response.raw, out_file)
				del response

			if not path.exists(mode.uploads_path + logo) :
				url = 'https://gateway.pinata.cloud/ipfs/'+ logo
				response = requests.get(url, stream=True)
				with open(mode.uploads_path + logo, 'wb') as out_file:
					shutil.copyfileobj(response.raw, out_file)
				del response

		if session['displayed_certificate']['service_product_group'] :
			products = session['displayed_certificate']['service_product_group'].replace(' ', '').split(",")
			service_product_group = ""
			for product in products:
				service_product_group = service_product_group + """<li class="text-dark my-2 mx-5">""" + product.capitalize() + "</li>"
		else :
			service_product_group = None

		return render_template('./certificate/agreement_certificate.html',
							**menu,
							date_of_issue = session['displayed_certificate']['date_of_issue'],
							date_of_validity = session['displayed_certificate']['valid_until'],
							location = session['displayed_certificate']['location'],
							description=description,
							logo=logo,
							issued_to_name = session['displayed_certificate']['issued_to'].get('name', ''),
							issuer_name = session['displayed_certificate']['issued_by'].get('name',''),
							issuer_siret = session['displayed_certificate']['issued_by'].get('siret', ''),
							title = session['displayed_certificate']['title'],
							signature=signature,
							viewer=viewer,
							standard=session['displayed_certificate']['standard'],
							registration_number = session['displayed_certificate']['registration_number'],
							service_product_group = service_product_group,
							certificate_id=certificate_id,
							)

	# if reference credential display
	if session['displayed_certificate']['credentialSubject']['credentialCategory'] == 'reference' :
		yellow_star = "color: rgb(251,211,5); font-size: 12px;" # yellow
		black_star = "color: rgb(0,0,0);font-size: 12px;" # black

		description = session['displayed_certificate'].get('description','Unknown').replace('\r\n','<br>')

		signature = session['displayed_certificate']['credentialSubject']['managerSignature']
		logo = session['displayed_certificate']['credentialSubject']['companyLogo']

		if signature and logo :
			if not path.exists(mode.uploads_path + signature) :
				url = 'https://gateway.pinata.cloud/ipfs/'+ signature
				response = requests.get(url, stream=True)
				with open(mode.uploads_path + signature, 'wb') as out_file:
					shutil.copyfileobj(response.raw, out_file)
				del response

			if not path.exists(mode.uploads_path + logo) :
				url = 'https://gateway.pinata.cloud/ipfs/'+ logo
				response = requests.get(url, stream=True)
				with open(mode.uploads_path + logo, 'wb') as out_file:
					shutil.copyfileobj(response.raw, out_file)
				del response
		skills_str = ""
		try :
			for skill in session['displayed_certificate']['credentialSubject']['offers']['skills'] :
				skills_str += skill['description'] + ','
		except :
			logging.warning('skills not found')
		return render_template('./certificate/reference_certificate.html',
							**menu,
							issued_to_name = session['displayed_certificate']['credentialSubject']['name'],
							issuanceDate = session['displayed_certificate']['issuanceDate'][:10],
							startDate = session['displayed_certificate']['credentialSubject']['offers']['startDate'],
							endDate = session['displayed_certificate']['credentialSubject']['offers']['endDate'],
							price = session['displayed_certificate']['credentialSubject']['offers']['price'],
							currency = session['displayed_certificate']['credentialSubject']['offers']['priceCurrency'],
							description=session['displayed_certificate']['credentialSubject']['offers']['description'],
							review= session['displayed_certificate']['credentialSubject']['review']['reviewBody'],
							location=session['displayed_certificate']['credentialSubject']['offers']['location'],
							logo=logo,
							issuer_name = session['displayed_certificate']['credentialSubject']['companyName'],
							title = session['displayed_certificate']['credentialSubject']['offers']['title'],
							signature=signature,
							manager = session['displayed_certificate']['credentialSubject']['companyName'],
							certificate_id=certificate_id,
							viewer=viewer,
							skills=skills_str
							)

	else :
		# clean up to get a standard credential
		del session['displayed_certificate']['topic']
		del session['displayed_certificate']['doc_id']
		del session['displayed_certificate']['data_location']
		del session['displayed_certificate']['privacy']
		return jsonify(session['displayed_certificate'])
Exemplo n.º 5
0
	def create(self, did, mode, email=None, password=False, phone=None, wallet=None, category=1001) :
		""" Main function to create a repository for a user
		category is 1001 for person and 2001 for company
		DID is used to generate an ethereum private key
		email is used to recover in case of did keys are lost
		Talao smart contract is deployed on talaonet
		"""
		# Setup with DID as password, deterministic way to generate an address
		if not did :
			logging.error('did malformed')
			return False
		if did.split(':')[1] not in ['web', 'tz', 'ethr', 'key'] :
			logging.error('did not supported')
			return False
		repository = Repository()
		if repository.load(mode, did) :
			logging.error('A repository already exists for this DID')
			return False
		self.did = did
		self.email = email if email else ""
		if category not in [1001, 2001] :
			logging.error('wrong category')
			return False
		self.category = category
		self.private_key = '0x' + PBKDF2(self.did.encode(), SALT, 32, count=1000000, hmac_hash_module=SHA512).hex()
		self.address = helpers.ethereum_pvk_to_address(self.private_key)
		self.public_key = helpers.ethereum_pvk_to_pub(self.private_key)
		self.jwk = helpers.ethereum_to_jwk(self.private_key, 'ethr')

		# create RSA key
		RSA_key = RSA.generate(2048)
		self.RSA_private = RSA_key.exportKey('PEM')
		self.RSA_public =  RSA_key.publickey().exportKey('PEM')
		logging.info('RSA key generated')

		# Setup an AES key named 'private' to encrypt private data and to be shared with partnership
		private = get_random_bytes(16)
		self.private = private.hex()

		# Setup an AES key named 'secret' to encrypt secret data FIXME
		secret = get_random_bytes(16)
		self.secret = secret.hex()

		# AES private encrypted with RSA key
		cipher_rsa = PKCS1_OAEP.new(RSA_key)
		private_encrypted = cipher_rsa.encrypt(private)

		# AES secret encrypted with RSA key
		cipher_rsa = PKCS1_OAEP.new(RSA_key)
		secret_encrypted = cipher_rsa.encrypt(secret)

		try :
			# Ether transfer from TalaoGen wallet
			ether_transfer(self.address, mode.ether2transfer,mode)
			logging.info('ether transfer done ')
			# Talao tokens transfer from TalaoGen wallet
			token_transfer(self.address, mode.talao_to_transfer, mode)
			logging.info('token transfer done')
			# CreateVaultAccess call in the token to declare the identity within the Talao Token smart contract
			createVaultAccess(self.address, self.private_key, mode)
			logging.info('vault access created')
		except :
			logging.error('init Talao protocol failed')
			return False

		# Identity setup
		contract = mode.w3.eth.contract(mode.workspacefactory_contract,abi=constante.Workspace_Factory_ABI)
		nonce = mode.w3.eth.getTransactionCount(self.address)
		bemail = bytes(self.email.lower() , 'utf-8')
		txn = contract.functions.createWorkspace(self.category,
												1,
												1,
												self.RSA_public,
												private_encrypted,
												secret_encrypted,
												bemail).buildTransaction({'chainId': mode.CHAIN_ID,
																			'gas': 7500000,
																			'gasPrice': mode.w3.toWei(mode.GASPRICE, 'gwei'),
																			'nonce': nonce})
		signed_txn = mode.w3.eth.account.signTransaction(txn, self.private_key)
		mode.w3.eth.sendRawTransaction(signed_txn.rawTransaction)
		transaction_hash = mode.w3.toHex(mode.w3.keccak(signed_txn.rawTransaction))
		receipt = mode.w3.eth.waitForTransactionReceipt(transaction_hash, timeout=2000, poll_latency=1)
		if not receipt['status'] :
			logging.error('transaction to create repository failed')
			return False

		# workspace_contract address to be read in fondation smart contract
		self.workspace_contract = ownersToContracts(self.address, mode)
		logging.info('repository has been deployed')

		# store RSA key in file ./RSA_key/rinkeby, talaonet ou ethereum
		filename = "./RSA_key/" + mode.BLOCKCHAIN + '/did:talao:' + mode.BLOCKCHAIN + ':'  + self.workspace_contract[2:] + ".pem"
		try :
			file = open(filename,"wb")
			file.write( self.RSA_private)
			file.close()
			logging.info('RSA key stored on server')
		except :
			logging.error('RSA key not stored on server')
			return False

		# store Ethereum private key in keystore
		if not privatekey.add_private_key(self.private_key, mode) :
			logging.error('private key storage failed')
			return False
		else :
			logging.info('private key stored on server')

		# ERC725 key 1 issued to Web Relay as the Repository Manager
		if not add_key(self.address, self.workspace_contract, self.address, self.workspace_contract, self.private_key, mode.relay_address, 1, mode) :
			logging.error('ERC725 key 1 to repository manager failed')
			return False
		else :
			logging.error('ERC725 key 1 isued to repository manager')

		# rewrite email for recovery
		if Claim().add(self.address, self.workspace_contract, self.address, self.workspace_contract, self.private_key, 'email', self.email, 'public', mode)[0] :
			logging.info('email encryted updated')
		else :
			logging.warning('email encrypted not updated')

		logging.info('end of create repository')
		return True
Exemplo n.º 6
0
	def remove_credential(self, credential_id, mode) :
		credential  = Claim()
		return credential.relay_delete(self.workspace_contract, credential_id, mode)