forked from baron/baron-sso
Implement tenant import and RP auto login policies
This commit is contained in:
@@ -7,9 +7,15 @@ String? resolveLinkedRpLaunchUrl(LinkedRp rp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final initUrl = rp.initUrl.trim();
|
||||
if (initUrl.isNotEmpty) {
|
||||
return initUrl;
|
||||
if (rp.autoLoginSupported) {
|
||||
final initUrl = rp.initUrl.trim();
|
||||
if (initUrl.isNotEmpty) {
|
||||
return initUrl;
|
||||
}
|
||||
final autoLoginUrl = rp.autoLoginUrl.trim();
|
||||
if (autoLoginUrl.isNotEmpty) {
|
||||
return autoLoginUrl;
|
||||
}
|
||||
}
|
||||
|
||||
final url = rp.url.trim();
|
||||
|
||||
@@ -97,6 +97,8 @@ class LinkedRp {
|
||||
final String logo;
|
||||
final String url;
|
||||
final String initUrl;
|
||||
final bool autoLoginSupported;
|
||||
final String autoLoginUrl;
|
||||
final String status;
|
||||
final List<String> scopes;
|
||||
final DateTime? lastAuthenticatedAt;
|
||||
@@ -107,6 +109,8 @@ class LinkedRp {
|
||||
required this.logo,
|
||||
required this.url,
|
||||
required this.initUrl,
|
||||
required this.autoLoginSupported,
|
||||
required this.autoLoginUrl,
|
||||
required this.status,
|
||||
required this.scopes,
|
||||
this.lastAuthenticatedAt,
|
||||
@@ -129,6 +133,8 @@ class LinkedRp {
|
||||
logo: json['logo']?.toString() ?? '',
|
||||
url: json['url']?.toString() ?? '',
|
||||
initUrl: json['init_url']?.toString() ?? '',
|
||||
autoLoginSupported: json['auto_login_supported'] == true,
|
||||
autoLoginUrl: json['auto_login_url']?.toString() ?? '',
|
||||
status: json['status']?.toString() ?? '',
|
||||
scopes: (json['scopes'] as List?)?.whereType<String>().toList() ?? [],
|
||||
lastAuthenticatedAt: parsedLastAuth,
|
||||
|
||||
@@ -11,6 +11,8 @@ class LinkedRp {
|
||||
final String logo;
|
||||
final String url;
|
||||
final String initUrl;
|
||||
final bool autoLoginSupported;
|
||||
final String autoLoginUrl;
|
||||
final String status;
|
||||
final List<String> scopes;
|
||||
final DateTime? lastAuthenticatedAt;
|
||||
@@ -21,6 +23,8 @@ class LinkedRp {
|
||||
required this.logo,
|
||||
required this.url,
|
||||
required this.initUrl,
|
||||
required this.autoLoginSupported,
|
||||
required this.autoLoginUrl,
|
||||
required this.status,
|
||||
required this.scopes,
|
||||
required this.lastAuthenticatedAt,
|
||||
@@ -43,6 +47,8 @@ class LinkedRp {
|
||||
logo: json['logo']?.toString() ?? '',
|
||||
url: json['url']?.toString() ?? '',
|
||||
initUrl: json['init_url']?.toString() ?? '',
|
||||
autoLoginSupported: json['auto_login_supported'] == true,
|
||||
autoLoginUrl: json['auto_login_url']?.toString() ?? '',
|
||||
status: json['status']?.toString() ?? 'unknown',
|
||||
scopes: (json['scopes'] as List?)?.whereType<String>().toList() ?? [],
|
||||
lastAuthenticatedAt: parsedLastAuth,
|
||||
|
||||
@@ -1247,6 +1247,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
onRevoke: isRevoked ? null : () => _onRevokeLink(rp.id, name),
|
||||
url: rp.url,
|
||||
launchUrl: resolveLinkedRpLaunchUrl(rp),
|
||||
autoLoginSupported: rp.autoLoginSupported,
|
||||
lastAuthDateTime: rp.lastAuthenticatedAt,
|
||||
),
|
||||
);
|
||||
@@ -1393,6 +1394,16 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
color: _ink,
|
||||
),
|
||||
),
|
||||
if (item.autoLoginSupported) ...[
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
tr(
|
||||
'msg.userfront.dashboard.auto_login_supported',
|
||||
fallback: '연동앱 클릭 시 별도 로그인 없이 로그인할 수 있습니다.',
|
||||
),
|
||||
style: TextStyle(fontSize: 12, color: Colors.green[700]),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 14),
|
||||
Row(
|
||||
children: [
|
||||
@@ -2421,6 +2432,7 @@ class _ActivityItem {
|
||||
final String status;
|
||||
final String? url;
|
||||
final String? launchUrl;
|
||||
final bool autoLoginSupported;
|
||||
final List<String> scopes;
|
||||
final bool isRevoked;
|
||||
final VoidCallback? onRevoke;
|
||||
@@ -2435,6 +2447,7 @@ class _ActivityItem {
|
||||
required this.scopes,
|
||||
this.url,
|
||||
this.launchUrl,
|
||||
this.autoLoginSupported = false,
|
||||
this.isRevoked = false,
|
||||
this.onRevoke,
|
||||
this.lastAuthDateTime,
|
||||
|
||||
@@ -6,6 +6,8 @@ LinkedRp _linkedRp({
|
||||
required String status,
|
||||
String url = '',
|
||||
String initUrl = '',
|
||||
bool autoLoginSupported = false,
|
||||
String autoLoginUrl = '',
|
||||
}) {
|
||||
return LinkedRp(
|
||||
id: 'client-1',
|
||||
@@ -13,6 +15,8 @@ LinkedRp _linkedRp({
|
||||
logo: '',
|
||||
url: url,
|
||||
initUrl: initUrl,
|
||||
autoLoginSupported: autoLoginSupported,
|
||||
autoLoginUrl: autoLoginUrl,
|
||||
status: status,
|
||||
scopes: const ['openid', 'profile'],
|
||||
lastAuthenticatedAt: null,
|
||||
@@ -27,20 +31,25 @@ void main() {
|
||||
'status': 'active',
|
||||
'url': 'https://example.com',
|
||||
'init_url': 'https://sso.example.com/oidc/oauth2/auth?client_id=client-1',
|
||||
'auto_login_supported': true,
|
||||
'auto_login_url': 'https://example.com/login?auto=1',
|
||||
});
|
||||
|
||||
expect(
|
||||
rp.initUrl,
|
||||
'https://sso.example.com/oidc/oauth2/auth?client_id=client-1',
|
||||
);
|
||||
expect(rp.autoLoginSupported, isTrue);
|
||||
expect(rp.autoLoginUrl, 'https://example.com/login?auto=1');
|
||||
});
|
||||
|
||||
test('활성 앱은 initUrl을 우선 진입 URL로 사용한다', () {
|
||||
test('자동 로그인 지원 앱은 initUrl을 우선 진입 URL로 사용한다', () {
|
||||
final launchUrl = resolveLinkedRpLaunchUrl(
|
||||
_linkedRp(
|
||||
status: 'active',
|
||||
url: 'https://example.com',
|
||||
initUrl: 'https://sso.example.com/oidc/oauth2/auth?client_id=client-1',
|
||||
autoLoginSupported: true,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -50,7 +59,20 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
test('활성 앱은 initUrl이 없으면 기존 url로 폴백한다', () {
|
||||
test('자동 로그인 미지원 앱은 initUrl이 있어도 기존 url로 폴백한다', () {
|
||||
final launchUrl = resolveLinkedRpLaunchUrl(
|
||||
_linkedRp(
|
||||
status: 'active',
|
||||
url: 'https://example.com',
|
||||
initUrl: 'https://sso.example.com/oidc/oauth2/auth?client_id=client-1',
|
||||
autoLoginSupported: false,
|
||||
),
|
||||
);
|
||||
|
||||
expect(launchUrl, 'https://example.com');
|
||||
});
|
||||
|
||||
test('활성 앱은 자동 로그인 URL이 없으면 기존 url로 폴백한다', () {
|
||||
final launchUrl = resolveLinkedRpLaunchUrl(
|
||||
_linkedRp(status: 'active', url: 'https://example.com'),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user