Repository: incubator-milagro-mfa-sdk-core
Updated Branches:
  refs/heads/master cadbe7c8d -> a9e2bcb95 (forced update)


Add documentation


Project: 
http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/commit/a9e2bcb9
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/tree/a9e2bcb9
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/diff/a9e2bcb9

Branch: refs/heads/master
Commit: a9e2bcb95b66172f7cdcfae3c1f3c0f0f8515453
Parents: e631fb2
Author: Simeon Aladjem <simeon.alad...@miracl.com>
Authored: Fri Sep 16 13:26:28 2016 +0300
Committer: Simeon Aladjem <simeon.alad...@miracl.com>
Committed: Fri Sep 16 13:26:28 2016 +0300

----------------------------------------------------------------------
 M-Pin SDK - Authentication flow.png             | Bin 0 -> 34457 bytes
 M-Pin SDK - Authentication flow.xml             |   2 +
 ...- Authentication to Browser Session flow.png | Bin 0 -> 50192 bytes
 ...- Authentication to Browser Session flow.xml |   2 +
 M-Pin SDK - Registration flow.png               | Bin 0 -> 36643 bytes
 M-Pin SDK - Registration flow.xml               |   2 +
 Mobile-SDK-Architecture.png                     | Bin 0 -> 26171 bytes
 README.md                                       | 371 ++++++++++++++++++-
 8 files changed, 376 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/a9e2bcb9/M-Pin
 SDK - Authentication flow.png
----------------------------------------------------------------------
diff --git a/M-Pin SDK - Authentication flow.png b/M-Pin SDK - Authentication 
flow.png
new file mode 100644
index 0000000..c386255
Binary files /dev/null and b/M-Pin SDK - Authentication flow.png differ

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/a9e2bcb9/M-Pin
 SDK - Authentication flow.xml
----------------------------------------------------------------------
diff --git a/M-Pin SDK - Authentication flow.xml b/M-Pin SDK - Authentication 
flow.xml
new file mode 100644
index 0000000..4bf06c0
--- /dev/null
+++ b/M-Pin SDK - Authentication flow.xml       
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mxGraphModel dx="1050" dy="636" grid="1" gridSize="10" guides="1" 
tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" 
pageWidth="826" pageHeight="1169" background="#ffffff" math="0"><root><mxCell 
id="0"/><mxCell id="1" parent="0"/><mxCell id="2" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" parent="1" source="3" 
target="5" edge="1"><mxGeometry x="414" y="130" as="geometry"/></mxCell><mxCell 
id="3" value="Start" style="ellipse;whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="379" y="90" width="70" height="40" 
as="geometry"/></mxCell><mxCell id="25" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;" 
parent="1" source="5" target="23" edge="1"><mxGeometry relative="1" 
as="geometry"><Array as="points"/></mxGeometry></mxCell><mxCell id="5" 
value="&lt;font face=&quot;Lucida 
Console&quot;&gt;StartAuthentication&lt;/font&gt;" 
style="whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry x="342" 
y="180" wid
 th="144" height="40" as="geometry"/></mxCell><mxCell id="9" 
value="&lt;code&gt;&lt;font face=&quot;Lucida 
Console&quot;&gt;OK&lt;/font&gt;&lt;/code&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;entryX=0.5;entryY=0;"
 parent="1" source="23" target="19" edge="1"><mxGeometry as="geometry"><mxPoint 
y="3" as="offset"/><mxPoint x="414" y="449.6715328467153" 
as="sourcePoint"/><mxPoint x="414" y="371" as="targetPoint"/><Array 
as="points"/></mxGeometry></mxCell><mxCell id="18" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;exitX=0.5;exitY=1;"
 parent="1" source="19" target="21" edge="1"><mxGeometry x="414" y="763" 
as="geometry"><Array as="points"/></mxGeometry></mxCell><mxCell id="19" 
value="Read Secret (PIN)&lt;div&gt;from end user&lt;/div&gt;" 
style="whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry x="354" 
y="383" width="120" height="40" as="geometry"/></mxCell><mxCell id="37" 
value="" style="edgeStyle=orthogonalEdg
 eStyle;rounded=0;html=1;" parent="1" source="21" target="36" 
edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="21" 
value="&lt;p&gt;&lt;code&gt;&lt;font face=&quot;Lucida Console&quot; 
style=&quot;font-size: 
12px&quot;&gt;FinishAuthentication&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;" 
style="whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry x="330" 
y="483" width="168" height="40" as="geometry"/></mxCell><mxCell id="22" 
value="End" style="ellipse;whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="379" y="759.5999999999999" width="70" height="40" 
as="geometry"/></mxCell><mxCell id="27" value="&lt;span&gt;&lt;font 
face=&quot;Lucida Console&quot;&gt;REVOKED&lt;/font&gt;&lt;/span&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;" 
parent="1" source="23" target="28" edge="1"><mxGeometry x="-0.04" y="15" 
relative="1" as="geometry"><mxPoint x="582" y="315" as="targetPoint"/><Array 
as="points"/><mxPoint as="offset"/></mxGeometry><
 /mxCell><mxCell id="23" value="Status?" 
style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry 
x="366" y="265" width="95" height="60" as="geometry"/></mxCell><mxCell id="30" 
value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=1;entryY=0.5;exitX=0.5;exitY=1;"
 parent="1" source="28" target="22" edge="1"><mxGeometry relative="1" 
as="geometry"><mxPoint x="637" y="435" as="targetPoint"/><Array 
as="points"><mxPoint x="637" y="780"/></Array></mxGeometry></mxCell><mxCell 
id="28" value="User is Revoked" style="whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="580" y="275" width="114" height="40" 
as="geometry"/></mxCell><mxCell id="39" value="&lt;font face=&quot;Lucida 
Console&quot;&gt;OK&lt;/font&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" parent="1" source="36" 
target="22" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell 
id="41" value="&lt;span&gt;&lt;font face=&quot;Lucida 
Console&quot;&gt;INCORRECT_PIN&lt;/
 font&gt;&lt;/span&gt;" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" 
parent="1" source="36" target="40" edge="1"><mxGeometry x="-0.08" y="-12" 
relative="1" as="geometry"><mxPoint as="offset"/></mxGeometry></mxCell><mxCell 
id="36" value="Status?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="366" y="573" width="95" height="65" 
as="geometry"/></mxCell><mxCell id="43" value="&lt;font face=&quot;Lucida 
Console&quot;&gt;REGISTERED&lt;/font&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;exitX=0.5;exitY=0;"
 parent="1" source="40" target="19" edge="1"><mxGeometry x="-0.5393" 
relative="1" as="geometry"><mxPoint x="218.5" y="733" as="targetPoint"/><Array 
as="points"><mxPoint x="219" y="403"/></Array><mxPoint 
as="offset"/></mxGeometry></mxCell><mxCell id="48" value="&lt;font 
face=&quot;Lucida Console&quot;&gt;BLOCKED&lt;/font&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;" 
parent="1" sourc
 e="40" target="46" edge="1"><mxGeometry relative="1" as="geometry"><Array 
as="points"/></mxGeometry></mxCell><mxCell id="40" value="User State?" 
style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry 
x="171" y="573" width="95" height="65" as="geometry"/></mxCell><mxCell id="50" 
value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;exitX=0.5;exitY=1;"
 parent="1" source="46" target="22" edge="1"><mxGeometry relative="1" 
as="geometry"><mxPoint x="219" y="1090" as="targetPoint"/><Array 
as="points"><mxPoint x="219" y="780"/></Array></mxGeometry></mxCell><mxCell 
id="46" value="User is Blocked&lt;div&gt;(need to re-register)&lt;/div&gt;" 
style="whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry x="159" 
y="690" width="120" height="40" as="geometry"/></mxCell></root></mxGraphModel>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/a9e2bcb9/M-Pin
 SDK - Authentication to Browser Session flow.png
----------------------------------------------------------------------
diff --git a/M-Pin SDK - Authentication to Browser Session flow.png b/M-Pin SDK 
- Authentication to Browser Session flow.png
new file mode 100644
index 0000000..3685828
Binary files /dev/null and b/M-Pin SDK - Authentication to Browser Session 
flow.png differ

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/a9e2bcb9/M-Pin
 SDK - Authentication to Browser Session flow.xml
----------------------------------------------------------------------
diff --git a/M-Pin SDK - Authentication to Browser Session flow.xml b/M-Pin SDK 
- Authentication to Browser Session flow.xml
new file mode 100644
index 0000000..4237a4b
--- /dev/null
+++ b/M-Pin SDK - Authentication to Browser Session flow.xml    
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mxGraphModel dx="1050" dy="636" grid="1" gridSize="10" guides="1" 
tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" 
pageWidth="826" pageHeight="1169" background="#ffffff" math="0"><root><mxCell 
id="0"/><mxCell id="1" parent="0"/><mxCell id="2" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" parent="1" source="3" 
target="5" edge="1"><mxGeometry x="414" y="130" as="geometry"/></mxCell><mxCell 
id="3" value="Start" style="ellipse;whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="379" y="90" width="70" height="40" 
as="geometry"/></mxCell><mxCell id="25" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;" 
parent="1" source="5" target="23" edge="1"><mxGeometry relative="1" 
as="geometry"><Array as="points"/></mxGeometry></mxCell><mxCell id="5" 
value="&lt;font face=&quot;Lucida 
Console&quot;&gt;StartAuthentication&lt;/font&gt;" 
style="whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry x="342" 
y="180" wid
 th="144" height="40" as="geometry"/></mxCell><mxCell id="9" 
value="&lt;code&gt;&lt;font face=&quot;Lucida 
Console&quot;&gt;OK&lt;/font&gt;&lt;/code&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0.5;exitY=1;entryX=0.5;entryY=0;"
 parent="1" source="23" target="31" edge="1"><mxGeometry as="geometry"><mxPoint 
as="offset"/><mxPoint x="414" y="449.6715328467153" as="sourcePoint"/><mxPoint 
x="414" y="420" as="targetPoint"/><Array 
as="points"/></mxGeometry></mxCell><mxCell id="13" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" parent="1" source="14" 
target="17" edge="1"><mxGeometry x="414" y="585" 
as="geometry"/></mxCell><mxCell id="14" value="&lt;font face=&quot;Lucida 
Console&quot;&gt;CheckAccessNumber&lt;/font&gt;" 
style="whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry x="342" 
y="460" width="144" height="40" as="geometry"/></mxCell><mxCell id="15" 
value="&lt;span&gt;&lt;font face=&quot;Lucida 
Console&quot;&gt;INCORRECT_ACCESS_NUMBER&lt;/fon
 t&gt;&lt;/span&gt;&lt;br&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;exitX=0;exitY=0.5;entryX=0;entryY=0.5;"
 parent="1" source="17" target="31" edge="1"><mxGeometry as="geometry"><mxPoint 
x="500" y="520" as="targetPoint"/><Array as="points"><mxPoint x="190" 
y="585"/><mxPoint x="190" y="391"/></Array><mxPoint x="-76" y="82" 
as="offset"/></mxGeometry></mxCell><mxCell id="35" value="&lt;font 
face=&quot;Lucida Console&quot;&gt;OK&lt;/font&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" parent="1" source="17" 
target="19" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell 
id="17" value="Status?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="366" y="552" width="95" height="65" 
as="geometry"/></mxCell><mxCell id="18" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;exitX=0.5;exitY=1;"
 parent="1" source="19" target="21" edge="1"><mxGeometry x="414" y="790" 
as="geometry"><Array as="poin
 ts"/></mxGeometry></mxCell><mxCell id="19" value="Read Secret 
(PIN)&lt;div&gt;from end user&lt;/div&gt;" style="whiteSpace=wrap;html=1;" 
parent="1" vertex="1"><mxGeometry x="354" y="670" width="120" height="40" 
as="geometry"/></mxCell><mxCell id="37" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" parent="1" source="21" 
target="36" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell 
id="21" value="&lt;p&gt;&lt;code&gt;&lt;font face=&quot;Lucida Console&quot; 
style=&quot;font-size: 
12px&quot;&gt;FinishAuthenticationAN&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;" 
style="whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry x="330" 
y="770" width="168" height="40" as="geometry"/></mxCell><mxCell id="22" 
value="End" style="ellipse;whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="379" y="1046.6" width="70" height="40" 
as="geometry"/></mxCell><mxCell id="27" value="&lt;span&gt;&lt;font 
face=&quot;Lucida Console&quot;&gt;REVOKED&lt;/font&gt;&lt;/span
 &gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;" 
parent="1" source="23" target="28" edge="1"><mxGeometry x="-0.04" y="15" 
relative="1" as="geometry"><mxPoint x="582" y="315" as="targetPoint"/><Array 
as="points"/><mxPoint as="offset"/></mxGeometry></mxCell><mxCell id="23" 
value="Status?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="366" y="265" width="95" height="60" 
as="geometry"/></mxCell><mxCell id="30" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=1;entryY=0.5;exitX=0.5;exitY=1;"
 parent="1" source="28" target="22" edge="1"><mxGeometry relative="1" 
