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

Support oidcTokenType from configuration #938

Merged
merged 1 commit into from
Nov 8, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ abstract class AuthenticationOIDCDataSource {
String clientId,
String redirectUrl,
String discoveryUrl,
String oidcTokenType,
List<String> scopes,
bool preferEphemeralSessionIOS,
List<String>? promptValues,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,7 @@
import 'dart:developer' as developer;

import 'package:data/data.dart';
import 'package:data/src/network/model/request/permanent_token_body_request.dart';
import 'package:data/src/network/model/response/permanent_token.dart';
import 'package:data/src/network/model/response/user_response.dart';
import 'package:data/src/util/constant.dart';
import 'package:data/src/util/device_manager.dart';
import 'package:dio/dio.dart';
import 'package:domain/domain.dart';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class AuthenticationOIDCDataSourceImpl implements AuthenticationOIDCDataSource {
String clientId,
String redirectUrl,
String discoveryUrl,
String oidcTokenType,
List<String> scopes,
bool preferEphemeralSessionIOS,
List<String>? promptValues,
Expand All @@ -81,7 +82,7 @@ class AuthenticationOIDCDataSourceImpl implements AuthenticationOIDCDataSource {
developer.log('getTokenOIDC(): ${result?.idToken.toString()}', name: 'AuthenticationOIDCDataSourceImpl');

if(result != null) {
final tokenOIDC = result.toTokenOIDC();
final tokenOIDC = result.toTokenOIDC(oidcTokenType);
if (tokenOIDC.isTokenValid()) {
return tokenOIDC;
} else {
Expand Down
6 changes: 4 additions & 2 deletions data/lib/src/extensions/authentication_token_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ import 'package:flutter_appauth/flutter_appauth.dart';

extension AuthorizationTokenResponseExtension on AuthorizationTokenResponse {

TokenOIDC toTokenOIDC() {
TokenOIDC toTokenOIDC(String? oidcTokenType) {
return TokenOIDC(
accessToken ?? '',
TokenId(idToken ?? ''),
accessTokenExpirationDateTime ?? DateTime.now(),
refreshToken ?? '');
refreshToken ?? '',
oidcTokenType ?? DomainConstant.opaqueOidc,
);
}
}
7 changes: 4 additions & 3 deletions data/lib/src/local/model/token_oidc_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,22 @@ class TokenOIDCCache with EquatableMixin {
final TokenId tokenId;
final DateTime expiredTime;
final String refreshToken;
final String oidcTokenType;

TokenOIDCCache(this.token, this.tokenId, this.expiredTime, this.refreshToken);
TokenOIDCCache(this.token, this.tokenId, this.expiredTime, this.refreshToken, this.oidcTokenType);

factory TokenOIDCCache.fromJson(Map<String, dynamic> json) => _$TokenOIDCCacheFromJson(json);

Map<String, dynamic> toJson() => _$TokenOIDCCacheToJson(this);

TokenOIDC toTokenOIDC() => TokenOIDC(token, tokenId, expiredTime, refreshToken);
TokenOIDC toTokenOIDC() => TokenOIDC(token, tokenId, expiredTime, refreshToken, this.oidcTokenType);

@override
List<Object?> get props => [token, tokenId, expiredTime, refreshToken];
}

extension TokenOIDCExtension on TokenOIDC {
TokenOIDCCache toTokenOIDCCache() {
return TokenOIDCCache(token, tokenId, expiredTime, refreshToken);
return TokenOIDCCache(token, tokenId, expiredTime, refreshToken, oidcTokenType);
}
}
12 changes: 7 additions & 5 deletions data/lib/src/network/linshare_http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,20 @@ class LinShareHttpClient {
final bearerAuth = 'Bearer ${oidcToken.token}';
final resultJson = await _dioClient.post(
Endpoint.authentication.generateAuthenticationUrl(authenticateUrl, apiVersion),
options: Options(headers: _buildPermanentTokenRequestParam(bearerAuth, otpCode: otpCode, tokenId: oidcToken.tokenId.uuid)),
options: Options(headers: _buildPermanentTokenRequestParam(bearerAuth, otpCode: otpCode, tokenOidcType: oidcToken.oidcTokenType, tokenId: oidcToken.tokenId.uuid)),
data: bodyRequest.toJson());
return PermanentToken.fromJson(resultJson);
}

Map<String, dynamic> _buildPermanentTokenRequestParam(String authorizationHeader, {OTPCode? otpCode, String? tokenId}) {
Map<String, dynamic> _buildPermanentTokenRequestParam(String authorizationHeader, {OTPCode? otpCode, String? tokenOidcType,String? tokenId}) {
final headerParam = _dioClient.getHeaders();
headerParam[HttpHeaders.authorizationHeader] = authorizationHeader;
headerParam['X-LinShare-Auth-Provider'] = 'Oidc-Jwt';
headerParam['X-LinShare-Client-App'] = 'Linshare-Web';
if (tokenOidcType != null) {
headerParam[Constant.linshareAuthProviderHeader] = tokenOidcType;
}
headerParam[Constant.linshareClientAppHeader] = Constant.linshareClientAppValue;
if (tokenId != null) {
headerParam['X-Linshare-Id-Token'] = tokenId;
headerParam[Constant.linshareTokenIdHeader] = tokenId;
}
if (otpCode != null && otpCode.value.isNotEmpty) {
headerParam[Constant.linShare2FAPin] = otpCode.value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class AuthenticationOIDCRepositoryImpl extends AuthenticationOIDCRepository {
String clientId,
String redirectUrl,
String discoveryUrl,
String oidcTokenType,
List<String> scopes,
bool preferEphemeralSessionIOS,
List<String>? promptValues,
Expand All @@ -53,6 +54,7 @@ class AuthenticationOIDCRepositoryImpl extends AuthenticationOIDCRepository {
clientId,
redirectUrl,
discoveryUrl,
oidcTokenType,
scopes,
preferEphemeralSessionIOS,
promptValues,
Expand Down
4 changes: 4 additions & 0 deletions data/lib/src/util/constant.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ class Constant {
static const biometricSettingState = 'biometric_setting_state';
static const biometricSettingTimeoutMilliseconds = 'biometric_setting_timeout_milliseconds';
static const defaultBiometricAuthenticationTimeoutInMilliseconds = 3 * 60 * 1000;
static const linshareAuthProviderHeader = 'X-LinShare-Auth-Provider';
static const linshareClientAppHeader = 'X-LinShare-Client-App';
static const linshareClientAppValue = 'Linshare-Web';
static const linshareTokenIdHeader = 'X-Linshare-Id-Token';
}
8 changes: 8 additions & 0 deletions data/lib/src/util/oidc_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,33 @@ class OIDCParser {

final matchString = regExp.stringMatch(oidcString) ?? '';
if (matchString.isNotEmpty) {
final regexOidcType = RegExp('(oidcToken:)(.\')(.\*)(\')');
final regExpAuthority = RegExp('(authority:)(.\')(.\*)(\')');
final regExpClientId = RegExp('(client_id:)(.\')(.\*)(\')');
final regExpRedirectUrl = RegExp('(redirect_url:)(.\')(.\*)(\')');
final regExpPostLogoutRedirectUri = RegExp('(post_logout_redirect_uri:)(.\')(.\*)(\')');
final regExpResponseType = RegExp('(response_type:)(.\')(.\*)(\')');
final regExpScope = RegExp('(scope:)(.\')(.\*)(\')');

final oidcTypeMatch = regexOidcType.allMatches(matchString).first.group(3) ?? '';
final authorityMatch = regExpAuthority.allMatches(matchString).first.group(3) ?? '';
final clientIdMatch = regExpClientId.allMatches(matchString).first.group(3) ?? '';
final _ = regExpRedirectUrl.allMatches(matchString).first.group(3) ?? '';
final logoutUrlMatch = regExpPostLogoutRedirectUri.allMatches(matchString).first.group(3) ?? '';
final scopeMatch = regExpScope.allMatches(matchString).first.group(3) ?? '';
final responseTypeMatch = regExpResponseType.allMatches(matchString).first.group(3) ?? '';

String oidcTokenType = DomainConstant.opaqueOidc;
if (oidcTypeMatch == 'JWT') {
oidcTokenType = DomainConstant.jwtOidc;
}

return OIDCConfiguration(
authority: authorityMatch,
clientId: clientIdMatch,
logoutRedirectUri: logoutUrlMatch,
responseType: responseTypeMatch,
oidcTokenType: oidcTokenType,
scopes: scopeMatch.split(' '),
);
}
Expand Down
2 changes: 2 additions & 0 deletions data/test/oidc_parser_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ void main() {
clientId: 'linshare-mobile',
responseType: 'code',
logoutRedirectUri: 'linshare.mobile://oauthredirect',
oidcTokenType: 'Oidc-Jwt',
scopes: ['openid', 'email', 'profile'],
);

Expand Down Expand Up @@ -90,6 +91,7 @@ void main() {

mobileOidcEnabled: false,
mobileOidcSetting: {
oidcToken: 'JWT',
authority: 'https://auth.linshare.local/',
client_id: 'linshare-mobile',
redirect_url: 'linshare.mobile://oauthredirect',
Expand Down
Loading
Loading