Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
M
Mobile App
Manage
Activity
Members
Labels
Plan
Issues
3
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Code
Mobile App
Commits
08a8d51f
Commit
08a8d51f
authored
5 years ago
by
Markin Igor
Browse files
Options
Downloads
Patches
Plain Diff
Rework cancellation flows.
parent
aa9f4562
No related branches found
Branches containing commit
No related tags found
1 merge request
!2
Resolve "Rework auth flow."
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
lib/src/app.dart
+113
-8
113 additions, 8 deletions
lib/src/app.dart
lib/src/error-alert.dart
+22
-0
22 additions, 0 deletions
lib/src/error-alert.dart
lib/src/screens/home.dart
+10
-134
10 additions, 134 deletions
lib/src/screens/home.dart
with
145 additions
and
142 deletions
lib/src/app.dart
+
113
−
8
View file @
08a8d51f
// app.dart
import
'../config.dart'
;
import
'error-alert.dart'
;
import
'screens/splashscreen.dart'
;
import
'package:flutter/material.dart'
;
import
'screens/home.dart'
;
...
...
@@ -6,6 +8,11 @@ import 'package:flutter/services.dart';
import
'dart:async'
;
import
'dart:developer'
;
import
'package:shared_preferences/shared_preferences.dart'
;
import
'package:flutter_web_browser/flutter_web_browser.dart'
;
import
'dart:convert'
;
import
'package:url_launcher/url_launcher.dart'
;
import
'package:flutter_app_auth_wrapper/flutter_app_auth_wrapper.dart'
;
import
'dart:io'
;
import
'package:uni_links/uni_links.dart'
;
...
...
@@ -52,8 +59,6 @@ class App extends StatelessWidget {
navigateAfterFuture:
initApplication
,
)
);
}
}
...
...
@@ -76,9 +81,59 @@ class _MainAppState extends State<MainApp> {
// Url of the app which invoked OAuth
String
_invokerURL
;
String
_host
=
Config
.
appFlavor
==
Flavor
.
DEVELOPMENT
?
Config
.
HOSTS
[
0
]
:
Config
.
DEFAULT_APP_HOST
;
Screen
_currentScreen
=
Screen
.
App
;
@override
initState
()
{
super
.
initState
();
// Set up app host
if
(
widget
.
initialHost
!=
null
)
{
setState
(()
{
_host
=
widget
.
initialHost
;
});
}
// Subscribe to authorization events
FlutterAppAuthWrapper
.
eventStream
()
.
listen
((
data
)
async
{
var
token
=
json
.
decode
(
data
.
toString
())[
"access_token"
];
setScreen
(
Screen
.
App
);
log
(
"Open
$_invokerURL
"
);
try
{
await
launch
(
"
$_invokerURL
?token=
$token
&host=
$_host
"
);
}
catch
(
e
)
{
log
(
"Error launching url
$_invokerURL
"
);
}
},
onError:
(
error
)
{
log
(
"Err
$error
"
);
String
errorMessage
=
error
.
message
;
String
errorDetails
=
error
.
details
;
if
(
// Handle cancellation for Android
errorDetails
==
'{"type":0,"code":1,"errorDescription":"User cancelled flow"}'
||
// Handle cancellation for iOS
errorMessage
.
toLowerCase
()
.
contains
(
"the operation couldn"
)
)
{
if
(
Platform
.
isAndroid
)
{
// Show only for android, because iOS will show the same alert as
// was for Auth request
openVereign
();
}
else
{
setScreen
(
Screen
.
App
);
}
}
else
{
showErrorAlert
(
context
,
Platform
.
isAndroid
?
errorDetails
:
errorMessage
,
openVereign
);
setScreen
(
Screen
.
App
);
}
});
initUniLinks
();
}
...
...
@@ -89,37 +144,87 @@ class _MainAppState extends State<MainApp> {
}
Future
<
Null
>
initUniLinks
()
async
{
updateAppMod
e
(
widget
.
initialUri
);
handleLinkChang
e
(
widget
.
initialUri
);
_sub
=
getUriLinksStream
()
.
listen
((
Uri
uri
)
{
updateAppMod
e
(
uri
);
handleLinkChang
e
(
uri
);
},
onError:
(
err
)
{
log
(
'got err:
$err
'
);
});
}
updateAppMod
e
(
Uri
uri
)
{
handleLinkChang
e
(
Uri
uri
)
{
if
(
uri
?.
path
==
"/authorize"
)
{
setState
(()
{
_appMode
=
AppMode
.
Authorization
;
_invokerURL
=
uri
.
queryParameters
[
"invokerUrl"
];
});
startOAuth
();
}
else
{
setState
(()
{
_appMode
=
AppMode
.
Default
;
});
openVereign
();
}
}
setScreen
(
Screen
screen
)
{
setState
(()
{
_currentScreen
=
screen
;
});
}
openVereign
()
{
setScreen
(
Screen
.
Dashboard
);
FlutterWebBrowser
.
openWebPage
(
url:
_host
,
androidToolbarColor:
Color
(
0xFFd51d32
));
}
startOAuth
()
{
if
(
_currentScreen
==
Screen
.
OAuth
)
{
return
;
}
setScreen
(
Screen
.
OAuth
);
var
params
=
Config
.
getOAuthParams
(
host:
_host
);
FlutterAppAuthWrapper
.
startAuth
(
AuthConfig
(
clientId:
params
[
"clientId"
],
clientSecret:
params
[
"clientSecret"
],
redirectUrl:
params
[
"redirectUrl"
],
state:
"login"
,
prompt:
"consent"
,
endpoint:
AuthEndpoint
(
auth:
params
[
"authEndpoint"
],
token:
params
[
"tokenEndpoint"
]),
scopes:
[
"user_account_status"
,
"user_territory"
,
"user_profile"
],
),
);
}
setHost
(
String
host
)
{
setState
(()
{
_host
=
host
;
});
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
appBar:
new
AppBar
(
title:
Text
(
"Vereign"
)),
body:
Home
(
mode:
_appMode
,
invokerURL:
_invokerURL
,
host:
widget
.
initialHost
host:
_host
,
setHost:
setHost
,
openDashboardClick:
openVereign
,
authorizeClick:
startOAuth
,
)
);
}
...
...
This diff is collapsed.
Click to expand it.
lib/src/error-alert.dart
0 → 100644
+
22
−
0
View file @
08a8d51f
import
'package:flutter/material.dart'
;
Future
<
void
>
showErrorAlert
(
context
,
errorString
,
callback
)
{
return
showDialog
<
void
>(
context:
context
,
builder:
(
BuildContext
context
)
{
return
AlertDialog
(
title:
Text
(
'Authorization error'
),
content:
Text
(
errorString
),
actions:
<
Widget
>[
FlatButton
(
child:
Text
(
'Open Dashboard'
),
onPressed:
()
async
{
Navigator
.
of
(
context
)
.
pop
();
callback
();
},
),
],
);
},
);
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
lib/src/screens/home.dart
+
10
−
134
View file @
08a8d51f
import
'package:flutter/material.dart'
;
import
'package:flutter_web_browser/flutter_web_browser.dart'
;
import
'package:flutter_app_auth_wrapper/flutter_app_auth_wrapper.dart'
;
import
'package:url_launcher/url_launcher.dart'
;
import
'dart:developer'
;
import
'dart:convert'
;
import
'dart:async'
;
import
'package:shared_preferences/shared_preferences.dart'
;
...
...
@@ -13,46 +8,29 @@ import '../app.dart';
class
Home
extends
StatefulWidget
{
Home
({
@required
this
.
mode
,
@required
this
.
invokerURL
,
@required
this
.
host
,
@required
this
.
setHost
,
@required
this
.
authorizeClick
,
@required
this
.
openDashboardClick
,
});
final
AppMode
mode
;
final
String
invokerURL
;
final
String
host
;
final
void
Function
(
String
)
setHost
;
final
void
Function
()
openDashboardClick
;
final
void
Function
()
authorizeClick
;
@override
_HomeState
createState
()
=
>
_HomeState
();
}
class
_HomeState
extends
State
<
Home
>
{
String
_host
=
Config
.
appFlavor
==
Flavor
.
DEVELOPMENT
?
Config
.
HOSTS
[
0
]
:
Config
.
DEFAULT_APP_HOST
;
bool
_hidden
=
true
;
Screen
_currentScreen
=
Screen
.
App
;
@override
initState
()
{
super
.
initState
();
// Set up initial host
if
(
widget
.
host
!=
null
)
{
setState
(()
{
_host
=
widget
.
host
;
});
}
setScreenByMode
(
widget
.
mode
);
FlutterAppAuthWrapper
.
eventStream
()
.
listen
((
data
)
{
var
token
=
json
.
decode
(
data
.
toString
())[
"access_token"
];
_showAlert
(
token
);
setScreen
(
Screen
.
App
);
},
onError:
(
error
)
{
log
(
"Err
$error
"
);
setScreen
(
Screen
.
App
);
});
Timer
(
Duration
(
seconds:
3
),
()
{
...
...
@@ -63,105 +41,6 @@ class _HomeState extends State<Home> {
);
}
setScreen
(
Screen
screen
)
{
if
(
_currentScreen
==
screen
&&
screen
!=
Screen
.
Dashboard
// ATM we can not determine whether dashboard was closed or not, so we avoid this case
)
{
return
;
}
setState
(()
{
_currentScreen
=
screen
;
});
if
(
_currentScreen
==
Screen
.
Dashboard
)
{
openVereign
();
}
else
if
(
_currentScreen
==
Screen
.
OAuth
)
{
startOAuth
();
}
}
Future
<
void
>
_showAlert
(
token
)
{
return
showDialog
<
void
>(
context:
context
,
builder:
(
BuildContext
context
)
{
return
AlertDialog
(
title:
Text
(
'Authorization success'
),
actions:
<
Widget
>[
FlatButton
(
child:
Text
(
'Go back'
),
onPressed:
()
async
{
Navigator
.
of
(
context
)
.
pop
();
log
(
"Open
${widget.invokerURL}
"
);
try
{
await
launch
(
"
${widget.invokerURL}
?token=
$token
&host=
$_host
"
);
}
catch
(
e
)
{
log
(
"Error launching url
${widget.invokerURL}
"
);
}
},
),
],
);
},
);
}
@override
void
didUpdateWidget
(
Home
oldWidget
)
{
// this method IS called when parent widget passes new "props"
// unlike React, this method IS called _before_ the build
// unlike React, this method ISN'T called after setState()
if
(
widget
.
host
!=
oldWidget
.
host
&&
widget
.
host
!=
null
)
{
setState
(()
{
_host
=
widget
.
host
;
});
}
if
(
widget
.
mode
!=
oldWidget
.
mode
)
{
setScreenByMode
(
widget
.
mode
);
}
super
.
didUpdateWidget
(
oldWidget
);
}
setScreenByMode
(
AppMode
mode
)
{
if
(
mode
==
AppMode
.
Authorization
)
{
setScreen
(
Screen
.
OAuth
);
}
else
if
(
mode
==
AppMode
.
Default
)
{
setScreen
(
Screen
.
Dashboard
);
}
}
openVereign
()
{
FlutterWebBrowser
.
openWebPage
(
url:
_host
,
androidToolbarColor:
Color
(
0xFFd51d32
));
}
startOAuth
()
{
var
params
=
Config
.
getOAuthParams
(
host:
_host
);
FlutterAppAuthWrapper
.
startAuth
(
AuthConfig
(
clientId:
params
[
"clientId"
],
clientSecret:
params
[
"clientSecret"
],
redirectUrl:
params
[
"redirectUrl"
],
state:
"login"
,
prompt:
"consent"
,
endpoint:
AuthEndpoint
(
auth:
params
[
"authEndpoint"
],
token:
params
[
"tokenEndpoint"
]),
scopes:
[
"user_account_status"
,
"user_territory"
,
"user_profile"
],
),
);
}
@override
Widget
build
(
BuildContext
context
)
{
if
(
_hidden
)
{
...
...
@@ -169,23 +48,20 @@ class _HomeState extends State<Home> {
}
var
children
=
<
Widget
>[
_urlButton
(
context
,
"Open Dashboard"
,
()
=
>
setScreen
(
Scre
en
.
Dashboard
)
),
_urlButton
(
context
,
"Open Dashboard"
,
widget
.
op
enDashboard
Click
),
];
if
(
widget
.
mode
==
AppMode
.
Authorization
)
{
children
.
add
(
_urlButton
(
context
,
"Authorize with Vereign"
,
()
=
>
setScreen
(
Screen
.
OAuth
)
));
children
.
add
(
_urlButton
(
context
,
"Authorize with Vereign"
,
widget
.
authorizeClick
));
}
if
(
Config
.
appFlavor
==
Flavor
.
DEVELOPMENT
)
{
children
.
add
(
wrapInContainer
(
DropdownButton
<
String
>(
value:
_
host
,
value:
widget
.
host
,
onChanged:
(
String
newValue
)
async
{
setState
(()
{
_host
=
newValue
;
});
widget
.
setHost
(
newValue
);
final
prefs
=
await
SharedPreferences
.
getInstance
();
prefs
.
setString
(
"host"
,
newValue
);
},
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment