mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-27 04:56:48 +00:00
Company create (#610)
* API: refactor checkPermission - Rename to checkRole (actually what it is doing) - Permission check will be incoming * Add checkPermission function for API * Create a new company * Bump release notes * Cleanup * Fix
This commit is contained in:
parent
0c5944a8a0
commit
1a3f48f48c
@ -1,3 +1,8 @@
|
||||
### 0.18.0 - February 2025
|
||||
---
|
||||
- Adds ability to create new companies from the app
|
||||
- Updated translations
|
||||
|
||||
### 0.17.4 - January 2025
|
||||
---
|
||||
- Display responsible owner for orders
|
||||
|
79
lib/api.dart
79
lib/api.dart
@ -237,9 +237,12 @@ class InvenTreeAPI {
|
||||
|
||||
UserProfile? profile;
|
||||
|
||||
// Available user roles (permissions) are loaded when connecting to the server
|
||||
// Available user roles are loaded when connecting to the server
|
||||
Map<String, dynamic> roles = {};
|
||||
|
||||
// Available user permissions are loaded when connecting to the server
|
||||
Map<String, dynamic> permissions = {};
|
||||
|
||||
// Profile authentication token
|
||||
String get token => profile?.token ?? "";
|
||||
|
||||
@ -701,12 +704,11 @@ class InvenTreeAPI {
|
||||
|
||||
var data = response.asMap();
|
||||
|
||||
if (data.containsKey("roles")) {
|
||||
// Save a local copy of the user roles
|
||||
roles = (response.data["roles"] ?? {}) as Map<String, dynamic>;
|
||||
if (!data.containsKey("roles")) {
|
||||
|
||||
roles = {};
|
||||
permissions = {};
|
||||
|
||||
return true;
|
||||
} else {
|
||||
showServerError(
|
||||
apiUrl,
|
||||
L10().serverError,
|
||||
@ -714,6 +716,11 @@ class InvenTreeAPI {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
roles = (data["roles"] ?? {}) as Map<String, dynamic>;
|
||||
permissions = (data["permissions"] ?? {}) as Map<String, dynamic>;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Request plugin information from the server
|
||||
@ -740,9 +747,9 @@ class InvenTreeAPI {
|
||||
|
||||
/*
|
||||
* Check if the user has the given role.permission assigned
|
||||
* e.g. "part", "change"
|
||||
* e.g. "sales_order", "change"
|
||||
*/
|
||||
bool checkPermission(String role, String permission) {
|
||||
bool checkRole(String role, String permission) {
|
||||
|
||||
if (!_connected) {
|
||||
return false;
|
||||
@ -750,17 +757,17 @@ class InvenTreeAPI {
|
||||
|
||||
// If we do not have enough information, assume permission is allowed
|
||||
if (roles.isEmpty) {
|
||||
debug("checkPermission - no roles defined!");
|
||||
debug("checkRole - no roles defined!");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!roles.containsKey(role)) {
|
||||
debug("checkPermission - role '$role' not found!");
|
||||
debug("checkRole - role '$role' not found!");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (roles[role] == null) {
|
||||
debug("checkPermission - role '$role' is null!");
|
||||
debug("checkRole - role '$role' is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -773,7 +780,7 @@ class InvenTreeAPI {
|
||||
} else {
|
||||
// Unknown error - report it!
|
||||
sentryReportError(
|
||||
"api.checkPermission",
|
||||
"api.checkRole",
|
||||
error, stackTrace,
|
||||
context: {
|
||||
"role": role,
|
||||
@ -788,6 +795,54 @@ class InvenTreeAPI {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the user has the particular model permission assigned
|
||||
* e.g. "company", "add"
|
||||
*/
|
||||
bool checkPermission(String model, String permission) {
|
||||
if (!_connected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (permissions.isEmpty) {
|
||||
// Not enough information available - default to True
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!permissions.containsKey(model)) {
|
||||
debug("checkPermission - model '$model' not found!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (permissions[model] == null) {
|
||||
debug("checkPermission - model '$model' is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
List<String> perms = List.from(permissions[model] as List<dynamic>);
|
||||
return perms.contains(permission);
|
||||
} catch (error, stackTrace) {
|
||||
if (error is TypeError) {
|
||||
// Ignore TypeError
|
||||
} else {
|
||||
// Unknown error - report it!
|
||||
sentryReportError(
|
||||
"api.checkPermission",
|
||||
error, stackTrace,
|
||||
context: {
|
||||
"model": model,
|
||||
"permission": permission,
|
||||
"error": error.toString(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Unable to determine permission - assume true?
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Perform a PATCH request
|
||||
Future<APIResponse> patch(String url, {Map<String, dynamic> body = const {}, int? expectedStatusCode}) async {
|
||||
|
@ -212,7 +212,7 @@ class InvenTreeModel {
|
||||
// Test if the user can "edit" this model
|
||||
bool get canEdit {
|
||||
for (String role in rolesRequired) {
|
||||
if (InvenTreeAPI().checkPermission(role, "change")) {
|
||||
if (InvenTreeAPI().checkRole(role, "change")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -224,7 +224,7 @@ class InvenTreeModel {
|
||||
// Test if the user can "create" this model
|
||||
bool get canCreate {
|
||||
for (String role in rolesRequired) {
|
||||
if (InvenTreeAPI().checkPermission(role, "add")) {
|
||||
if (InvenTreeAPI().checkRole(role, "add")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -236,7 +236,7 @@ class InvenTreeModel {
|
||||
// Test if the user can "delete" this model
|
||||
bool get canDelete {
|
||||
for (String role in rolesRequired) {
|
||||
if (InvenTreeAPI().checkPermission(role, "delete")) {
|
||||
if (InvenTreeAPI().checkRole(role, "delete")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -248,7 +248,7 @@ class InvenTreeModel {
|
||||
// Test if the user can "view" this model
|
||||
bool get canView {
|
||||
for (String role in rolesRequired) {
|
||||
if (InvenTreeAPI().checkPermission(role, "view")) {
|
||||
if (InvenTreeAPI().checkRole(role, "view")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -234,6 +234,9 @@
|
||||
"company": "Company",
|
||||
"@company": {},
|
||||
|
||||
"companyAdd": "Add Company",
|
||||
"@companyAdd": {},
|
||||
|
||||
"companyEdit": "Edit Company",
|
||||
"@companyEdit": {},
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_speed_dial/flutter_speed_dial.dart";
|
||||
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
|
||||
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
@ -35,6 +37,48 @@ class _CompanyListWidgetState extends RefreshableState<CompanyListWidget> {
|
||||
@override
|
||||
String getAppBarTitle() => widget.title;
|
||||
|
||||
Future<void> _addCompany(BuildContext context) async {
|
||||
|
||||
InvenTreeCompany().createForm(
|
||||
context,
|
||||
L10().companyAdd,
|
||||
data: widget.filters,
|
||||
onSuccess: (result) async {
|
||||
Map<String, dynamic> data = result as Map<String, dynamic>;
|
||||
|
||||
if (data.containsKey("pk")) {
|
||||
var company = InvenTreeCompany.fromJson(data);
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => CompanyDetailWidget(company)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<SpeedDialChild> actionButtons(BuildContext context) {
|
||||
List<SpeedDialChild> actions = [];
|
||||
|
||||
if (InvenTreeAPI().checkPermission("company", "add")) {
|
||||
actions.add(
|
||||
SpeedDialChild(
|
||||
child: Icon(TablerIcons.circle_plus, color: Colors.green),
|
||||
label: L10().companyAdd,
|
||||
onTap: () {
|
||||
_addCompany(context);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget getBody(BuildContext context) {
|
||||
return PaginatedCompanyList(widget.title, widget.filters);
|
||||
|
@ -183,7 +183,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> with BaseWidgetPr
|
||||
bool allowed = true;
|
||||
|
||||
if (role.isNotEmpty || permission.isNotEmpty) {
|
||||
allowed = InvenTreeAPI().checkPermission(role, permission);
|
||||
allowed = InvenTreeAPI().checkRole(role, permission);
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: inventree
|
||||
description: InvenTree stock management
|
||||
|
||||
version: 0.17.4+96
|
||||
version: 0.18.0+97
|
||||
|
||||
environment:
|
||||
sdk: ">=2.19.5 <3.13.0"
|
||||
|
@ -117,10 +117,10 @@ void main() {
|
||||
assert(api.roles.isNotEmpty);
|
||||
|
||||
// Check available permissions
|
||||
assert(api.checkPermission("part", "change"));
|
||||
assert(api.checkPermission("stock_location", "delete"));
|
||||
assert(!api.checkPermission("part", "weirdpermission"));
|
||||
assert(api.checkPermission("blah", "bloo"));
|
||||
assert(api.checkRole("part", "change"));
|
||||
assert(api.checkRole("stock_location", "delete"));
|
||||
assert(!api.checkRole("part", "weirdpermission"));
|
||||
assert(api.checkRole("blah", "bloo"));
|
||||
|
||||
debugContains("Received token from server");
|
||||
debugContains("showSnackIcon: 'Connected to Server'");
|
||||
|
Loading…
x
Reference in New Issue
Block a user