Added server data form.
This commit is contained in:
parent
7e9d90b9f7
commit
1868f4e722
|
@ -1,21 +1,29 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'ui/server_form.dart';
|
||||
import 'ui/dialog.dart';
|
||||
|
||||
void main() => runApp(MyApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
final title = 'Welcome page test';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
title: title,
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.green,
|
||||
dialogTheme: baseDialogTheme,
|
||||
),
|
||||
home: MyHomePage(title: 'Flutter Demo Home Page'),
|
||||
);
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: Text(title)),
|
||||
body: ServerForm(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
MyHomePage({Key key, this.title}) : super(key: key);
|
||||
|
||||
|
|
153
lib/ui/server_form.dart
Normal file
153
lib/ui/server_form.dart
Normal file
|
@ -0,0 +1,153 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'dialog.dart';
|
||||
import '../utils/verify_server.dart';
|
||||
|
||||
final log = Logger();
|
||||
|
||||
class ServerForm extends StatefulWidget {
|
||||
ServerForm({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ServerFormState createState() => _ServerFormState();
|
||||
}
|
||||
|
||||
class _ServerFormState extends State<ServerForm> {
|
||||
Uri zAddress;
|
||||
Uri botZAddress;
|
||||
bool _autoValidate = false;
|
||||
bool _disableFields = false;
|
||||
final _serverFormKey = GlobalKey<FormState>();
|
||||
|
||||
final zController = TextEditingController();
|
||||
final botZController = TextEditingController();
|
||||
|
||||
InputDecoration _textFieldDecoration(String label, IconData icon) {
|
||||
return InputDecoration(
|
||||
labelText: label,
|
||||
icon: Icon(icon),
|
||||
hintText: 'Please, insert $label address',
|
||||
);
|
||||
}
|
||||
|
||||
SnackBar showProgress() {
|
||||
return SnackBar(
|
||||
content: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
CircularProgressIndicator(
|
||||
value: null,
|
||||
strokeWidth: 7.0,
|
||||
),
|
||||
Text('Processing Data')
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
String validateServer(String address) {
|
||||
if (address.isEmpty) {
|
||||
return 'Server address must not be empty';
|
||||
}
|
||||
try {
|
||||
Uri.parse(address);
|
||||
} on FormatException catch (e) {
|
||||
return e.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String validateZServer(String address) {
|
||||
String baseValidation = this.validateServer(address);
|
||||
if (baseValidation != null) {
|
||||
return baseValidation;
|
||||
}
|
||||
if (utf8.encode(address).length > 72) {
|
||||
return "Server address string length is > 72 bytes. Refusing to go on.";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> _onPressed() async {
|
||||
log.d("Button pressed");
|
||||
setState(() {
|
||||
_disableFields = true;
|
||||
});
|
||||
Scaffold.of(context).showSnackBar(this.showProgress());
|
||||
if (!_serverFormKey.currentState.validate()) {
|
||||
setState(() {
|
||||
_autoValidate = true;
|
||||
_disableFields = false;
|
||||
});
|
||||
Scaffold.of(context).hideCurrentSnackBar();
|
||||
return;
|
||||
}
|
||||
|
||||
bool resp;
|
||||
Uri _botZAddr = Uri.parse(botZController.text);
|
||||
Uri _zAddr = Uri.parse(zController.text);
|
||||
log.d("Received botZAddr: $_botZAddr\tzAddr: $_zAddr");
|
||||
try {
|
||||
resp = await verifyServer(_botZAddr, _zAddr);
|
||||
log.i("Secret is${resp ? ' ' : ' NOT '}a match");
|
||||
} catch (err) {
|
||||
log.e("Error: ${err.toString()}");
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: errorDialogBuilder("Error", "${err.toString()}"));
|
||||
} finally {
|
||||
log.d("Clean the state");
|
||||
setState(() {
|
||||
_disableFields = false;
|
||||
});
|
||||
Scaffold.of(context).hideCurrentSnackBar();
|
||||
}
|
||||
|
||||
if (!resp) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: errorDialogBuilder("Error",
|
||||
"The BotZ server does not target the provided Z server."));
|
||||
} else {
|
||||
_serverFormKey.currentState.save();
|
||||
// TODO: go to the next window.
|
||||
}
|
||||
|
||||
log.d("Done");
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Form(
|
||||
key: _serverFormKey,
|
||||
child: Column(children: <Widget>[
|
||||
TextFormField(
|
||||
autofocus: true,
|
||||
autocorrect: false,
|
||||
controller: zController,
|
||||
enabled: !_disableFields,
|
||||
decoration: this._textFieldDecoration("Z server", Icons.http),
|
||||
validator: this.validateZServer,
|
||||
autovalidate: _autoValidate,
|
||||
onSaved: (String addr) {
|
||||
zAddress = Uri.parse(addr);
|
||||
}),
|
||||
TextFormField(
|
||||
autocorrect: false,
|
||||
controller: botZController,
|
||||
enabled: !_disableFields,
|
||||
decoration: this._textFieldDecoration("BotZ server", Icons.http),
|
||||
validator: this.validateServer,
|
||||
autovalidate: _autoValidate,
|
||||
onSaved: (String addr) {
|
||||
botZAddress = Uri.parse(addr);
|
||||
}),
|
||||
RaisedButton(
|
||||
onPressed: _onPressed,
|
||||
child: Text('Save'),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
42
lib/utils/verify_server.dart
Normal file
42
lib/utils/verify_server.dart
Normal file
|
@ -0,0 +1,42 @@
|
|||
import 'package:http/http.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:dbcrypt/dbcrypt.dart';
|
||||
|
||||
import 'connection.dart';
|
||||
|
||||
|
||||
final log = Logger();
|
||||
|
||||
Future<bool> verifyServer(Uri serverAddr, Uri zTargetAddr, {Map<String, String> routes=defaultRoutes}) async {
|
||||
String botZTargetUri = serverAddr.toString() + routes['ping'];
|
||||
|
||||
log.d("botZ server uri: $botZTargetUri");
|
||||
log.d("z server: ${zTargetAddr.toString()}");
|
||||
|
||||
var resp = await get(
|
||||
botZTargetUri,
|
||||
);
|
||||
|
||||
log.d("Status code: ${resp.statusCode}");
|
||||
if (resp.statusCode >= 300 || resp.statusCode < 200) {
|
||||
log.d("Status code is not 2xx: $resp.statusCode");
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<String, dynamic> respData = jsonDecode(resp.body);
|
||||
|
||||
log.d("Response: ${respData.toString()}");
|
||||
if (!respData.containsKey('hash')) {
|
||||
log.d("Response is malformed: ${respData.toString()}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DBCrypt().checkpw(zTargetAddr.toString(), respData['hash'])) {
|
||||
log.d("The server answer do not match the expected response: ${respData.toString()}");
|
||||
return false;
|
||||
}
|
||||
|
||||
log.d("Response is ok!");
|
||||
return true;
|
||||
}
|
|
@ -36,6 +36,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
dbcrypt:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dbcrypt
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
|
|
@ -22,6 +22,7 @@ dependencies:
|
|||
|
||||
http: ^0.12.0+2
|
||||
logger: ^0.7.0+2
|
||||
dbcrypt: ^1.0.0
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^0.1.2
|
||||
|
|
Loading…
Reference in New Issue
Block a user