Skip to content

Commit

Permalink
Merge pull request #2 from iProov/MOB-1442-Make-example-app-ready
Browse files Browse the repository at this point in the history
  • Loading branch information
emre-sari-iproov authored Feb 29, 2024
2 parents 455e1e4 + 7f9cbe1 commit 14e2e8c
Show file tree
Hide file tree
Showing 8 changed files with 332 additions and 31 deletions.
102 changes: 96 additions & 6 deletions APIClient/APIClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,46 @@ public enum AssuranceType
Liveness
}

public enum ErrorType
{
InvalidImage,
NoToken,
InvalidJSON,
ServerError
}

public class Error: Exception
{
public ErrorType Type { get; }
public string? ServerErrorMessage { get; }

public Error(ErrorType type, string? serverErrorMessage = null)
{
Type = type;
ServerErrorMessage = serverErrorMessage;
}

public override string Message
{
get
{
switch (Type)
{
case ErrorType.InvalidImage:
return "Invalid image";
case ErrorType.NoToken:
return "No token";
case ErrorType.InvalidJSON:
return "Invalid JSON";
case ErrorType.ServerError:
return ServerErrorMessage ?? "unknown";
default:
return base.Message;
}
}
}
}

static class EnumExtensions
{

Expand Down Expand Up @@ -119,17 +159,42 @@ public async Task<string> GetToken(AssuranceType assuranceType, ClaimType type,
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await httpClient.PostAsync($"{baseURL}/claim/{type.toInternalString()}/token", content);
response.EnsureSuccessStatusCode();

var responseContent = await response.Content.ReadAsStringAsync();
var responseDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(responseContent);

return (string)responseDict["token"];
if (responseDict == null)
{
throw new Error(type: ErrorType.InvalidJSON);
}

if (!response.IsSuccessStatusCode)
{
if (responseDict.TryGetValue("error_description", out var serverErrorMessageObj))
{
string serverErrorMessage = (string)serverErrorMessageObj;
throw new Error(type: ErrorType.ServerError, serverErrorMessage: serverErrorMessage);
}

int statusCodeAsInt = (int)response.StatusCode;
throw new Error(ErrorType.ServerError, serverErrorMessage: $"Unexpected status code: {statusCodeAsInt}");
}

if (responseDict.TryGetValue("token", out var tokenObj))
{
string token = (string)tokenObj;
return token;
}

throw new Error(type: ErrorType.NoToken);
}

public async Task<bool> EnrolPhoto(string token, byte[] jpegImage, PhotoSource source)
{
var fileContent = new ByteArrayContent(jpegImage);
ByteArrayContent? fileContent = new ByteArrayContent(jpegImage);
if (fileContent == null)
{
throw new Error(type: ErrorType.InvalidImage);
}

var multipartFormData = new MultipartFormDataContent();
multipartFormData.Add(new StringContent(apiKey), "api_key");
Expand All @@ -143,6 +208,11 @@ public async Task<bool> EnrolPhoto(string token, byte[] jpegImage, PhotoSource s
var responseContent = await response.Content.ReadAsStringAsync();
var responseDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseContent);

if (responseDict == null)
{
throw new Error(type: ErrorType.InvalidJSON);
}

return responseDict.ContainsKey("success") && bool.Parse(responseDict["success"]);
}

Expand All @@ -164,11 +234,26 @@ public async Task<Dictionary<string, object>> Validate(string token, string user
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await httpClient.PostAsync($"{baseURL}/claim/verify/validate", content);
response.EnsureSuccessStatusCode();

var responseContent = await response.Content.ReadAsStringAsync();
var responseDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(responseContent);

if (responseDict == null)
{
throw new Error(type: ErrorType.InvalidJSON);
}

if (!response.IsSuccessStatusCode)
{
if (responseDict.TryGetValue("error_description", out var serverErrorMessageObj))
{
string serverErrorMessage = (string)serverErrorMessageObj;
throw new Error(type: ErrorType.ServerError, serverErrorMessage: serverErrorMessage);
}

int statusCodeAsInt = (int)response.StatusCode;
throw new Error(ErrorType.ServerError, serverErrorMessage: $"Unexpected status code: {statusCodeAsInt}");
}

return responseDict;
}

Expand Down Expand Up @@ -198,6 +283,11 @@ public async Task<string> GetOAuthToken(string username, string password)
var responseContent = await response.Content.ReadAsStringAsync();
var responseDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseContent);

if (responseDict == null)
{
throw new Error(type: ErrorType.InvalidJSON);
}

return responseDict["access_token"];
}
}
Expand Down
1 change: 0 additions & 1 deletion ExampleAppMAUI/AppShell.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
Title="ExampleAppMAUI">

<ShellContent
Title="iProov LA Enrol"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />

