Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix of #457 #458

Merged
merged 1 commit into from
Dec 18, 2024
Merged
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
4 changes: 4 additions & 0 deletions backends/carp_webservices/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.5.2

* fix of issues [#457](https://github.com/cph-cachet/carp.sensing-flutter/issues/457)

## 3.5.1

* upgrade to carp_serialization v. 2.0 & carp_mobile_sensing: 1.10.0
Expand Down
25 changes: 5 additions & 20 deletions backends/carp_webservices/example/.metadata
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.

version:
revision: "7482962148e8d758338d8a28f589f317e1e42ba4"
revision: "5874a72aa4c779a02553007c47dacbefba2374dc"
channel: "stable"

project_type: app
Expand All @@ -13,26 +13,11 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
- platform: android
create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
- platform: ios
create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
- platform: linux
create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
create_revision: 5874a72aa4c779a02553007c47dacbefba2374dc
base_revision: 5874a72aa4c779a02553007c47dacbefba2374dc
- platform: macos
create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
- platform: web
create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
- platform: windows
create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4
create_revision: 5874a72aa4c779a02553007c47dacbefba2374dc
base_revision: 5874a72aa4c779a02553007c47dacbefba2374dc

# User provided section

Expand Down
28 changes: 28 additions & 0 deletions backends/carp_webservices/example/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
65 changes: 23 additions & 42 deletions backends/carp_webservices/lib/carp_auth/carp_auth.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 42 additions & 41 deletions backends/carp_webservices/lib/carp_auth/carp_auth_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ class CarpAuthService {
_manager!.userChanges().listen((user) {
if (user != null) {
_currentUser = getCurrentUserProfile(user);
_authEventController.add(AuthEvent.authenticated);
if (_currentUser != null) {
_authEventController.add(AuthEvent.authenticated);
} else {
_authEventController.add(AuthEvent.failed);
}
}
});
}
Expand All @@ -128,28 +132,27 @@ class CarpAuthService {
/// The discovery URL in the [authProperties] is used to find the Identity Server.
///
/// Returns the signed in user (with an [OAuthToken] access token), if successful.
/// Throws a [CarpServiceException] if not successful.
/// Throws a [CarpServiceException] if not successful.
Future<CarpUser> authenticate() async {
assert(_manager != null, 'Manager not configured. Call configure() first.');

if (!_manager!.didInit) {
await initManager();
}
if (!_manager!.didInit) await initManager();

OidcUser? response = await manager!.loginAuthorizationCodeFlow();

if (response != null) {
_currentUser = getCurrentUserProfile(response);
currentUser.authenticated(OAuthToken.fromTokenResponse(response.token));
_authEventController.add(AuthEvent.authenticated);
return currentUser;

if (_currentUser != null) {
_currentUser!
.authenticated(OAuthToken.fromTokenResponse(response.token));
_authEventController.add(AuthEvent.authenticated);
return currentUser;
}
}

// All other cases are treated as a failed attempt and throws an error
// All other cases are treated as a failed attempt
_authEventController.add(AuthEvent.failed);
_currentUser = null;

// auth error response from CARP is in the form
throw CarpServiceException(
httpStatus: HTTPStatus(401),
message: 'Authentication failed.',
Expand All @@ -167,10 +170,7 @@ class CarpAuthService {
required String password,
}) async {
assert(_manager != null, 'Manager not configured. Call configure() first.');

if (!_manager!.didInit) {
await initManager();
}
if (!_manager!.didInit) await initManager();

final OidcUser? response = await manager?.loginPassword(
username: username,
Expand All @@ -179,17 +179,18 @@ class CarpAuthService {

if (response != null) {
_currentUser = getCurrentUserProfile(response);
currentUser.authenticated(OAuthToken.fromTokenResponse(response.token));
_authEventController.add(AuthEvent.refreshed);
return currentUser;

if (_currentUser != null) {
_currentUser!
.authenticated(OAuthToken.fromTokenResponse(response.token));
_authEventController.add(AuthEvent.authenticated);
return currentUser;
}
}

// All other cases are treated as a failed attempt and throws an error
// All other cases are treated as a failed attempt
_authEventController.add(AuthEvent.failed);
_currentUser = null;

// auth error response from CARP is on the form
// {error: invalid_grant, error_description: Bad credentials}
throw CarpServiceException(
httpStatus: HTTPStatus(401),
message: 'Authentication failed.',
Expand All @@ -207,30 +208,27 @@ class CarpAuthService {
/// Throws a [CarpServiceException] if not successful.
Future<CarpUser> refresh() async {
assert(_manager != null, 'Manager not configured. Call configure() first.');

if (!_manager!.didInit) {
await initManager();
}
if (!_manager!.didInit) await initManager();

final OidcUser? response = await manager?.refreshToken();

print('reposnse : $response');

if (response != null) {
currentUser = getCurrentUserProfile(response);
currentUser.authenticated(OAuthToken.fromTokenResponse(response.token));
_authEventController.add(AuthEvent.refreshed);
return currentUser;
_currentUser = getCurrentUserProfile(response);

if (_currentUser != null) {
_currentUser!
.authenticated(OAuthToken.fromTokenResponse(response.token));
_authEventController.add(AuthEvent.authenticated);
return currentUser;
}
}

// All other cases are treated as a failed attempt and throws an error
// All other cases are treated as a failed attempt
_authEventController.add(AuthEvent.failed);

// auth error response from CARP is on the form
// {error: invalid_grant, error_description: Bad credentials}
throw CarpServiceException(
httpStatus: HTTPStatus(401),
message: 'Token refresh failed.',
message: 'Authentication failed.',
);
}

Expand Down Expand Up @@ -265,10 +263,13 @@ class CarpAuthService {
// USERS
// --------------------------------------------------------------------------

/// Gets the CARP profile of the current user from the JWT token
CarpUser getCurrentUserProfile(OidcUser response) {
var jwt = JwtDecoder.decode(response.token.accessToken!);
return CarpUser.fromJWT(jwt, response.token);
/// Gets the CARP profile of the current user from the JWT token of [user].
/// Returns null if the the [user] don't have an access token.
CarpUser? getCurrentUserProfile(OidcUser user) {
if (user.token.accessToken == null) return null;

var jwt = JwtDecoder.decode(user.token.accessToken!);
return CarpUser.fromJWT(jwt, user.token);
}

/// Makes sure that the [CarpApp] or [CarpUser] is configured, by throwing a
Expand Down
22 changes: 11 additions & 11 deletions backends/carp_webservices/lib/carp_auth/carp_user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ class CarpUser {
String id;

/// The user's email
String email;
String? email;

/// User's first name
String firstName;
String? firstName;

/// User's last name
String lastName;
String? lastName;

/// The list of roles that this user has in CARP.
List<dynamic> roles = [];
Expand All @@ -32,10 +32,10 @@ class CarpUser {
CarpUser({
required this.username,
required this.id,
required this.firstName,
required this.lastName,
required this.email,
required this.roles,
this.firstName,
this.lastName,
this.email,
this.roles = const [],
this.token,
});

Expand All @@ -57,10 +57,10 @@ class CarpUser {
return CarpUser(
username: jwt['preferred_username'] as String,
id: jwt['sub'] as String,
firstName: jwt['given_name'] as String,
lastName: jwt['family_name'] as String,
email: jwt['email'] as String,
roles: jwt['realm_access']['roles'] as List<dynamic>,
firstName: jwt['given_name'] as String?,
lastName: jwt['family_name'] as String?,
email: jwt['email'] as String?,
roles: jwt['realm_access']['roles'] as List<dynamic>? ?? [],
token: OAuthToken.fromTokenResponse(token),
);
}
Expand Down
Loading
Loading