#!/usr/bin/python """A FOAF checker that takes a URI of a signed FOAF file, confirms the signature, and returns the name, email address, other selected properties of the foaf:Person in that instance with an rdf:seeAlso that matches the URI. Repeat: the FOAF instance must have a or equivalent in the foaf:Person that this URI describes. PGP Signing FOAF Files http://usefulinc.com/foaf/signingFoafFiles FoafCheck requires GnuPG. See also: http://www.sixapart.com/log/2003/01/fun_with_foaf.shtml """ import os, rdfxml, sys, urllib RDF = rdfxml.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#') FOAF = rdfxml.Namespace('http://xmlns.com/foaf/0.1/') WOT = rdfxml.Namespace('http://xmlns.com/wot/0.1/') class World(object): def __init__(self): self.subjects = {} def triple(self, s, p, o): if s[0] == '<': s = s[1:-1] if p[0] == '<': p = p[1:-1] if o[0] == '<': o = o[1:-1] if o[0] == '"': o = o[1:-1] if not self.subjects.has_key(s): self.subjects[s] = { RDF.about: [ s ] } if not self.subjects[s].has_key(p): self.subjects[s][p] = [] self.subjects[s][p].append(o) class FoafCheckError(Exception): pass def check_uri(uri): try: foaf_instance = urllib.urlopen(uri).read() except OSError: raise FoafCheckError("Could not read FOAF instance '%s'" % uri) foaf = World() rdfxml.parseRDF(foaf_instance, uri, foaf) if not foaf.subjects.has_key(uri): raise FoafCheckError('FOAF instance missing resource for "this" URI') if not foaf.subjects[uri].has_key(WOT.assurance): raise FoafCheckError('FOAF instance missing wot:assurance in resource for "this" URI') foaf_signature_uri = foaf.subjects[uri][WOT.assurance][0] try: foaf_signature = urllib.urlopen(foaf_signature_uri).read() except OSError: raise FoafCheckError("Could not read FOAF signature '%s'" % foaf_signature_uri) open('/tmp/foaf-check-temp-file.rdf', 'w').write(foaf_instance) open('/tmp/foaf-check-temp-file.rdf.asc', 'w').write(foaf_signature) result = os.system('''/usr/bin/gpg --no-options --homedir=/tmp --verify \ /tmp/foaf-check-temp-file.rdf.asc /tmp/foaf-check-temp-file.rdf \ >/tmp/foaf-check-temp-file.log 2>&1''') if result != 0: print open('/tmp/foaf-check-temp-file.log').read() raise FoafCheckError('FOAF signature does not verify') found = 0 for node in foaf.subjects.values(): if node.has_key(RDF.seeAlso): if node[RDF.seeAlso][0] == uri: found = 1 break if not found: raise FoafCheckError('No foaf:Person found in FOAF instance') return node if __name__ == "__main__": if len(sys.argv) != 2: print __doc__ sys.exit(1) try: node = check_uri(sys.argv[1]) except FoafCheckError: print sys.exc_info()[1] sys.exit(1) for ii in "name firstName surname nick mbox homepage depiction".split(): if node.has_key(FOAF + ii): print "%s: %s" % (ii, node[FOAF + ii][0])