Expand Down
8 changes: 6 additions & 2 deletions ExampleAppMAUI/ExampleAppMAUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,13 @@
<ProjectReference Include="..\APIClient\APIClient.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="Resources\Images\custom-back.png" />
<None Remove="Resources\Images\custom_back.png" />
<None Remove="Resources\Images\reload.png" />
<None Remove="Resources\Images\logo.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Images\custom-back.png" />
<MauiImage Include="Resources\Images\custom_back.png" />
<MauiImage Include="Resources\Images\reload.png" />
<MauiImage Include="Resources\Images\logo.png" />
</ItemGroup>
</Project>
158 changes: 142 additions & 16 deletions ExampleAppMAUI/MainPage.xaml
Original file line number Diff line number Diff line change
@@ -1,33 +1,159 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ExampleAppMAUI.MainPage">
x:Class="ExampleAppMAUI.MainPage"
Shell.NavBarIsVisible="false">

<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Label x:Name="SDKversion"/>
<Entry x:Name="UserIdEntry"
Placeholder="Enter text"
/>

<Button
x:Name="GenerateUUIDBtn"
Text="Generate UUID"
Clicked="onGenerateUUID"
/>
<Image x:Name="logoImage"
Source="logo.png"
Margin="0,35,0,10"
MaximumHeightRequest="140"/>

<VerticalStackLayout
Spacing="8"
x:Name="UserIdVerticalStackLayout">

<Label x:Name="UserIdLabel"
Text="User ID"
VerticalTextAlignment="Center"/>

<BoxView
HeightRequest="1"
BackgroundColor="LightGray"/>

<Border StrokeThickness="0">
<FlexLayout Direction="Row" BackgroundColor="White">
<Entry x:Name="UserIdEntry"
FontSize="12"
FontAutoScalingEnabled="True"
FlexLayout.Grow="1"
Text="Enter text"
VerticalTextAlignment="Center"
BackgroundColor="White"
TextColor="Black"/>
<ImageButton x:Name="GenerateUUIDBtn"
HeightRequest="44"
WidthRequest="44"
Clicked="OnGenerateUUID"
Source="reload"
BackgroundColor="White"/>
</FlexLayout>
</Border>
</VerticalStackLayout>

<VerticalStackLayout
Spacing="8"
x:Name="ClaimTypeVerticalStackLayout">

<Label x:Name="selectClaimTypeLabel"
Text="Select claim type"
HorizontalOptions="Start"/>

<BoxView
HeightRequest="1"
BackgroundColor="LightGray"/>

<Border
BackgroundColor="Transparent"
StrokeThickness="0">
<FlexLayout Direction="Row" BackgroundColor="Transparent">
<Button
x:Name="EnrolButton"
FlexLayout.Grow="1"
Text="Enrol"
Clicked="OnEnrolButtonClicked"
HorizontalOptions="Fill"
BackgroundColor="RoyalBlue"
TextColor="White"
WidthRequest="{Binding Path=Width, Source={x:Reference VerifyButton}}"
/>
<BoxView
WidthRequest="8"
BackgroundColor="Transparent"/>
<Button
x:Name="VerifyButton"
FlexLayout.Grow="1"
Text="Verify"
Clicked="OnVerifyButtonClicked"
HorizontalOptions="Fill"
BackgroundColor="DarkGray"
TextColor="White"
/>
</FlexLayout>
</Border>
</VerticalStackLayout>

<VerticalStackLayout
Spacing="8"
x:Name="AssuranceTypeVerticalStackLayout">

<Label x:Name="selectAssuranceTypeLabel"
Text="Select assurance type"
HorizontalOptions="Start"/>

<BoxView
HeightRequest="1"
BackgroundColor="LightGray"/>

<Border
BackgroundColor="Transparent"
StrokeThickness="0">
<FlexLayout Direction="Row" BackgroundColor="Transparent">
<Button
x:Name="GPAButton"
FlexLayout.Grow="1"
Text="GPA"
Clicked="OnGPAButtonClicked"
HorizontalOptions="Fill"
BackgroundColor="RoyalBlue"
TextColor="White"
WidthRequest="{Binding Path=Width, Source={x:Reference VerifyButton}}"
/>
<BoxView
WidthRequest="8"
BackgroundColor="Transparent"/>
<Button
x:Name="LAButton"
FlexLayout.Grow="1"
Text="LA"
Clicked="OnLAButtonClicked"
HorizontalOptions="Fill"
BackgroundColor="DarkGray"
TextColor="White"
/>
</FlexLayout>
</Border>
</VerticalStackLayout>

<ProgressBar
x:Name="ClaimProgress"
IsVisible="false"
Progress="0"
ProgressColor="RoyalBlue"
/>

<Button
x:Name="LaunchEnrolBtn"
Text="Enrol with LA"
x:Name="LaunchButton"
Text="Enrol with GPA"
Clicked="OnLaunchIProov"
HorizontalOptions="Fill" />
HorizontalOptions="Fill"
BackgroundColor="RoyalBlue"
TextColor="White"
Margin="0,20,0,0"
HeightRequest="60"
/>

<Image x:Name="ClaimFrame"/>

<Label x:Name="SDKVersionLabel"
Margin="0,50,0,30"
HorizontalOptions="Center"
/>
</VerticalStackLayout>
</ScrollView>

</ContentPage>

</ContentPage>
Loading

0 comments on commit 14e2e8c

Please sign in to comment.