-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Getting-Started-with-Akka-http-signature.md #3
base: master
Are you sure you want to change the base?
Changes from 1 commit
595db63
5aca3c7
db93d16
9dca8c0
7281e3a
77326af
a10d456
d4e3797
fc3e478
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -114,111 +114,77 @@ This will save the contents of the key in String format within the file found by | |
|
||
### Saving a public Key to RDF | ||
|
||
A user can also transform his public keys to an RDF. In order to do this one must first import multiple files in order to resolve the required dependencies. | ||
A user can also transform his public keys to an RDF. In order to do this one must first import multiple files in order to resolve the required dependencies: | ||
|
||
The org.w3 declarations required are: | ||
|
||
```scala | ||
import org.w3.banana.binder | ||
import org.w3.banana.binder.RecordBinder | ||
implicit val binder = RecordBinder | ||
val cert = CertPrefix[Rdf] | ||
``` | ||
Several java imports from java's security and math library are also required for this process: | ||
import $ivy.`run.cosy::solid-client:0.1-SNAPSHOT` | ||
import run.cosy.auth.RSAKeys | ||
import com.typesafe.sslconfig.akka._ | ||
import akka.actor._ | ||
import akka.http.scaladsl.model.Uri | ||
import com.typesafe.config.ConfigFactory | ||
import akka.event.Logging | ||
import akka.stream.{ActorMaterializer, ActorMaterializerSettings,Supervision,_} | ||
import akka.http.scaladsl.model.{Uri=>AkkaUri,_} | ||
|
||
```scala | ||
import java.math.BigInteger | ||
import java.security.KeyFactory | ||
import java.security.interfaces.RSAPublicKey | ||
import java.security.spec.RSAPublicKeySpec | ||
``` | ||
import scala.concurrent.ExecutionContext | ||
|
||
import org.w3.banana.jena.Jena | ||
|
||
After that the binder and all it's functionalities can be imported: | ||
import Jena._ | ||
|
||
```scala | ||
import org.w3.banana.binder._ | ||
import recordBinder._ | ||
import run.cosy.solid.client.Web._ | ||
import java.security.interfaces.RSAPublicKey | ||
``` | ||
|
||
Finally, after that, the user can create the Cert object that contains the required dependencies to turn a Key into a Pointed Graph | ||
Finally, after that, the user can create a value for the public key String collected from the .pem file in located within the .keys directory. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. horrible grammar. A value? |
||
|
||
```scala | ||
@ object Cert { | ||
|
||
implicit val rsaClassUri = classUrisFor[RSAPublicKey](cert.RSAPublicKey) | ||
val factory = KeyFactory.getInstance("RSA") | ||
val exponent = property[BigInteger](cert.exponent) | ||
val modulus = property[Array[Byte]](cert.modulus) | ||
|
||
implicit val binder: PGBinder[Rdf, RSAPublicKey] = | ||
pgb[RSAPublicKey](modulus, exponent)( | ||
(m, e) => factory.generatePublic(new RSAPublicKeySpec(new BigInteger(m), e)).asInstanceOf[RSAPublicKey], | ||
key => Some((key.getModulus.toByteArray, key.getPublicExponent)) | ||
) // withClasses rsaClassUri | ||
} | ||
@ val pubStr = read(home/".keys"/"pubKey.pem") | ||
|
||
defined object Cert | ||
pubStr: String = """MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkZXI44b8Qh7oNXzGvmdGSan1cisdzOur | ||
WWWheSxvr9zHe5kyNh8UtVZeVjTsRr/SnwEwqm1KJRiu0CfnyjTZmhQZJitZDjg+sTdDx3pcxntC | ||
MfckgRfaG+MjODbL2VTNHzaDYHlex0VwITcPH7RjPxJZyYmAlVg+MWMfX2VOBPqdBRZxO0DyH6ka | ||
kENtgT0TJ9XNEVWH+gpezc66jgptz/wryzCaVobdF042TvQ5VoZC5gavUMgDuHS3TiT9LXBFT3Hg | ||
A18h0qaZDkwJe6mHD/aULVrZYxf9irGJQAS2aTQHO/zdRJazlMX7oWQrVRpCmcz/BLpgxz4x9IC0 | ||
hHhTWQIDAQAB""" | ||
|
||
@ import Cert._ | ||
``` | ||
|
||
After this all dependencies should be resolved and the user will be able to transform the keys into a Pointed Graph: | ||
After this all dependencies should be resolved and the user will be able to transform the keys into a Pointed Graph using the following function | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the function below is hardly a function worth mentioning: It's more of a piece of test code to verify that things are working correctly. That is obvious because there are no attributes passed to the funciton. |
||
|
||
```scala | ||
@ val keyPG = pub.toPG | ||
@ def pubKeyPG = { | ||
import ops._ | ||
implicit val bind = run.cosy.crypto.Cert.binderWithName[Rdf](Uri("#key")) | ||
pubKey.map(_.toPG) | ||
} | ||
|
||
keyPG : PointedGraph[RDF] = org.w3.banana.PointedGraph$$anon$1@7f8fa63d | ||
defined function pubKeyPG | ||
``` | ||
One can then retrieve both the pointer and the graph: | ||
After that the user can simply call said function to get a pointed graph: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a little note as to what the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am unsure what you mean by this - where can I find this function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if you search the PR you will find that function. It's from the client code. |
||
|
||
```scala | ||
@ val keyGraph = keyGraph.graph | ||
@ val keyGraph = pubKeyPG | ||
|
||
keyGraph : RDF#Graph = {5880.026289.0-02638.0-6288.0-06411.0-23110.021178.029228.0 http://www.w3.org/ns/auth/cert#exponent "65537"^^http://www.w3.org/2001/XMLSchema#integer; 5880.026289.0-02638.0-6288.0-06411.0-23110.021178.029228.0 @http://www.w3.org/ns/auth/cert#modulus "00937adccd722bc982aed4847872b81e36b890bca13166714bc2befe4d8547b6218ecd2da1eb020198a4ea00e4db6757c7dda738ec8db8b3bf211d3a3a17e196a2035bc4c79d06d8a581487d9f49e86374712b10ef500dfa242a20cab52911e2636c9d99b21fe9768ef2381989a25dc8b0b7a46531249aac27c4b8ab451a19d5fbdfa5f78b0deac9778c7ff87cf6106ae4a6433466beb21df1265bf1fc9ab9cc80d7aff8cc4d0f67ae28647e4048da8df753493b8de6a8e0961416b4b37f7012907d2e756034b8a84c6e495c8f1d81f69843ae51379571d83b38e1c08a08c3748ef75ed7ecb016d0c8426b30c8c5060a08f87f6764b0ec14667cd6f0daa1244157"^^http://www.w3.org/2001/XMLSchema#hexBinary} | ||
|
||
@ val keyRDFPointer = keyGraph.pointer | ||
|
||
keyRDFPointer: RDF#Node = 5880.026289.0-02638.0-6288.0-06411.0-23110.021178.029228.0 | ||
``` | ||
As is evident, the pointer is an automatically generated Blank Node, which can be quite difficult to process. Because of this, it would be more optimal to change the pointer to not be a blank node but rather a #uri. The user can change the pointer by using the following function : | ||
|
||
```scala | ||
@ implicit class PGwrapper(val pg: PointedGraph[Rdf]) extends AnyVal { | ||
def rename(to: Rdf#Node)(implicit ops: RDFOps[Rdf]): PointedGraph[Rdf] = { | ||
val oldNode = pg.pointer | ||
PointedGraph[Rdf]( | ||
to, | ||
ops.makeGraph(pg.graph.triples.map{ triple => | ||
ops.fromTriple(triple) match { | ||
case (oldNode,rel,obj) => ops.makeTriple(to,rel,obj) | ||
case (subj,rel,oldNode) => ops.makeTriple(subj,rel,to) | ||
case _ => triple | ||
} | ||
}) | ||
) | ||
} | ||
} | ||
|
||
defined class PGwrapper | ||
res44: Try[PointedGraph[Jena]] = Success(org.w3.banana.PointedGraph$$anon$1@5487b93e) | ||
``` | ||
|
||
After this, one can simply change the header by into something simple by calling this function like so: | ||
The function pubKeyPG returns a Try[PointedGraph[Jena]]. We can then retreive both the pointer and the graph from this PointedGraph like so: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should be able to do that in one step I think using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah this is how it works: val org.w3.banana.PointedGraph(p,g) = res2.value.get.get._1.content Read up pattern matching in Ordersky's book. |
||
|
||
```scala | ||
@ val finalKeyPG = keyPG.rename(URI("#key")) | ||
@ val keyFinalPointer= keyGraph.get.pointer | ||
|
||
finalKeyPG: PointedGraph[Rdf] = org.w3.banana.PointedGraph$$anon$1@4353a749 | ||
keyFinalPointer: Jena#Node = #key | ||
|
||
@ finalKeyPGPointer = finalKeyPG.pointer | ||
|
||
finalKeyPGPointer : Rdf#Node = #key | ||
@ val keyFinalGraph = keyGraph.get.graph | ||
|
||
@ finalKeyPGGraph = finalKeyPG.graph | ||
keyFinalGraph: Jena#Graph = {#key @http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://www.w3.org/ns/auth/cert#RSAPublicKey; #key @http://www.w3.org/ns/auth/cert#modulus "009195c8e386fc421ee8357cc6be674649a9f5722b1dccebab5965a1792c6fafdcc77b9932361f14b5565e5634ec46bfd29f0130aa6d4a2518aed027e7ca34d99a1419262b590e383eb13743c77a5cc67b4231f7248117da1be3233836cbd954cd1f368360795ec7457021370f1fb4633f1259c9898095583e31631f5f654e04fa9d0516713b40f21fa91a90436d813d1327d5cd115587fa0a5ecdceba8e0a6dcffc2bcb309a5686dd174e364ef439568642e606af50c803b874b74e24fd2d70454f71e0035f21d2a6990e4c097ba9870ff6942d5ad96317fd8ab1894004b66934073bfcdd4496b394c5fba1642b551a4299ccff04ba60c73e31f480b484785359"^^http://www.w3.org/2001/XMLSchema#hexBinary; #key @http://www.w3.org/ns/auth/cert#exponent "65537"^^http://www.w3.org/2001/XMLSchema#integer} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
finalKeyPGGraph: Rdf#Graph = {#key @http://www.w3.org/ns/auth/cert#modulus "0087acb657366c6a911a0ce2470c24b8d85dd21ae76c6001db37d122c2eafe0fe2ae35541ccdd3c1c81603d98dd7d61b2c31c8605f81fbc3566604b7755793698836caaa99d868477c46b5b735529b50c0acfea6e10fc9b953697a67d57499801beb651e7e08343131a00d1873ab753ce5e79fc961874ee132472f7f210bc38966081fe263c620b67469b52cc555a26dee4fa10d8f40959e0e13516cc0bd1c1669ce53367d28248149142429b127f01e13d9bf21de52a4ac5694d5038a94178e144823b152fa19cbbc094dd40ddbd41e2195a19081125887fccedae21c50660c629a6f2ba4c85a54e1a6472f90b7b62ac7fe58fdae9daa0edc8edec49802fbfac7"^^http://www.w3.org/2001/XMLSchema#hexBinary; #key @http://www.w3.org/ns/auth/cert#exponent "65537"^^http://www.w3.org/2001/XMLSchema#integer} | ||
``` | ||
|
||
As evident, the Blank node is now changed to something more readable and useful. | ||
As evident, the pointer of this graph is a useful identifier "#key" and the graph itself is the key information. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it useful? Also note that it is a relative URI. That should help you understand what is interesting about it when you post it. (It is useful also because how it is used in access control settings). |
||
|
||
The user can transform his key graph into a one of several well-known formats before publishing it on the server. One such format is turtle. In order to do that however, more external libraries are required: | ||
|
||
|
@@ -231,7 +197,7 @@ import org.w3.banana.jena.Jena | |
One can then represent the rdf of the key in turtle format: | ||
|
||
```scala | ||
@ val toTurtle = turtleWriter.asString(finalKeyPGGraph ,"").get | ||
@ val toTurtle = turtleWriter.asString(keyFinalGraph ,"").get | ||
|
||
toTurtle: String = """<#key> <http://www.w3.org/ns/auth/cert#exponent> | ||
65537 ; | ||
|
@@ -249,6 +215,12 @@ write(wd/"publicKey.ttl", toTurtle) | |
|
||
### Attaching Public keys to a File/URI | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Publishing the Public key to the WebThere are a number of ad hoc ways to do this and one simple standard way to publish it.
For illustration see the document [ I pointed you to twice already] and to the setup for rww-play. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you please add that to the doc as is, with the last link filled in. |
||
|
||
The most efficient way to attach a public key to a server is by using the rww-play library's httpMethods.sc script which makes use of the solid-server POST definition. That way the user can use the postLocal() and postLocalGood() functions to pubish his public key on a web and local server respectively. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's not rww-play's httpMethod.sc ! |
||
|
||
```scala | ||
Code but errors not resolved | ||
``` | ||
|
||
One can use the `cp` or the `mv` Ammonite commands to move the public key file into the test_www directory which resides within the rww-play directory. The process of attaching the file, containing the key to a URI is very similar. | ||
|
||
```scala | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
->"to an RDF Graph".
There is no such thing as an RDF.
Also I don't think we should be speaking of "user" here. Just stick to the generic one. Users are often thought of as end users, whereas here we are speaking of programmers, but that is obvious and a mouthful.