def _make_device_entity(self, device): """ - makes entity - publishes entity - namespace grant to device entity read on <hash>/<device>/control - namespace grant to device entity write on <hash>/<device>/report """ device_entity, newlyCreated = createOrLoadEntity(self.agent, device) if newlyCreated: self.agent.PublishEntity(wv.PublishEntityParams(DER=device_entity.PublicDER)) device_perspective=wv.Perspective( entitySecret=wv.EntitySecret(DER=device_entity.SecretDER) ) # grant permission to encrypt on device URIs, read/write on report/control respectively encrypt_policy = wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, # TODO: need this? # visibilityURI=[bytes("smarthome","utf8"),bytes(device,"utf8")], statements=[ wv.RTreePolicyStatement( permissionSet=wv.WaveBuiltinPSET, permissions=[wv.WaveBuiltinE2EE], resource="smarthome/{0}/+".format(device), ) ] )) msg_policy = wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[ wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["read"], resource="smarthome/{0}/control".format(device), ), wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/{0}/report".format(device), ) ] )) if newlyCreated: r = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=device_entity.hash, publish=True, policy=msg_policy )) #print(r) #print('msg policy attested') r = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=device_entity.hash, publish=True, policy=encrypt_policy, )) #print(r) #print('encrypt policy attested') #print(encrypt_policy) encrypt_proof = self.agent.BuildRTreeProof(wv.BuildRTreeProofParams( perspective=device_perspective, namespace=encrypt_policy.rTreePolicy.namespace, resyncFirst=True, statements=encrypt_policy.rTreePolicy.statements, )) if encrypt_proof.error.code != 0: raise Exception(encrypt_proof.error) msg_proof = self.agent.BuildRTreeProof(wv.BuildRTreeProofParams( perspective=device_perspective, namespace=msg_policy.rTreePolicy.namespace, resyncFirst=True, statements=msg_policy.rTreePolicy.statements, )) if msg_proof.error.code != 0: raise Exception(msg_proof.error) return device_entity, encrypt_proof, msg_proof
def grant_permissions_to(self, enthash): # grant the ability to decrypt data that the thermostat publishes resp = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=enthash, publish=True, policy=wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[wv.RTreePolicyStatement( permissionSet=wv.WaveBuiltinPSET, permissions=[wv.WaveBuiltinE2EE], resource="smarthome/thermostat/+", )] )) )) if resp.error.code != 0: raise Exception(resp.error.message) # grant the ability to decrypt data that the motion sensor publishes resp = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=enthash, publish=True, policy=wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[wv.RTreePolicyStatement( permissionSet=wv.WaveBuiltinPSET, permissions=[wv.WaveBuiltinE2EE], resource="smarthome/motion/+", )] )) )) if resp.error.code != 0: raise Exception(resp.error.message) # grant the ability to decrypt data that the light publishes resp = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=enthash, publish=True, policy=wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[wv.RTreePolicyStatement( permissionSet=wv.WaveBuiltinPSET, permissions=[wv.WaveBuiltinE2EE], resource="smarthome/light/+", )] )) )) if resp.error.code != 0: raise Exception(resp.error.message) # grant the ability to actuate the thermostat and the light and the notifications, and read the thermostat and light resp = self.agent.CreateAttestation(wv.CreateAttestationParams( perspective=self.perspective, subjectHash=enthash, publish=True, policy=wv.Policy(rTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, indirections=5, statements=[wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/thermostat/control", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/light/control", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/notify", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["read"], resource="smarthome/thermostat/report", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["read"], resource="smarthome/light/report", ),wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["read"], resource="smarthome/motion/report", )] )) )) if resp.error.code != 0: raise Exception(resp.error.message)
def on_message(self, client, userdata, msg): proof, payload = unpack_payload(msg.payload) if len(proof) == 0: return if msg.topic == self.nickname + "/smarthome/light/control": resp = self.agent.VerifyProof( wv.VerifyProofParams( proofDER=proof, requiredRTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, statements=[ wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/light/control", ) ]))) if resp.error.code != 0: print( "home server received light control with invalid proof: ", resp.error.message) return # actuate light state when the light receives a direct message ls = json.loads(payload).get('state') self.light_widget.state = (ls == 'on' or ls == True) #self.notify("Light changed (remote) to {0}".format('on' if self.light_widget.state else 'off')) elif msg.topic == self.nickname + "/smarthome/thermostat/control": resp = self.agent.VerifyProof( wv.VerifyProofParams( proofDER=proof, requiredRTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, statements=[ wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/thermostat/control", ) ]))) if resp.error.code != 0: print( "home server received thermostat control with invalid proof: ", resp.error.message) return # TODO integrate with gabe's widget here tstat_fields = json.loads(payload) #print('thermostat command', tstat_fields) if tstat_fields.get('hsp'): self.thermostat_widget.hsp = tstat_fields.get('hsp') self.notify( "Thermostat heating setpoint changed to {0}".format( self.thermostat_widget.hsp)) if tstat_fields.get('csp'): self.thermostat_widget.csp = tstat_fields.get('csp') self.notify( "Thermostat cooling setpoint changed to {0}".format( self.thermostat_widget.csp)) if tstat_fields.get('temperature'): self.thermostat_widget.temp = tstat_fields.get('temp') elif msg.topic == self.nickname + "/smarthome/notify": resp = self.agent.VerifyProof( wv.VerifyProofParams(proofDER=proof, requiredRTreePolicy=wv.RTreePolicy( namespace=self.ent.hash, statements=[ wv.RTreePolicyStatement( permissionSet=smarthome_pset, permissions=["write"], resource="smarthome/notify", ) ]))) if resp.error.code != 0: print("home server received notify with invalid proof: ", resp.error.message) return self.notify(json.loads(payload)) else: print("topic", msg.topic, "payload", payload)