as="geometry"><mxPoint x="637" y="435" as="targetPoint"/><Array 
as="points"><mxPoint x="668" y="1067"/></Array></mxGeometry></mxCell><mxCell 
id="28" value="User is Revoked" style="whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="611" y="275" width="114" height="40" 
as="geometry"/></mxCell><mxCell id="32" value="" style="edgeStyle=orthog
 onalEdgeStyle;rounded=0;html=1;" parent="1" source="31" target="14" 
edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell id="31" 
value="Read Access Number&lt;div&gt;from end user&amp;nbsp;&lt;/div&gt;" 
style="whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry x="346" 
y="371" width="136" height="40" as="geometry"/></mxCell><mxCell id="39" 
value="&lt;font face=&quot;Lucida Console&quot;&gt;OK&lt;/font&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" parent="1" source="36" 
target="22" edge="1"><mxGeometry relative="1" as="geometry"/></mxCell><mxCell 
id="41" value="&lt;span&gt;&lt;font face=&quot;Lucida 
Console&quot;&gt;INCORRECT_PIN&lt;/font&gt;&lt;/span&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" parent="1" source="36" 
target="40" edge="1"><mxGeometry x="-0.08" y="-12" relative="1" 
as="geometry"><mxPoint as="offset"/></mxGeometry></mxCell><mxCell id="52" 
value="&lt;span&gt;&lt;font face=&quot;Lucida 
Console&quot;&gt;INCORRECT_ACCESS_NU
 MBER&lt;/font&gt;&lt;/span&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=1;entryY=0.5;exitX=1;exitY=0.5;"
 edge="1" parent="1" source="36" target="31"><mxGeometry x="-0.7878" y="13" 
relative="1" as="geometry"><mxPoint x="561" y="892.5" as="targetPoint"/><Array 
as="points"><mxPoint x="640" y="893"/><mxPoint x="640" 
y="391"/></Array><mxPoint as="offset"/></mxGeometry></mxCell><mxCell id="36" 
value="Status?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="366" y="860" width="95" height="65" 
as="geometry"/></mxCell><mxCell id="43" value="&lt;font face=&quot;Lucida 
Console&quot;&gt;REGISTERED&lt;/font&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;" 
parent="1" source="40" target="19" edge="1"><mxGeometry x="-0.5393" 
relative="1" as="geometry"><mxPoint x="218.5" y="760" as="targetPoint"/><Array 
as="points"><mxPoint x="219" y="690"/></Array><mxPoint 
as="offset"/></mxGeometry></mxCell><mxCell id="48" value="&lt;
 font face=&quot;Lucida Console&quot;&gt;BLOCKED&lt;/font&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;" 
parent="1" source="40" target="46" edge="1"><mxGeometry relative="1" 
as="geometry"><Array as="points"/></mxGeometry></mxCell><mxCell id="40" 
value="User State?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" 
vertex="1"><mxGeometry x="171" y="860" width="95" height="65" 
as="geometry"/></mxCell><mxCell id="50" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;exitX=0.5;exitY=1;"
 parent="1" source="46" target="22" edge="1"><mxGeometry relative="1" 
as="geometry"><mxPoint x="219" y="1117" as="targetPoint"/><Array 
as="points"><mxPoint x="219" y="1067"/></Array></mxGeometry></mxCell><mxCell 
id="46" value="User is Blocked&lt;div&gt;(need to re-register)&lt;/div&gt;" 
style="whiteSpace=wrap;html=1;" parent="1" vertex="1"><mxGeometry x="159" 
y="977" width="120" height="40" as="geometry"/></mxCell></root></mxGraphModel>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/a9e2bcb9/M-Pin
 SDK - Registration flow.png
----------------------------------------------------------------------
diff --git a/M-Pin SDK - Registration flow.png b/M-Pin SDK - Registration 
flow.png
new file mode 100644
index 0000000..460f6f9
Binary files /dev/null and b/M-Pin SDK - Registration flow.png differ

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/a9e2bcb9/M-Pin
 SDK - Registration flow.xml
----------------------------------------------------------------------
diff --git a/M-Pin SDK - Registration flow.xml b/M-Pin SDK - Registration 
flow.xml
new file mode 100644
index 0000000..fdf50b7
--- /dev/null
+++ b/M-Pin SDK - Registration flow.xml 
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mxGraphModel dx="1050" dy="636" grid="1" gridSize="10" guides="1" 
tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" 
pageWidth="826" pageHeight="1169" background="#ffffff" math="0"><root><mxCell 
id="0"/><mxCell id="1" parent="0"/><mxCell id="41519c7962ced28-4" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" edge="1" parent="1" 
source="41519c7962ced28-1" target="41519c7962ced28-2"><mxGeometry relative="1" 
as="geometry"/></mxCell><mxCell id="41519c7962ced28-1" value="Start" 
style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry 
x="379" y="90" width="70" height="40" as="geometry"/></mxCell><mxCell 
id="41519c7962ced28-8" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;" 
edge="1" parent="1" source="41519c7962ced28-2" 
target="41519c7962ced28-6"><mxGeometry relative="1" as="geometry"><mxPoint 
x="405.5" y="330" as="targetPoint"/><Array 
as="points"/></mxGeometry></mxCell><mxCell id="41519c7962ced28-2" va
 lue="&lt;font face=&quot;Lucida Console&quot;&gt;MakeNewUser&lt;/font&gt;" 
style="whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry x="366" 
y="180" width="95" height="40" as="geometry"/></mxCell><mxCell 
id="41519c7962ced28-10" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" edge="1" parent="1" 
source="41519c7962ced28-6" target="41519c7962ced28-9"><mxGeometry relative="1" 
as="geometry"/></mxCell><mxCell id="41519c7962ced28-6" value="&lt;font 
face=&quot;Lucida Console&quot;&gt;StartRegistration&lt;/font&gt;" 
style="whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry x="347" 
y="270" width="133" height="40" as="geometry"/></mxCell><mxCell 
id="41519c7962ced28-13" value="&lt;div&gt;&lt;span&gt;&lt;font 
face=&quot;Lucida 
Console&quot;&gt;STARTED_REGISTRATION&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;/div&gt;"
 style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;" 
edge="1" parent="1" source="41519c7962ced28-9" target="41519c7962ced28-11"><m
 xGeometry x="-0.1333" y="15" relative="1" as="geometry"><mxPoint x="582" 
