def decrypt(self, key, serialization=SERIALIZATION.TURTLE): ''' Decrypt with SessionKey. Using encrypted string to recover the original Object. @return a new Obj decrypted from cipertext, without those additional types like EncryptedReference and Reference, which were inserted by encrypt() method before. ''' if self.encryptedStringRepresentation is not None: if isinstance(key, RSA._RSAobj): decryptedString, symkey = SmartAPICrypto().asymmetricDecrypt( key, self.encryptedStringRepresentation) else: decryptedString = SmartAPICrypto().symmetricDecrypt( key, self.encryptedStringRepresentation) model = Tools().fromString(decryptedString, serialization) # find the resource which was encrypted rootRes = Tools().getTopNode(model)[0] # figure out its SMARTAPI Class seasCls = Tools().getResourceClass(rootRes) # recover it to Obj or its subclass Object recoveredObj = seasCls.parse(rootRes) # remove EncryptedReference and Reference types. recoveredObj.types.remove(URIRef(RESOURCE.ENCRYPTEDREFERENCE)) recoveredObj.types.remove(URIRef(RESOURCE.REFERENCE)) self.__dict__.update(recoveredObj.__dict__) return recoveredObj else: pass
def fetchFromTransactionServer(cls, senderId, notary, *args): ''' @param senderId: URI string @param notary: URI string @param args: a variable number of Transaction Objects @return a dictionary, key is SeasIdentifierUri of each transaction, value is Transaction Object ''' try: client = HttpClient() # create an empty MIME multipart message sentHttpMessage = HttpMessage() # main request req = RequestFactory().create(senderId) req.setMethod(RESOURCE.READ) cls.messageIdCounter = cls.messageIdCounter + 1 req.setMessageId(cls.messageIdCounter) a = Activity() req.addActivity(a) i = Input() a.addInput(i) system = SystemOfInterest() system.setSameAs(notary) i.setSystemOfInterest(system) param = Parameter() param.setKey("transactions") param.setName("Transaction id list") param.setDescription( "List of ids of transactions that are sent to be fetched the database." ) for transaction in args: param.addValue(transaction.getIdentifierUri()) i.addParameter(param) # save Request object to multipart message, Main part mainRequestString = Tools.toString(req) sentHttpMessage.addMainpart(mainRequestString) mainRequestHash = SmartAPICrypto().createEncodedMessageDigest( mainRequestString) requestSignature = SmartAPICrypto().sign( CryptoKeyWallet.getPrivateKey(), mainRequestHash) #create transaction for the main request if cls.transactionIdentifierUriPrefix == '': transactionIdentifierUri = senderId + uuid.uuid4().get_hex() else: transactionIdentifierUri = transactionIdentifierUri + uuid.uuid4( ).get_hex() requestTransaction = Factory.createTransaction( transactionIdentifierUri, senderId) requestTransaction.setSigner(senderId) requestTransactionMessage = Message() requestTransactionMessage.setMessageId(req.getMessageId()) requestTransactionMessage.setHashCode(mainRequestHash) requestTransactionMessage.setSignature(requestSignature) requestTransaction.setMessage(requestTransactionMessage) # add requestTransaction to multipart message, non-Main part requestTransactionString = Tools.toString(requestTransaction) sentHttpMessage.add(transactionIdentifierUri, requestTransactionString) # add transactions that are sent to multipart message, non-Main part for trans in args: sentHttpMessage.add(trans.getIdentifierUri(), Tools.toString(trans)) # send out this multipart message payload = removeFrontHeader(sentHttpMessage.asString()) resp, contentType = client.sendPost( notary, payload, sentHttpMessage.getContentType()) receivedHttpMessagestr = addFrontHeader(resp, contentType) receivedHttpMessage = parseMIMEmessage(receivedHttpMessagestr) map = {} if isinstance(receivedHttpMessage, HttpMessageSingle): non_main_parts_dict = {} else: non_main_parts_dict = receivedHttpMessage.getNonMainPartsAsDict( ) counter = 0 for part in non_main_parts_dict.values(): counter = counter + 1 # recover the part from string to Seas Obj model = Tools().fromString(part, SERIALIZATION.TURTLE) rootRes = Tools().getTopNode(model)[0] seasCls = Tools().getResourceClass(rootRes) recoveredObj = seasCls.parse(rootRes) if isinstance( recoveredObj, Transaction ): # We want to save the Transaction that hold the requested data map[recoveredObj.getIdentifierUri()] = recoveredObj return map except: traceback.print_exc()
def parseStatement(self, statement): ''' It takes in statement as input, add property to existing model Class object. Return None ''' from SmartAPI.model.Parameter import Parameter from SmartAPI.model.Provenance import Provenance from SmartAPI.model.Activity import Activity from SmartAPI.model.Offering import Offering # get predicate and object predicate = str(statement.getPredicate()) objectNode = statement.getObject() # type if predicate == PROPERTY.RDF_TYPE: self.addType(URIRef(statement.getResource().toString())) return # sameas if predicate == PROPERTY.SAMEAS: self.setSameAs(statement.getResource().toString()) return # generatedby if predicate == PROPERTY.GENERATEDBY: self.setGeneratedBy(Activity.parse(statement.getResource())) return # generatedat if predicate == PROPERTY.GENERATEDAT: self.setGeneratedAt(statement.getObject().toPython()) return # provenance if predicate == PROPERTY.PROVENANCE: self.addProvenance(Provenance.parse(statement.getResource())) return # offerings if predicate == PROPERTY.OFFERS: self.addOffering(Offering.parse(statement.getResource())) return # target if predicate == PROPERTY.TARGET: self.addTarget(statement.getString()) return # label if predicate == PROPERTY.RDFS_LABEL: self.setName(statement.getString()) return # comment if predicate == PROPERTY.COMMENT: self.setDescription(statement.getString()) return # sessionKey if predicate == PROPERTY.SESSIONKEY: self.setSessionKey(statement.getString()) return # signature if predicate == PROPERTY.SIGNATURE: self.setSignature(statement.getString()) return # hashcode if predicate == PROPERTY.HASHCODE: self.setHashCode(statement.getString()) return # encryptionKeyType if predicate == PROPERTY.ENCRYPTIONKEYTYPE: self.setEncryptionKeyType(statement.getResource().toString()) return # notary if predicate == PROPERTY.NOTARY: self.setNotary(statement.getResource().toString()) return # parameters if predicate == PROPERTY.PARAMETER: p = Parameter().parse(statement.getResource()) self.add(p.getKey(), p.getValues()) return # if literal object if isinstance(objectNode, Literal): self.add(URIRef(predicate), objectNode.toPython()) #print 'DEBUG: ', objectNode.datatype, '...', objectNode # if ((objectNode.datatype is not None) and objectNode.datatype == XSD.duration): # self.add(URIRef(predicate), statement.getString()) # else: # self.add(URIRef(predicate), objectNode.toPython()) return # if isinstance(objectNode, URIRef): # print "parse URI resource ", objectNode # self.add(URIRef(predicate), objectNode) # return # if resource if isinstance(objectNode, URIRef): resource = statement.getResource() # first check if resource has a type implemented built-in # and parse using that klass = Tools().getResourceClass(resource, default=Obj) if klass is not None: self.add(URIRef(predicate), klass.parse(resource)) else: # None found, resort to Obj (the base class) self.add(URIRef(predicate), Obj.parse(resource)) return # Nothing else matches, use BNode as blank default entry if isinstance(objectNode, BNode): try: klass = Tools().getResourceClass(statement.getResource(), default=None) except: klass = None if klass is not None: self.add(URIRef(predicate), klass.parse(statement.getResource())) else: self.add(URIRef(predicate), objectNode.toPython()) return
def parse(cls, element): ''' factory method and class method. It takes in Resource as parameter, create a Seas Obj or its subClass object. @return: this newly created object, which could be either a real Obj or its subclass Object or a Reference, whose actual content is in multipart message's body part ''' if isinstance(element, Resource) and Tools.parsedObjs.has_key( element.toString()): return Tools.parsedObjs.get(element.toString()) elif isinstance( element, Resource) and not Tools.parsedObjs.has_key(element.toString()): if not element.isAnon(): obj = cls(element.toString()) else: obj = cls() Tools.parsedObjs[element.toString()] = obj for i in element.findProperties(): obj.parseStatement(i) # check whether this Obj is a reference if obj.isOfType(RESOURCE.MULTIPARTREFERENCE): if obj.hasIdentifierUri(): if (len(Tools.messagePartsForParse) > 0) and (obj.getIdentifierUri() in Tools.messagePartsForParse): stringRepresentation = Tools.messagePartsForParse[ obj.getIdentifierUri()] # if this Obj is EncryptedReference, it will be decrypted later by decrypt() call. if obj.isOfType(RESOURCE.ENCRYPTEDREFERENCE): obj.encryptedStringRepresentation = stringRepresentation else: # if not encrypted, replace this reference Obj with a new Object, # which is deserialzed from the stringRepresentation, containing actual content. # This happens in the case of digital signature model = Tools().fromString(stringRepresentation, SERIALIZATION.TURTLE) # find the root Resource rootRes = Tools().getTopNode(model)[0] # figure out its SMARTAPI Class seasCls = Tools().getResourceClass(rootRes) # recover it to Obj or its subclass Object recoveredObj = seasCls.parse(rootRes) # copy signature, hashcode from reference Obj to recovered Obj recoveredObj.setSignature(obj.getSignature()) recoveredObj.setHashCode(obj.getHashCode()) recoveredObj.types.remove( URIRef(RESOURCE.REFERENCE)) obj = recoveredObj del Tools.messagePartsForParse[obj.getIdentifierUri()] else: raise Exception( '******* ERROR: can not find the encrypted string representation of {}' .format(obj.getIdentifierUri())) #try: # raise Exception('just to check!!!') #except: # traceback.print_stack() else: raise Exception( '***** ERROR: reference Obj has to be named!!!*******') return obj return None