API authentication
All checks were successful
ci/woodpecker/push/flutterBuild Pipeline was successful

This commit is contained in:
Balazs Toldi 2022-05-09 09:55:11 +02:00
parent 4cd006be85
commit ec02aaa406
Signed by: Bazsalanszky
GPG key ID: 6C7D440036F99D58
7 changed files with 320 additions and 19 deletions

View file

@ -1,6 +1,10 @@
import 'package:flutter/material.dart';
import 'package:gitea_client/model/user.dart';
import 'package:gitea_client/service/AuthenticationChecker.dart';
import 'package:url_launcher/url_launcher.dart';
import 'model/ApiAccess.dart';
void main() {
runApp(const MyApp());
}
@ -17,6 +21,22 @@ class MyApp extends StatelessWidget {
primarySwatch: Colors.lightGreen,
),
home: const LoginPage(title: 'Gitea client'),
routes: {
},
onGenerateRoute: (route) {
switch (route.name) { // <- here
case "/loginstatus":
return MaterialPageRoute(
settings: const RouteSettings(name: "/parameterpage"),
builder: (context) => StatefulLoginStatus(
apiAccess: route.arguments as ApiAccess,
),
);
}
return null;
},
);
}
}
@ -60,7 +80,8 @@ class StatefulLoginForm extends StatefulWidget {
}
class _LoginForm extends State<StatefulLoginForm> {
final Uri getTokenUri = Uri.parse("https://www.jetbrains.com/help/youtrack/incloud/integration-with-gitea.html#enable-youtrack-integration-gitea");
final Uri getTokenUri = Uri.parse(
"https://www.jetbrains.com/help/youtrack/incloud/integration-with-gitea.html#enable-youtrack-integration-gitea");
final tokenController = TextEditingController();
final instanceController = TextEditingController();
String instance = "gitea.com";
@ -76,7 +97,7 @@ class _LoginForm extends State<StatefulLoginForm> {
children: [
DropdownButton(
value: instance,
items: <String>['gitea.com', 'codeberg.com', 'Other']
items: <String>['gitea.com', 'codeberg.org', 'Other']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
@ -105,26 +126,89 @@ class _LoginForm extends State<StatefulLoginForm> {
obscureText: true,
),
SizedBox(
width: (media.width > 600) ? media.width * 0.25 : media.width * 0.5,
width:
(media.width > 600) ? media.width * 0.25 : media.width * 0.5,
child: Container(
padding: EdgeInsetsDirectional.all(15),
child: ElevatedButton(
child: const Text("Login"),
onPressed: () => {
Navigator.pushNamed(context, "/loginstatus",
arguments: ApiAccess(
(instance == "Other")
? instanceController.text
: instance,
tokenController.text))
},
),
)),
//
TextButton(onPressed: () => {
_launchUrl(getTokenUri)
}, child: Text("Need a Token? Find out how to generate one!"))
TextButton(
onPressed: () => {_launchUrl(getTokenUri)},
child: Text("Need a Token? Find out how to generate one!"))
],
),
);
}
}
class StatefulLoginStatus extends StatefulWidget {
final ApiAccess apiAccess;
const StatefulLoginStatus({Key? key, required this.apiAccess}) : super(key: key);
@override
_StatefulLoginStatus createState() => _StatefulLoginStatus();
}
class _StatefulLoginStatus extends State<StatefulLoginStatus> {
Future<AuthenticatedUser>? userRequest;
@override
void initState() {
userRequest = AuthenticationChecker(widget.apiAccess).getAuthenticatedUserOrError();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Login status"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
FutureBuilder<AuthenticatedUser>(
future: userRequest,
builder: (context, snapshot) {
if (snapshot.hasError){
return Center(
child: Text(
"Hiba történt: ${snapshot.error}"
),
);
} else if (snapshot.hasData){
var user = snapshot.data!;
final username = user.username;
return Text("Logged in as $username");
} else {
return Center(
child: CircularProgressIndicator(),
);
}
}
)
],
),
));
}
}
void _launchUrl(Uri url) async {
if (!await launchUrl(url)) throw 'Could not launch $url';
}

6
lib/model/ApiAccess.dart Normal file
View file

@ -0,0 +1,6 @@
class ApiAccess{
final String instance;
final String token;
const ApiAccess(this.instance, this.token);
}

View file

@ -1,3 +1,5 @@
import 'dart:convert';
class AuthenticatedUser {
int? id;
String? login;

View file

@ -0,0 +1,21 @@
import 'package:gitea_client/model/ApiAccess.dart';
import 'package:gitea_client/service/gitea_service.dart';
import '../model/user.dart';
class AuthenticationChecker {
final ApiAccess apiAccess;
late GiteaServie service;
AuthenticationChecker(this.apiAccess) {
service = GiteaServie(apiAccess.instance, apiAccess.token);
}
Future<AuthenticatedUser> getAuthenticatedUserOrError() async{
final user = await service.getAuthenticatedUser();
if(user.username != null) {
return user;
}
throw Exception("Authentication failed");
}
}

View file

@ -0,0 +1,25 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:gitea_client/model/user.dart';
import 'package:http/http.dart' as http;
AuthenticatedUser _parseAuthenticatedUserResponse(String message){
return AuthenticatedUser.fromJson(jsonDecode(message));
}
class GiteaServie {
final String apiUrl;
final String _token;
const GiteaServie(this.apiUrl, this._token);
Future<AuthenticatedUser> getAuthenticatedUser() async {
var response = await http.get(
Uri.https(apiUrl, "api/v1/user", {
"token": _token,
}),
);
return compute(_parseAuthenticatedUserResponse, response.body);
}
}

View file

@ -1,6 +1,27 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "39.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
async:
dependency: transitive
description:
@ -15,6 +36,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
build:
dependency: transitive
description:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
characters:
dependency: transitive
description:
@ -29,6 +64,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
clock:
dependency: transitive
description:
@ -43,6 +85,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
cupertino_icons:
dependency: "direct main"
description:
@ -50,6 +106,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
dart_style:
dependency: transitive
description:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.3"
fake_async:
dependency: transitive
description:
@ -57,6 +120,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
flutter:
dependency: "direct main"
description: flutter
@ -84,6 +154,27 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
http:
dependency: "direct main"
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.4"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
intl:
dependency: "direct main"
description:
@ -98,6 +189,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "4.5.0"
json_serializable:
dependency: "direct dev"
description:
name: json_serializable
url: "https://pub.dartlang.org"
source: hosted
version: "6.2.0"
lints:
dependency: transitive
description:
@ -105,6 +210,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
matcher:
dependency: transitive
description:
@ -126,6 +238,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
path:
dependency: transitive
description:
@ -140,11 +259,39 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.2"
source_helper:
dependency: transitive
description:
name: source_helper
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.2"
source_span:
dependency: transitive
description:
@ -195,7 +342,7 @@ packages:
source: hosted
version: "1.3.0"
url_launcher:
dependency: "direct dev"
dependency: "direct main"
description:
name: url_launcher
url: "https://pub.dartlang.org"
@ -257,6 +404,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
sdks:
dart: ">=2.16.2 <3.0.0"
flutter: ">=2.10.0"

View file

@ -32,8 +32,10 @@ dependencies:
flutter_localizations:
sdk: flutter
intl: ^0.17.0
# For opening links in the browser
url_launcher: ^6.1.0
# For http communication
http: ^0.13.4
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
@ -41,14 +43,14 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
json_serializable: ^6.2.0
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^1.0.0
url_launcher: ^6.1.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec