Skip to content
Open
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
21 changes: 20 additions & 1 deletion lib/providers/collection_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/consts.dart';
import 'package:apidash/terminal/terminal.dart';
import 'package:better_networking/better_networking.dart';
import 'providers.dart';
import '../models/models.dart';
import '../services/services.dart';
Expand Down Expand Up @@ -216,6 +217,7 @@ class CollectionStateNotifier
String? id,
HTTPVerb? method,
AuthModel? authModel,
AuthInheritanceType? authInheritanceType,
String? url,
String? name,
String? description,
Expand Down Expand Up @@ -275,6 +277,7 @@ class CollectionStateNotifier
headers: headers ?? currentHttpRequestModel.headers,
params: params ?? currentHttpRequestModel.params,
authModel: authModel ?? currentHttpRequestModel.authModel,
authInheritanceType: authInheritanceType ?? currentHttpRequestModel.authInheritanceType,
isHeaderEnabledList: isHeaderEnabledList ??
currentHttpRequestModel.isHeaderEnabledList,
isParamEnabledList:
Expand Down Expand Up @@ -628,9 +631,25 @@ class CollectionStateNotifier
HttpRequestModel httpRequestModel) {
var envMap = ref.read(availableEnvironmentVariablesStateProvider);
var activeEnvId = ref.read(activeEnvironmentIdStateProvider);
var environments = ref.read(environmentsStateNotifierProvider);

// Handle auth inheritance
HttpRequestModel processedRequestModel = httpRequestModel;
if (httpRequestModel.authInheritanceType == AuthInheritanceType.environment &&
activeEnvId != null &&
environments != null &&
environments[activeEnvId] != null) {

final environment = environments[activeEnvId]!;
if (environment.defaultAuthModel != null) {
processedRequestModel = httpRequestModel.copyWith(
authModel: environment.defaultAuthModel,
);
}
}

return substituteHttpRequestModel(
httpRequestModel,
processedRequestModel,
envMap,
activeEnvId,
);
Expand Down
3 changes: 3 additions & 0 deletions lib/providers/environment_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:apidash/consts.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/utils/file_utils.dart';
import 'package:apidash_core/apidash_core.dart';
import 'package:better_networking/better_networking.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../services/services.dart' show hiveHandler, HiveHandler;

Expand Down Expand Up @@ -126,11 +127,13 @@ class EnvironmentsStateNotifier
String id, {
String? name,
List<EnvironmentVariableModel>? values,
AuthModel? defaultAuthModel,
}) {
final environment = state![id]!;
final updatedEnvironment = environment.copyWith(
name: name ?? environment.name,
values: values ?? environment.values,
defaultAuthModel: defaultAuthModel ?? environment.defaultAuthModel,
);
state = {
...state!,
Expand Down
115 changes: 69 additions & 46 deletions lib/screens/common_widgets/auth/auth_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:apidash_core/apidash_core.dart';
import 'package:better_networking/better_networking.dart';
import 'api_key_auth_fields.dart';
import 'basic_auth_fields.dart';
import 'bearer_auth_fields.dart';
Expand All @@ -12,16 +13,20 @@ import 'oauth2_field.dart';

class AuthPage extends StatelessWidget {
final AuthModel? authModel;
final AuthInheritanceType? authInheritanceType;
final bool readOnly;
final Function(APIAuthType? newType)? onChangedAuthType;
final Function(AuthModel? model)? updateAuthData;
final Function(AuthInheritanceType? newType)? onChangedAuthInheritanceType;

const AuthPage({
super.key,
this.authModel,
this.authInheritanceType,
this.readOnly = false,
this.onChangedAuthType,
this.updateAuthData,
this.onChangedAuthInheritanceType,
});

@override
Expand All @@ -41,61 +46,79 @@ class AuthPage extends StatelessWidget {
SizedBox(
height: 8,
),
ADPopupMenu<APIAuthType>(
value: authModel?.type.displayType,
values: APIAuthType.values
.map((type) => (type, type.displayType))
.toList(),
tooltip: kTooltipSelectAuth,
isOutlined: true,
onChanged: readOnly ? null : onChangedAuthType,
),
const SizedBox(height: 48),
switch (authModel?.type) {
APIAuthType.basic => BasicAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
),
APIAuthType.bearer => BearerAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
// Auth inheritance selection
if (!readOnly) ...[
ADPopupMenu<AuthInheritanceType>(
value: (authInheritanceType ?? AuthInheritanceType.none).displayType,
values: AuthInheritanceType.values
.map((type) => (type, type.displayType))
.toList(),
tooltip: "Select auth inheritance type",
isOutlined: true,
onChanged: onChangedAuthInheritanceType,
),
const SizedBox(height: 16),
],
// Show auth type selection only when not inheriting
if (authInheritanceType != AuthInheritanceType.environment) ...[
ADPopupMenu<APIAuthType>(
value: authModel?.type.displayType,
values: APIAuthType.values
.map((type) => (type, type.displayType))
.toList(),
tooltip: kTooltipSelectAuth,
isOutlined: true,
onChanged: readOnly ? null : onChangedAuthType,
),
const SizedBox(height: 48),
switch (authModel?.type) {
APIAuthType.basic => BasicAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
),
APIAuthType.bearer => BearerAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
),
APIAuthType.apiKey => ApiKeyAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
APIAuthType.apiKey => ApiKeyAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
),
APIAuthType.jwt => JwtAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
APIAuthType.jwt => JwtAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
),
APIAuthType.digest => DigestAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
APIAuthType.digest => DigestAuthFields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
),
APIAuthType.oauth1 => OAuth1Fields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
),
APIAuthType.oauth2 => OAuth2Fields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
APIAuthType.oauth2 => OAuth2Fields(
readOnly: readOnly,
authData: authModel,
updateAuth: updateAuthData,
),
APIAuthType.none =>
Text(readOnly ? kMsgNoAuth : kMsgNoAuthSelected),
_ => Text(readOnly
? "${authModel?.type.name} $kMsgAuthNotSupported"
: kMsgNotImplemented),
}
APIAuthType.none =>
Text(readOnly ? kMsgNoAuth : kMsgNoAuthSelected),
_ => Text(readOnly
? "${authModel?.type.name} $kMsgAuthNotSupported"
: kMsgNotImplemented),
}
] else ...[
const Text("Using environment inherited authentication"),
]
],
),
),
);
}
}
}
73 changes: 73 additions & 0 deletions lib/screens/envvar/environment_auth_editor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/consts.dart';
import 'package:better_networking/better_networking.dart';
import '../common_widgets/common_widgets.dart';

