Repository: incubator-milagro-mfa-sdk-core Updated Branches: refs/heads/master a9e2bcb95 -> 5a6c03fa0 (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/5a6c03fa Tree: http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/tree/5a6c03fa Diff: http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/diff/5a6c03fa Branch: refs/heads/master Commit: 5a6c03fa0ace77c3c1ae3e497bdca6f78c31b0a8 Parents: e631fb2 Author: Simeon Aladjem <[email protected]> Authored: Sat Sep 17 14:40:48 2016 +0300 Committer: Simeon Aladjem <[email protected]> Committed: Sat Sep 17 14:40:48 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 | 485 ++++++++++++++++++- 8 files changed, 490 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-milagro-mfa-sdk-core/blob/5a6c03fa/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/5a6c03fa/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="<font face="Lucida Console">StartAuthentication</font>" 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="<code><font face="Lucida Console">OK</font></code>" 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)<div>from end user</div>" 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="<p><code><font face="Lucida Console" style="font-size: 12px">FinishAuthentication</font></code></p>" 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="<span><font face="Lucida Console">REVOKED</font></span>" 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="<font face="Lucida Console">OK</font>" 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="<span><font face="Lucida Console">INCORRECT_PIN</ font></span>" 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="<font face="Lucida Console">REGISTERED</font>" 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="<font face="Lucida Console">BLOCKED</font>" 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<div>(need to re-register)</div>" 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/5a6c03fa/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/5a6c03fa/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="<font face="Lucida Console">StartAuthentication</font>" 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="<code><font face="Lucida Console">OK</font></code>" 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="<font face="Lucida Console">CheckAccessNumber</font>" 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="<span><font face="Lucida Console">INCORRECT_ACCESS_NUMBER</fon t></span><br>" 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="<font face="Lucida Console">OK</font>" 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)<div>from end user</div>" 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="<p><code><font face="Lucida Console" style="font-size: 12px">FinishAuthenticationAN</font></code></p>" 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="<span><font face="Lucida Console">REVOKED</font></span >" 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<div>from end user&nbsp;</div>" 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="<font face="Lucida Console">OK</font>" 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="<span><font face="Lucida Console">INCORRECT_PIN</font></span>" 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="<span><font face="Lucida Console">INCORRECT_ACCESS_NU MBER</font></span>" 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="<font face="Lucida Console">REGISTERED</font>" 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="< font face="Lucida Console">BLOCKED</font>" 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<div>(need to re-register)</div>" 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/5a6c03fa/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/5a6c03fa/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="<font face="Lucida Console">MakeNewUser</font>" 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="<font face="Lucida Console">StartRegistration</font>" 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="<div><span><font face="Lucida Console">STARTED_REGISTRATION</font></span><br></div>" 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="<code><font face="Lucida Console">ACTIVATED</font></code>" 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<div>Status is OK,&nbsp;<span style="line-height: 1.2">Check</span></div><div><span style="line-height: 1.2">User State</span></div>" 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="<font face="Lucida Console">ConfirmRegistration</font>" 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="<span><font face="Lucida Console">IDENTITY_NOT_VERIFIED</font></span>" 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)<div>from end user</div>" 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="<font face="Lucida Console">FinishRegistration</font>" 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/5a6c03fa/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/5a6c03fa/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index 44433b4..d9f29a1 100644 --- a/README.md +++ b/README.md @@ -1 +1,484 @@ -# 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. + + + +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`. + +**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. + +**NOTE** that the HTTP request instance should remain "alive" until calling `ReleaseHttpRequest()`. + +**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()`. + +**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 + + +##### User Authentication to an Online Session +