y="405" as="targetPoint"/><Array as="points"><mxPoint x="617" 
y="405"/></Array><mxPoint as="offset"/></mxGeometry></mxCell><mxCell 
id="41519c7962ced28-16" value="&lt;code&gt;&lt;font face=&quot;Lucida 
Console&quot;&gt;ACTIVATED&lt;/font&gt;&lt;/code&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" edge="1" parent="1" 
source="41519c7962ced28-9" target="41519c7962ced28-15"><mxGeometry x="0.0139" 
y="-18" relative="1" as="geometry"><mxPoint x="18" y="-18" 
as="offset"/></mxGeometry></mxCell><mxCell id="41519c7962ced28-9" value="If 
returned&lt;div&gt;Status is OK,&amp;nbsp;&lt;span style=&quot;line-height: 
1.2&quot;&gt;Check&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span 
style=&quot;line-height: 1.2&quot;&gt;User State&lt;/span&gt;&lt;/div&gt;" 
style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry 
x="345" y="360" width="137" height="90" as="geometry"/></mxCell><mxCell 
id="41519c7962ced28-
 18" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.75;entryY=0;exitX=0.5;exitY=1;"
 edge="1" parent="1" source="41519c7962ced28-11" 
target="41519c7962ced28-15"><mxGeometry relative="1" as="geometry"><mxPoint 
x="617" y="590" as="targetPoint"/><Array as="points"><mxPoint x="617" 
y="520"/><mxPoint x="450" y="520"/></Array></mxGeometry></mxCell><mxCell 
id="41519c7962ced28-11" value="Wait for user to confirm identity" 
style="whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry x="560" 
y="450" width="114" height="40" as="geometry"/></mxCell><mxCell 
id="41519c7962ced28-20" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" edge="1" parent="1" 
source="41519c7962ced28-15" target="41519c7962ced28-19"><mxGeometry 
relative="1" as="geometry"/></mxCell><mxCell id="41519c7962ced28-15" 
value="&lt;font face=&quot;Lucida 
Console&quot;&gt;ConfirmRegistration&lt;/font&gt;" 
style="whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry x="342" 
y="545" width
 ="144" height="40" as="geometry"/></mxCell><mxCell id="41519c7962ced28-22" 
value="&lt;span&gt;&lt;font face=&quot;Lucida 
Console&quot;&gt;IDENTITY_NOT_VERIFIED&lt;/font&gt;&lt;/span&gt;" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.75;entryY=0;exitX=1;exitY=0.5;"
 edge="1" parent="1" source="41519c7962ced28-19" 
target="41519c7962ced28-11"><mxGeometry x="-0.6526" y="15" relative="1" 
as="geometry"><mxPoint x="583" y="695" as="targetPoint"/><Array 
as="points"><mxPoint x="710" y="660"/><mxPoint x="710" y="410"/><mxPoint 
x="646" y="410"/></Array><mxPoint as="offset"/></mxGeometry></mxCell><mxCell 
id="41519c7962ced28-24" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" edge="1" parent="1" 
source="41519c7962ced28-19" target="41519c7962ced28-23"><mxGeometry 
relative="1" as="geometry"/></mxCell><mxCell id="41519c7962ced28-19" 
value="Status?" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" 
parent="1"><mxGeometry x="345" y="615" width="137" height="90" as="g
 eometry"/></mxCell><mxCell id="41519c7962ced28-26" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;exitX=0.5;exitY=1;"
 edge="1" parent="1" source="41519c7962ced28-23" 
target="41519c7962ced28-25"><mxGeometry relative="1" as="geometry"><Array 
as="points"/></mxGeometry></mxCell><mxCell id="41519c7962ced28-23" value="Read 
Secret (PIN)&lt;div&gt;from end user&lt;/div&gt;" 
style="whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry x="354" 
y="750" width="120" height="40" as="geometry"/></mxCell><mxCell 
id="41519c7962ced28-29" value="" 
style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;" 
edge="1" parent="1" source="41519c7962ced28-25" 
target="41519c7962ced28-27"><mxGeometry relative="1" as="geometry"><mxPoint 
x="413.5" y="1000" as="targetPoint"/><Array 
as="points"/></mxGeometry></mxCell><mxCell id="41519c7962ced28-25" 
value="&lt;font face=&quot;Lucida 
Console&quot;&gt;FinishRegistration&lt;/font&gt;" style="whiteSpace=wrap;htm
 l=1;" vertex="1" parent="1"><mxGeometry x="342" y="848" width="143" 
height="40" as="geometry"/></mxCell><mxCell id="41519c7962ced28-27" value="End" 
style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry 
x="379" y="944.5999999999999" width="70" height="40" 
as="geometry"/></mxCell></root></mxGraphModel>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/a9e2bcb9/Mobile-SDK-Architecture.png
----------------------------------------------------------------------
diff --git a/Mobile-SDK-Architecture.png b/Mobile-SDK-Architecture.png
new file mode 100644
index 0000000..303021c
Binary files /dev/null and b/Mobile-SDK-Architecture.png differ