class EnvironmentAuthEditor extends ConsumerWidget {
const EnvironmentAuthEditor({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final environment = ref.watch(selectedEnvironmentModelProvider);

if (environment == null) {
return const SizedBox.shrink();
}

final defaultAuthModel = environment.defaultAuthModel;

return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Default Authentication",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
const SizedBox(height: 16),
const Text(
"Set default authentication for all requests using this environment",
style: TextStyle(
fontSize: 14,
),
),
const SizedBox(height: 24),
AuthPage(
authModel: defaultAuthModel,
readOnly: false,
onChangedAuthType: (newType) {
if (newType != null) {
final updatedAuthModel = defaultAuthModel?.copyWith(type: newType) ??
AuthModel(type: newType);
ref
.read(environmentsStateNotifierProvider.notifier)
.updateEnvironment(
environment.id,
values: environment.values,
defaultAuthModel: updatedAuthModel,
);
}
},
updateAuthData: (model) {
ref
.read(environmentsStateNotifierProvider.notifier)
.updateEnvironment(
environment.id,
values: environment.values,
defaultAuthModel: model,
);
},
),
],
),
);
}
}
52 changes: 37 additions & 15 deletions lib/screens/envvar/environment_editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/consts.dart';
import '../common_widgets/common_widgets.dart';
import './editor_pane/variables_pane.dart';
import 'environment_auth_editor.dart';

class EnvironmentEditor extends ConsumerWidget {
const EnvironmentEditor({super.key});
Expand All @@ -15,6 +16,7 @@ class EnvironmentEditor extends ConsumerWidget {
final id = ref.watch(selectedEnvironmentIdStateProvider);
final name = ref
.watch(selectedEnvironmentModelProvider.select((value) => value?.name));

return Padding(
padding: context.isMediumWindow
? kPb10
Expand Down Expand Up @@ -84,24 +86,44 @@ class EnvironmentEditor extends ConsumerWidget {
borderRadius: kBorderRadius12,
),
elevation: 0,
child: const Padding(
padding: kPv6,
child: DefaultTabController(
length: 2,
child: Column(
children: [
kHSpacer40,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width: 30),
Text("Variable"),
SizedBox(width: 30),
Text("Value"),
SizedBox(width: 40),
TabBar(
tabs: const [
Tab(text: "Variables"),
Tab(text: "Auth"),
],
),
kHSpacer40,
Divider(),
Expanded(child: EditEnvironmentVariables())
const Expanded(
child: TabBarView(
children: [
Padding(
padding: kPv6,
child: Column(
children: [
kHSpacer40,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width: 30),
Text("Variable"),
SizedBox(width: 30),
Text("Value"),
SizedBox(width: 40),
],
),
kHSpacer40,
Divider(),
Expanded(child: EditEnvironmentVariables())
],
),
),
EnvironmentAuthEditor(),
],
),
),
],
),
),
Expand All @@ -112,4 +134,4 @@ class EnvironmentEditor extends ConsumerWidget {
),
);
}
}
}
Loading