Skip to content
This repository was archived by the owner on Jun 25, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 39 additions & 29 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:flutter/services.dart';
import 'dart:async';
import 'package:msal_flutter/msal_flutter.dart';


void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
Expand All @@ -12,22 +11,26 @@ class MyApp extends StatefulWidget {
}

class _MyAppState extends State<MyApp> {

static const String _authority = "https://msalfluttertest.b2clogin.com/tfp/msalfluttertest.onmicrosoft.com/B2C_1_sisu";
static const String _authority =
"https://msalfluttertest.b2clogin.com/tfp/msalfluttertest.onmicrosoft.com/B2C_1_sisu";
static const String _clientId = "5913dfb1-7576-451c-a7ea-a7c5a3f8682a";

String _output = 'NONE';

PublicClientApplication pca;

Future<void> _acquireToken() async{
if(pca == null){
pca = await PublicClientApplication.createPublicClientApplication(_clientId, authority: _authority);
Future<void> _acquireToken() async {
if (pca == null) {
pca = await PublicClientApplication.createPublicClientApplication(
_clientId,
authority: _authority);
}

String res;
try{
res = await pca.acquireToken(["https://msalfluttertest.onmicrosoft.com/msalbackend/user_impersonation"]);
try {
res = await pca.acquireToken([
"https://msalfluttertest.onmicrosoft.com/msalbackend/user_impersonation"
]);
} on MsalUserCancelledException {
res = "User cancelled";
} on MsalNoAccountException {
Expand All @@ -36,7 +39,7 @@ class _MyAppState extends State<MyApp> {
res = "invalid config";
} on MsalInvalidScopeException {
res = "Invalid scope";
}on MsalException {
} on MsalException {
res = "Error getting token. Unspecified reason";
}

Expand All @@ -46,14 +49,17 @@ class _MyAppState extends State<MyApp> {
}

Future<void> _acquireTokenSilently() async {
if(pca == null){
pca = await PublicClientApplication.createPublicClientApplication(_clientId, authority: _authority);
if (pca == null) {
pca = await PublicClientApplication.createPublicClientApplication(
_clientId,
authority: _authority);
}

String res;
try
{
res = await pca.acquireTokenSilent(["https://msalfluttertest.onmicrosoft.com/msalbackend/user_impersonation"]);
try {
res = await pca.acquireTokenSilent([
"https://msalfluttertest.onmicrosoft.com/msalbackend/user_impersonation"
]);
} on MsalUserCancelledException {
res = "User cancelled";
} on MsalNoAccountException {
Expand All @@ -62,7 +68,7 @@ class _MyAppState extends State<MyApp> {
res = "invalid config";
} on MsalInvalidScopeException {
res = "Invalid scope";
}on MsalException {
} on MsalException {
res = "Error getting token silently!";
}

Expand All @@ -73,23 +79,25 @@ class _MyAppState extends State<MyApp> {

Future _logout() async {
print("called logout");
if(pca == null){
pca = await PublicClientApplication.createPublicClientApplication(_clientId, authority: _authority);
if (pca == null) {
pca = await PublicClientApplication.createPublicClientApplication(
_clientId,
authority: _authority);
}

print("pca is not null");
String res;
try{
try {
await pca.logout();
res = "Account removed";
} on MsalException {
res = "Error signing out";
} on PlatformException catch (e){
} on PlatformException catch (e) {
res = "some other exception ${e.toString()}";
}

print("setting state");
setState((){
setState(() {
_output = res;
});
}
Expand All @@ -104,13 +112,15 @@ class _MyAppState extends State<MyApp> {
body: Center(
child: Column(
children: <Widget>[
RaisedButton( onPressed: _acquireToken,
child: Text('AcquireToken()'),),
RaisedButton( onPressed: _acquireTokenSilently,
child: Text('AcquireTokenSilently()')),
RaisedButton( onPressed: _logout,
child: Text('Logout')),
Text( _output),
RaisedButton(
onPressed: _acquireToken,
child: Text('AcquireToken()'),
),
RaisedButton(
onPressed: _acquireTokenSilently,
child: Text('AcquireTokenSilently()')),
RaisedButton(onPressed: _logout, child: Text('Logout')),
Text(_output),
],
),
),
Expand Down
27 changes: 0 additions & 27 deletions example/test/widget_test.dart

This file was deleted.

52 changes: 37 additions & 15 deletions lib/src/msal_exception.dart
Original file line number Diff line number Diff line change
@@ -1,39 +1,61 @@
class MsalException implements Exception {
String errorMessage;
MsalException(this.errorMessage);
final String errorMessage;

const MsalException(this.errorMessage);
}

class MsalChangedClientIdException extends MsalException {
MsalChangedClientIdException()
: super(
"Cannot create a client with a new client ID. Only 1 client id supported");
const MsalChangedClientIdException()
: super("Cannot create a client with a new client ID. "
"Only 1 client id supported");

static MsalChangedClientIdException create() =>
const MsalChangedClientIdException();
}

class MsalUserCancelledException extends MsalException {
MsalUserCancelledException() : super("User cancelled login request");
const MsalUserCancelledException() : super("User cancelled login request");

static MsalUserCancelledException create() =>
const MsalUserCancelledException();
}

class MsalNoAccountException extends MsalException {
MsalNoAccountException()
const MsalNoAccountException()
: super("Cannot login silently. No account available");

static MsalNoAccountException create() =>
const MsalNoAccountException();
}

class MsalInvalidConfigurationException extends MsalException {
MsalInvalidConfigurationException(errorMessage) : super(errorMessage);
const MsalInvalidConfigurationException(String errorMessage) : super(errorMessage);

static MsalInvalidConfigurationException create(String errorMessage) =>
MsalInvalidConfigurationException(errorMessage);
}

class MsalInvalidScopeException extends MsalException {
MsalInvalidScopeException() : super("Invalid or no scope");
const MsalInvalidScopeException() : super("Invalid or no scope");

static MsalInvalidScopeException create() =>
const MsalInvalidScopeException();
}

class MsalInitializationException extends MsalException {
MsalInitializationException()
: super(
"Error initializing client. Please ensure correctly configuration supplied");
const MsalInitializationException()
: super("Error initializing client. Please ensure "
"correctly configuration supplied");

static MsalInitializationException create() =>
const MsalInitializationException();
}

class MsalUninitializedException extends MsalException {
MsalUninitializedException()
: super(
"Client not initialized. Client must be initialized before attempting to use");
const MsalUninitializedException()
: super("Client not initialized. Client "
"must be initialized before attempting to use");

static MsalUninitializedException create() =>
const MsalUninitializedException();
}
125 changes: 44 additions & 81 deletions lib/src/public_client_application.dart
Original file line number Diff line number Diff line change
@@ -1,109 +1,72 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'msal_exception.dart';

/// Represents a PublicClientApplication used to authenticate using the implicit flow
@immutable
class PublicClientApplication {
static const MethodChannel _channel = const MethodChannel('msal_flutter');

String _clientId, _authority;
final String _clientId;
final String? _authority;

/// Create a new PublicClientApplication authenticating as the given [clientId],
/// optionally against the selected [authority], defaulting to the common
PublicClientApplication(String clientId, {String authority}) {
throw Exception(
"Direct call is no longer supported in v1.0, please use static method createPublicClientApplication");
}

PublicClientApplication._create(String clientId, {String authority}) {
_clientId = clientId;
_authority = authority;
}
const PublicClientApplication._create(this._clientId, {String? authority})
: _authority = authority;

static Future<PublicClientApplication> createPublicClientApplication(
String clientId,
{String authority}) async {
var res = PublicClientApplication._create(clientId, authority: authority);
String clientId, {
String? authority,
}) async {
final res = PublicClientApplication._create(clientId, authority: authority);
await res._initialize();
return res;
}

/// Acquire a token interactively for the given [scopes]
Future<String> acquireToken(List<String> scopes) async {
//create the arguments
var res = <String, dynamic>{'scopes': scopes};

//call platform
try {
final String token = await _channel.invokeMethod('acquireToken', res);
return token;
} on PlatformException catch (e) {
throw _convertException(e);
}
}
Future<String> acquireToken(List<String> scopes) =>
_invokePlatformMethod<String>('acquireToken', {'scopes': scopes});

/// Acquire a token silently, with no user interaction, for the given [scopes]
Future<String> acquireTokenSilent(List<String> scopes) async {
//create the arguments
var res = <String, dynamic>{'scopes': scopes};
Future<String> acquireTokenSilent(List<String> scopes) =>
_invokePlatformMethod('acquireTokenSilent', {'scopes': scopes});

//call platform
try {
final String token =
await _channel.invokeMethod('acquireTokenSilent', res);
return token;
} on PlatformException catch (e) {
throw _convertException(e);
}
}
Future<void> logout() => _invokePlatformMethod('logout');

// initialize the main client platform side
Future<void> _initialize() async => _invokePlatformMethod(
'initialize',
<String, dynamic>{
'clientId': this._clientId,
//if authority has been set, add it as well
if (this._authority != null) 'authority': this._authority
},
);

Future logout() async {
Future<T> _invokePlatformMethod<T>(String method,
[Map<String, dynamic> arguments = const {}]) async {
try {
await _channel.invokeMethod('logout', <String, dynamic>{});
return await _channel.invokeMethod(method, arguments);
} on PlatformException catch (e) {
throw _convertException(e);
}
}

MsalException _convertException(PlatformException e) {
switch (e.code) {
case "CANCELLED":
return MsalUserCancelledException();
case "NO_SCOPE":
return MsalInvalidScopeException();
case "NO_ACCOUNT":
return MsalNoAccountException();
case "NO_CLIENTID":
return MsalInvalidConfigurationException("Client Id not set");
case "INVALID_AUTHORITY":
return MsalInvalidConfigurationException("Invalid authroity set.");
case "CONFIG_ERROR":
return MsalInvalidConfigurationException(
"Invalid configuration, please correct your settings and try again");
case "NO_CLIENT":
return MsalUninitializedException();
case "CHANGED_CLIENTID":
return MsalChangedClientIdException();
case "INIT_ERROR":
return MsalInitializationException();
case "AUTH_ERROR":
default:
return MsalException("Authentication error");
}
}

//initialize the main client platform side
Future _initialize() async {
var res = <String, dynamic>{'clientId': this._clientId};
//if authority has been set, add it aswell
if (this._authority != null) {
res["authority"] = this._authority;
}
static final _exceptionMapping = <String, MsalException Function()>{
"CANCELLED": MsalUninitializedException.create,
"NO_SCOPE": MsalInvalidScopeException.create,
"NO_ACCOUNT": MsalNoAccountException.create,
"NO_CLIENT": MsalUninitializedException.create,
"CHANGED_CLIENTID": MsalChangedClientIdException.create,
"INIT_ERROR": MsalInitializationException.create,
"NO_CLIENTID": () => MsalInvalidConfigurationException("Client Id not set"),
"INVALID_AUTHORITY": () =>
MsalInvalidConfigurationException("Invalid authroity set."),
"CONFIG_ERROR": () => MsalInvalidConfigurationException(
"Invalid configuration, please correct your settings and try again"),
};

try {
await _channel.invokeMethod('initialize', res);
} on PlatformException catch (e) {
throw _convertException(e);
}
}
MsalException _convertException(PlatformException e) =>
_exceptionMapping[e.code]?.call() ??
MsalException("Authentication error");
}
Loading