http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/a9e2bcb9/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 44433b4..93932d0 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,370 @@
-# Mobile SDK core 
+# Apache Milagro Mobile SDK Core
+
+## Architecture and API
+
+### System Overview
+The Mobile SDK is a software library that allows mobile application developers 
to use the Apache Milagro authentication scheme for authenticating their 
end-users. It is a "native" library which contains native API for each platform:
+- Java API for Android
+- Objective-C API for iOS
+- C# API for Windows Phone. 
+
+The SDK implements a Client in the Apache Milagro authentication scheme. It is 
divided into three layers:
+* Crypto
+* Core
+* Platform Adaptation
+
+#### Crypto
+
+The Crypto layer performs all the cryptographic operations required during the 
Milagro Registration and Authentication process. It is currently based on the 
_Apache Milagro Crypto_ library. A Trusted Execution Environment (TEE) may be 
available on some Android platforms (mainly on Samsung devices). The TEE allows 
for hardware-secured execution of sensitive code and storage of sensitive data. 
The Mobile SDK is designed in such a way that when the TEE is present, the 
Crypto code might run on it allowing sensitive data to be stored on it. Thus, 
two variants of Crypto layer are made available, _Non-TEE Crypto_ and _TEE 
Crypto_. They provide the same API towards the Core layer and so should be 
interchangeable.
+
+The Apache Milagro Crypto is a C library which the Non-TEE Crypto wraps with 
platform-agnostic C++ code.
+
+#### Core
+
+The Core layer implements the logic and flow of the Apache Milagro 
Authentication Platform. It is written in C++ and is platform-agnostic. As it 
is not solely able to perform certain tasks, such as storing data on the 
device, or making HTTP requests, it invokes the _Platform Adaptation_ layer 
through interfaces provided during the Core initialization, to do them.
+
+#### Platform Adaptation
+
+This layer is implemented separately for every platform, since it is the only 
platform-specific component in the SDK. It provides a thin adaptation layer for 
the Core's C++ API to the native languages, Java, Objective-C or C#, for the 
different Mobile Platforms. It also provides platform-specific implementation 
of Secure and Non-Secure Storage and HTTP Requests.
+
+![alt text](Mobile-SDK-Architecture.png)
+
+For the platform-specific API's see:
+* [Android SDK 
API](https://github.com/apache/incubator-milagro-mfa-sdk-android)
+* [iOS SDK API](https://github.com/apache/incubator-milagro-mfa-sdk-ios)
+* [Windows Phone SDK 
API](https://github.com/apache/incubator-milagro-mfa-sdk-wp)
+
+### Core API
+
+The Core layer is the central part of the Apache Milagro SDK. It implements 
the functionality of a Milagro Client and drives the communication with the 
Milagro MFA Services. The SDK Core (and Crypto) are implemented in a portable 
way, using C/C++ programming languages, to enable them to be compiled for 
different platforms such as a mobile or a desktop one. Most of the platforms 
provide a native API to make HTTP requests and store data. The Core utilizes 
the services on the specific platform it was compiled to, and runs on top of 
them. Hence, it works with Interfaces for those platform-specific services, as 
they are implemented at the _Platform Adaptation Layer_. 
+
+The interfaces are:
+
+* `IHttpRequest` - for making HTTP requests
+* `IStorage`     - for storing data on the device
+* `IContext`     - for grouping the rest of the interfaces into a single bundle
+
+Although the SDK Core API (part of it) is the de-facto SDK API, it is not 
exposed to the application developer. It is an internal API to the Platform 
Adaptation Layer, which presents the SDK API to the application in a way that 
is native to the platform.
+
+#### HTTP Request Interface (`IHttpRequest`)
+The Core uses this interface to make HTTP requests. It should be implemented 
in the Platform Adaptation Layer. The Core creates an HTTP Request object via 
`IContext::CreateHttpRequest()` method and when done, releases the request via 
`IContext::ReleaseHttpRequest()`.
+
+##### `virtual void SetHeaders(const StringMap& headers);`
+This method sets the headers for the HTTP Request. The headers are passed in 
the `headers` key/value map, which is a standard `std::map<std::string, 
std::string>` object. This method should be called prior to executing the HTTP 
Request.
+
+##### `virtual void SetQueryParams(const StringMap& queryParams);`
+This method sets the query parameters for the HTTP Request. The query 
parameters are passed in the `queryParams` key/value map, which is a standard 
`std::map<std::string, std::string>` object. This method is called prior to 
executing the HTTP Request.
+
+##### `virtual void SetContent(const String& data);`
+This method sets the content (the data) of the HTTP Request. It is passed in 
the `data` parameter as a string. This method is called prior to executing the 
HTTP Request.
+
+##### `virtual void SetTimeout(int seconds);`
+This method sets a timeout for the HTTP Request. The timeout is set in 
`seconds`. If not set, the timeout is expected to be infinite. This method is 
called prior to executing the HTTP Request.
+
+##### `virtual bool Execute(Method method, const String& url);`
+This method executes the HTTP Request with the provided `method` and to the 
given `url`. The `Method` enumerator is defined as follows:
+```c++
+enum Method
+{
+    GET,
+    POST,
+    PUT,
+    DELETE,
+    OPTIONS,
+    PATCH
+};
+```
+The request is made with the previously set headers, query parameters and 
data. If the HTTP request was successfully executed, and a response received, 
the return value will be `true`. If the execution failed, the return value 
would be `false`.<br/>
+**NOTE** that a non-2xx HTTP response does not mean that the request has 
failed, but that it succeeded while the return status code was not a 2xx HTTP 
response.
+If the `Execute()` request failed, the `GetExecuteErrorMessage()` will return 
more information on the reason for the failure.
+
+##### `virtual const String& GetExecuteErrorMessage() const;`
+Returns an error message describing the failure of a preceding `Execute()` 
request.
+
+##### `virtual int GetHttpStatusCode() const;`
+Returns the status code received in response to the preceding successfully 
executed HTTP request.
+
+##### `virtual const StringMap& GetResponseHeaders() const;`
+Returns the headers received in response to the preceding successfully 
executed HTTP request. The headers are returned in a key/value map, which is a 
standard `std::map<std::string, std::string>` object.
+
+##### `virtual const String& GetResponseData() const;`
+Returns the data received as a response to the preceding successfully executed 
HTTP request. The data is returned as a string.
+
+#### Storage Interface (`IStorage`)
+The Core uses this interface to store data on the specific platform. As 
different platforms provide different storage options, the implementation of 
the interface should be part of the Platform Adaptation Layer. There are two 
kinds of storages that the Core uses, Secure and Non-secure. In the Secure 
Storage, the Core stores the _regOTT_ (during registration) and _M-Pin Token_ 
for every user that is registered through the device. In the Non-Secure 
Storage, the Core stores all non-sensitive data, like cached Time Permits. The 
`IContext` provides the interface to the correct Storage via the 
`IContext::GetStorage(IStorage::Type)` method.
+
+##### `virtual bool SetData(const String& data);`
+This method sets/writes the whole storage data. The data is provided in the 
data parameter, as a string. The return value is `true` on success or `false` 
on failure. If the method fails, further information regarding the error can be 
obtained through the `GetErrorMessage()` method.
+
+##### `virtual bool GetData(OUT String& data);`
+This method gets/reads the whole storage data. The data is returned in the 
`data` parameter, as a string. The return value is `true` on success or `false` 
on failure. If the method fails, further information regarding the error can be 
obtained through the `GetErrorMessage()` method.
+
+##### `virtual const String& GetErrorMessage() const;`
+Returns the error from the preceding failed `GetData()` or `SetData()` methods.
+
+#### Context Interface (`IContext`)
+The Context Interface "bundles" the rest of the interfaces. This is the only 
interface that is provided to the Core where the other interfaces are 
used/accessed through it. 
+
+##### `virtual IHttpRequest* CreateHttpRequest() const;`
+This request creates a new HTTP request instance that conforms with 
`IHttpRequest`, and returns a pointer to it. The Core calls 
`CreateHttpRequest()` when it needs to make an HTTP request. After receiving a 
pointer to such an instance, the Core sets the needed headers, query parameters 
and data, and then executes the request. The Core will then check for the 
status code, the headers, the data of the response, and will finally release 
the HTTP request.<br/>
+
+**NOTE** that the HTTP request instance should remain "alive" until calling 
`ReleaseHttpRequest()`.<br/>
+**NOTE** As the Core might create two or more HTTP request instances in 
parallel, the implementation should not use global or local (stack) HTTP 
request objects.
+
+##### `virtual void ReleaseHttpRequest(IN IHttpRequest* request) const;`
+This request destroys/releases a previously created HTTP request instance. The 
Core calls `CreateHttpRequest()` when it needs to make an HTTP request. After 
receiving a pointer to such an instance, the Core sets the needed headers, 
query parameters and data, and then executes the request. The Core checks for 
the status code, the headers, the data of the response, and finally releases 
the HTTP request.
+
+**NOTE** that the HTTP request instance should remain "alive" until calling 
`ReleaseHttpRequest()`.<br/>
+**NOTE** Also, as the Core might create two or more HTTP request instances in 
parallel, the implementation should not use global or local (stack) HTTP 
request objects.
+
+##### `virtual IStorage* GetStorage(IStorage::Type type) const;`
+This method returns a pointer to the storage implementation, which conforms to 
`IStorage`. There are two storage types, Secure and Non-Secure, where you can 
pass your desired storage type as a parameter. The `IStorage::Type` enumerator 
is defined as follows:
+```c++
+enum Type
+{
+    SECURE,
+    NONSECURE
+};
+```
+##### `virtual CryptoType GetMPinCryptoType() const;`
+
+This method provides information regarding the supported Crypto Type on the 
specific platform. Currently, this method could return a different value than 
Non-TEE Crypto, only on an Android platform. Other platforms will always return 
a Non-TEE Crypto value. On an Android, the Platform Adaptation needs to check 
if TEE is supported, and then return TEE or Non-TEE Crypto type accordingly. 
+The `CryptoType` enumerator is defined as follows:
+```c++
+enum CryptoType
+{
+    CRYPTO_TEE,
+    CRYPTO_NON_TEE
+};
+```
+
+#### Main Core API (`MPinSDK`)
+The `MPinSDK` is the main SDK Core class. In order to use the Core, one should 
create an instance of the `MPinSDK` class and initialize it. Most of the 
methods return a `MPinSDK::Status` object, which is defined as follows:
+
+```c++
+class Status
+{
+public:
+    enum Code
+    {
+        OK,
+        PIN_INPUT_CANCELLED,     // Local error, returned when a user cancels 
entering a pin
+        CRYPTO_ERROR,            // Local error in crypto functions
+        STORAGE_ERROR,           // Local storage related error
+        NETWORK_ERROR,           // Local error - unable to connect to remote 
server (no internet, or invalid server/port)
+        RESPONSE_PARSE_ERROR,    // Local error - unable to parse json 
response from remote server (invalid json or unexpected json structure)
+        FLOW_ERROR,              // Local error - improper MPinSDK class usage
+        IDENTITY_NOT_AUTHORIZED, // Remote error - remote server refuses user 
registration or authentication
+        IDENTITY_NOT_VERIFIED,   // Remote error - remote server refuses user 
registration because identity is not verified
+        REQUEST_EXPIRED,         // Remote error - register/authentication 
request expired
+        REVOKED,                 // Remote error - unable to get time permit 
(probably the user is temporarily suspended)
+        INCORRECT_PIN,           // Remote error - user entered wrong pin
+        INCORRECT_ACCESS_NUMBER, // Remote/local error - wrong access number 
(checksum failed or RPS returned 412)
+        HTTP_SERVER_ERROR,       // Remote error, when the error does not 
apply to any of the above - the remote server returned internal server error 
status (5xx)
+        HTTP_REQUEST_ERROR,      // Remote error, where the error does not 
apply to any of the above - invalid data sent to server, the remote server 
returned 4xx error status
+        BAD_USER_AGENT,          // Remote error - user agent not supported
+        CLIENT_SECRET_EXPIRED    // Remote error - re-registration required 
because server master secret expired
+    };
+
+    Code GetStatusCode() const;
+    const String& GetErrorMessage() const;
+    bool operator==(Code statusCode) const;
+    bool operator!=(Code statusCode) const;
+
+    ...
+};
+```
+The methods that return `Status`, will always return `Status::OK` if 
successful. Many methods expect the provided `User` object to be in a certain 
state, and if it is not, the method will return `Status::FLOW_ERROR`
+
+##### `Status Init(const StringMap& config, IN IContext* ctx);`
+##### `Status Init(const StringMap& config, IN IContext* ctx, const StringMap& 
customHeaders);`
+This method initializes the `MPinSDK` instance. It receives a map of 
configuration parameters and a pointer to a [Context 
Interface](#Context-Interface). The configuration map is a key-value map into 
which different configuration options can be inserted. This is a flexible way 
of passing configurations into the Core, as the method parameters will not 
change when new configuration parameters are added. 
+Unsupported parameters will be ignored. Currently, the Core recognizes the 
following parameters:
+
+* `backend` - the URL of the Milagro MFA back-end service (Mandatory)
+* `rpsPrefix` - the prefix that should be added for requests to the RPS 
(Optional). The default value is `"rps"`.
+
+The `customHeaders` parameter is optional and allows the caller to pass 
additional map of custom headers, which will be added to any HTTP request that 
the SDK executes.
+
+Example:
+```c++
+MPinSDK::StringMap config;
+config["backend"] = "http://ec2-54-77-232-113.eu-west-1.compute.amazonaws.com";;
+ 
+MPinSDK* sdk = new MPinSDK;
+MPinSDK::Status s = sdk->Init( config, Context::Instance() );
+```
+
+##### `void Destroy();`
+This method clears the `MPinSDK` instance and releases any allocated data by 
it. After calling this method, one should use `Init()` again in order to re-use 
the `MPinSDK` instance.
+
+##### `Status TestBackend(const String& server, const String& rpsPrefix = 
"rps") const;`
+This method will test whether `server` is a valid back-end URL by trying to 
retrieve Client Settings from it.
+Optionally, a custom RPS prefix might be specified if it was customized at the 
back-end and is different than the default `"rps"`.
+If the back-end URL is a valid one, the method will return `Status::OK`.
+
+##### `Status SetBackend(const String& server, const String& rpsPrefix = 
"rps");`
+This method will change the currently configured back-end in the Core.
+Initially the back-end might be set through the `Init()` method, but then it 
might be change using this method.
+`server` is the new back-end URL that should be used.
+Optionally, a custom RPS prefix might be specified if it was customized at the 
back-end and is different than the default `"rps"`.
+If successful, the method will return `Status::OK`. 
+
+##### `UserPtr MakeNewUser(const String& id, const String& deviceName = "") 
const;`
+This method creates a new `User` object. The User object represents an 
end-user of the Milagro authentication. The user has its own unique identity, 
which is passed as the id parameter to this method. Additionally, an optional 
`deviceName` might be specified. The _Device Name_ is passed to the RPA, which 
might store it and use it later to determine which _M-Pin ID_ is associated 
with this device. The returned value is of type `UserPtr`, which is a reference 
counting shared pointer to the newly created `User` instance. The User class 
itself looks like this:
+```c++
+class User
+{
+public:
+    enum State
+    {
+        INVALID,
+        STARTED_REGISTRATION,
+        ACTIVATED,
+        REGISTERED,
+        BLOCKED
+    };
+
+    const String& GetId() const;
+    const String& GetBackend() const;
+    State GetState() const;
+
+private:
+    ....
+};
+```
+The newly created user is in the `INVALID` state.
+The `User` class is defined in the namespace of the `MPinSDK` class.
+
+##### `void DeleteUser(INOUT UserPtr user);`
+This method deletes a user from the users list that the SDK maintains. All the 
user data including its _M-Pin ID_, its state and _M-Pin Token_ will be 
deleted. A new user with the same identity can be created later with the 
`MakeNewUser()` method.
+
+##### `Status ListUsers(OUT std::vector<UserPtr>& users) const;`
+This method populates the provided vector with all the users that are 
associated with the currently set backend. Different users might be in 
different states, reflecting their registration status.
+The method will return `Status::OK` on success and `Status::FLOW_ERROR` if no 
backend is set through the `Init()` or `SetBackend()` methods.
+
+##### `Status ListUsers(OUT std::vector<UserPtr>& users, const String& 
backend) const;`
+This method populates the provided vector with all the users that are 
associated with the provided `backend`. Different users might be in different 
states, reflecting their registration status.
+The method will return `Status::OK` on success and `Status::FLOW_ERROR` if the 
SDK was not initialized.
+
+##### `Status ListAllUsers(OUT std::vector<UserPtr>& users) const;`
+This method populates the provided vector with all the users associated with 
all the backends know to the SDK. Different users might be in different states, 
reflecting their registration status.
+The user association to a backend could be retrieved through the 
`User::GetBackend()` method.
+The method will return `Status::OK` on success and `Status::FLOW_ERROR` if the 
SDK was not initialized.
+
+##### `Status ListBackends(OUT std::vector<String>& backends) const;`
+This method will populate the provided vector with all the backends known to 
the SDK.
+The method will return `Status::OK` on success and `Status::FLOW_ERROR` if the 
SDK was not initialized.
+
+##### `Status GetSessionDetails(const String& accessCode, OUT SessionDetails& 
sessionDetails);`
+This method could be optionally used to retrieve details regarding a browser 
session when the SDK is used to authenticate users to an online service, such 
as the _MIRACL MFA Platform_.
+In this case an `accessCode` is transferred to the mobile device out-of-band 
e.g. via scanning a graphical code. The code is then provided to this method to 
get the session details.
+This method will also notify the backend that the `accessCode` was retrieved 
from the browser session.
+The returned `SessionDetails` look as follows:
+```c++
+class SessionDetails
+{
+public:
+    void Clear();
+
+    String prerollId;
+    String appName;
+    String appIconUrl;
+};
+```
+During the online browser session an optional user identity might be provided 
meaning that this is the user that wants to register/authenticate to the online 
service.
+The `prerollId` will carry that user ID, or it will be empty if no such ID was 
provided.
+`appName` is the name of the web application to which the service will 
authenticate the user.
+`appIconUrl` is the URL from which the icon for web application could be 
downloaded.
+
+
+##### `Status StartRegistration(INOUT UserPtr user, const String& activateCode 
= "", const String& userData = "");`
+This method initializes the registration for a User that has already been 
created. The Core starts the Milagro Setup flow, sending the necessary requests 
to the back-end service. The State of the User instance will change to 
`STARTED_REGISTRATION`. The status will indicate whether the operation was 
successful or not. During this call, an _M-Pin ID_ for the end-user will be 
issued by the RPS and stored within the user object. The RPA could also start a 
user identity verification procedure, by sending a verification e-mail.
+
+The optional `activateCode` parameter might be provided if the registration 
process requires such. In cases when the user verification is done through a 
_One-Time-Code_ (OTC) or through an SMS that carries such code, this OTC should 
be passed as the `activateCode` parameter. In those cases, the identity 
verification should be completed instantly and the User State will be set to 
`ACTIVATED`.
+ 
+Optionally, the application might pass additional `userData` which might help 
the RPA to verify the user identity. The RPA might decide to verify the 
identity without starting a verification process. In this case, the `Status` of 
the call will still be `Status::OK`, but the User State will be set to 
`ACTIVATED`.
+
+##### `Status RestartRegistration(INOUT UserPtr user, const String& userData = 
"");`
+This method re-initializes the registration process for a user, where 
registration has already started. The difference between this method and 
`StartRegistration()` is that it will not generate a new _M-Pin ID_, but will 
use the one that was already generated. Besides that, the methods follow the 
same procedures, such as getting the RPA to re-start the user identity 
verification procedure of sending a verification email to the user.
+
+The application could also pass additional `userData` to help the RPA to 
verify the user identity. The RPA might decide to verify the identity without 
starting a verification process. In this case, the `Status` of the call will 
still be `Status::OK`, but the User State will be set to `ACTIVATED`.
+
+##### `Status ConfirmRegistration(INOUT UserPtr user, const String& 
pushMessageIdentifier = "");`
+This method allows the application to check whether the user identity 
verification process has been finalized or not. The provided `user` object is 
expected to be either in the `STARTED_REGISTRATION` state or in the `ACTIVATED` 
state. The latter is possible if the RPA activated the user immediately with 
the call to `StartRegistration()` and no verification process was started. 
During the call to `ConfirmRegistration()` the SDK will make an attempt to 
retrieve _Client Key_ for the user. This attempt will succeed if the user has 
already been verified/activated but will fail otherwise. The method will return 
`Status::OK` if the Client Key has been successfully retrieved and 
`Status::IDENTITY_NOT_VERIFIED` if the identity has not been verified yet. If 
the method has succeeded, the application is expected to get the desired 
PIN/secret from the end-user and then call `FinishRegistration()`, and provide 
the PIN.
+
+**Note** Using the optional parameter `pushMessageIdentifier`, the application 
can provide a platform specific identifier for sending _Push Messages_ to the 
device. Such push messages might be utilized as an alternative to the _Access 
Number/Code_, as part of the authentication flow.
+
+##### `Status FinishRegistration(INOUT UserPtr user, const String& pin)`
+This method finalizes the user registration process. It extracts the _M-Pin 
Token_ from the _Client Key_ for the provided `pin` (secret), and then stores 
the token in the secure storage. On successful completion, the User state will 
be set to `REGISTERED` and the method will return `Status::OK`
+
+##### `Status StartAuthentication(INOUT UserPtr user, const String& accessCode 
= "");`
+This method starts the authentication process for a given `user`. It attempts 
to retrieve the _Time Permits_ for the user, and if successful, will return 
`Status::OK`.
+If they cannot be retrieved, the method will return `Status::REVOKED`. If this 
method is successfully completed, the app should read the PIN/secret from the 
end-user and call one of the `FinishAuthentication()` variants to authenticate 
the user.
+
+Optionally, an `accessCode` could be provided. This code is retrieved 
out-of-band from a browser session when the user has to be authenticated to an 
online service, such as the _MIRACL MFA Platform_.
+When this code is provided, the SDK will notify the service that 
authentication associated with the given `accessCode` has started for the 
provided user. 
+
+
+##### `Status CheckAccessNumber(const String& accessNumber);`
+This method is used only when a user needs to be authenticated to a remote 
(browser) session, using _Access Number_. The access numbers might have a 
check-sum digit in them and this check-sum needs to be verified on the client 
side, in order to prevent calling the back-end with non-compliant access 
numbers. The method will return `Status::OK` if successful, and 
`Status::INCORRECT_ACCESS_NUMBER` if not successful.
+
+##### `Status FinishAuthentication(INOUT UserPtr user, const String& pin);`
+##### `Status FinishAuthentication(INOUT UserPtr user, const String& pin, OUT 
String& authResultData);`
+This method performs end-user authentication where the `user` to be 
authenticated is passed as a parameter, along with his `pin` (secret).
+The method performs the authentication against the _Milagro MFA Server_ using 
the provided PIN and the stored _M-Pin Token_, and then logs into the RPA.
+The RPA responds with the authentication _User Data_ which is returned to the 
application through the `authResultData` parameter.
+If successful, the returned status will be `Status::OK`, and if the 
authentication fails, the return status would be `INCORRECT_PIN`.
+After the 3rd (configurable in the RPS) unsuccessful authentication attempt, 
the method will return `Status::INCORRECT_PIN` and the User State will be set 
to `BLOCKED`.
+
+
+##### `Status FinishAuthenticationOTP(INOUT UserPtr user, const String& pin, 
OUT OTP& otp);`
+This method performs end-user authentication for an OTP. The authentication 
process is similar to `FinishAuthentication()`, but the RPA issues an OTP 
instead of logging the user into the application. The returned status is 
analogical to the `FinishAuthentication()` method, but, in addition to that, an 
`OTP` structure is returned. The `OTP` structure looks like this:
+```c++
+class OTP
+{
+public:
+    String otp;
+    long expireTime;
+    int ttlSeconds;
+    long nowTime;
+    Status status;
+};
+```
+The `otp` string is the issued OTP.
+The `expireTime` is the Milagro MFA system time when the OTP will expire.
+The `ttlSeconds` is the expiration period in seconds.
+The `nowTime` is the current Milagro MFA system time.
+`Status` is the status of the OTP generation. The status will be `Status::OK` 
if the OTP was successfully generated, or `Status::FLOW_ERROR` if not.
+
+**NOTE** that OTP might be generated only by RPA that supports that 
functionality, such as the MIRACL M-Pin SSO. Other RPA's might not support OTP 
generation where the `status` inside the returned `otp` structure will be 
`Status::FLOW_ERROR`.
+
+##### `Status FinishAuthenticationAN(INOUT UserPtr user, const String& pin, 
const String& accessNumber);`
+This method authenticates the end-user using an _Access Number_ (also refered 
as _Access Code_), provided by a PC/Browser session. After this authentication, 
the end-user can log into the PC/Browser which provided the Access Number, 
while the authentication itself is done on the Mobile Device. `accessNumber` is 
the Access Number from the browser session. The returned status might be:
+`Status::OK` - Successful authentication.
+`Status::INCORRECT_PIN` - The authentication failed because of incorrect PIN. 
After the 3rd (configurable in the RPS) unsuccessful authentication attempt, 
the method will still return `Status::INCORRECT_PIN` but the User State will be 
set to `BLOCKED`.
+`Status::INCORRECT_ACCESS_NUMBER` - The authentication failed because of 
incorrect Access Number. 
+
+##### `bool CanLogout(IN UserPtr user);`
+This method is used after authentication with an Access Number/Code through 
`FinishAuthenticationAN()`. After such an authentication, the Mobile Device can 
log out the end-user from the Browser session, if the RPA supports that 
functionality. This method checks whether logout information was provided by 
the RPA and the remote (Browser) session can be terminated from the Mobile 
Device. The method will return `true` if the user can be logged-out from the 
remote session, and `false` otherwise.
+
+##### `bool Logout(IN UserPtr user);`
+This method tries to log out the end-user from a remote (Browser) session 
after a successful authentication through `FinishAuthenticationAN()`. Before 
calling this method, it is recommended to ensure that logout data was provided 
by the RPA and that the logout operation can be actually performed. The method 
will return `true` if the logged-out request to the RPA was successful, and 
`false` otherwise.
+
+##### `const char* GetVersion();`
+This method returns a pointer to a null-terminated string with the version 
number of the SDK.
+
+##### `String GetClientParam(const String& key);`
+This method returns the value for a _Client Setting_ with the given key. The 
value is returned as a String always, i.e. when a numeric or a boolean value is 
expected, the conversion should be handled by the application. 
+Client settings that might interest the applications are:
+* `accessNumberDigits` - The number of Access Number digits that should be 
entered by the user, prior to calling `FinishAuthenticationAN()`.
+* `setDeviceName` - Indicator (`true/false`) whether the application should 
ask the user to insert a _Device Name_ and pass it to the `MakeNewUser()` 
method.
+* `appID` - The _App ID_ used by the backend. The App ID is a unique ID 
assigned to each customer or application. It is a hex-encoded long numeric 
value. The App ID can be used only for information purposes and it does not 
affect the application's behavior in any way.
+
+#### Main Flows
+
+##### User Registration
+![*](M-Pin SDK - Registration flow.png)
+
+##### User Authentication to an Online Session
+![*](M-Pin SDK - Authentication to Browser Session flow.png)

Reply via email to