Skip to content

Add new functionality #275

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

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
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
6 changes: 6 additions & 0 deletions lib/solidpod.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,9 @@ export 'src/solid/api/rest_api.dart' show getResourcesInContainer;

// Function to get the latest log enties
export 'src/solid/api/common_permission.dart' show getLatestLog;

// Read encrypted/non-encrypted files stored in an external POD
export 'src/solid/read_external_pod.dart' show readExternalPod;

// Write to encrypted/non-encrypted files in an external POD
export 'src/solid/write_external_pod.dart' show writeExternalPod;
4 changes: 2 additions & 2 deletions lib/src/solid/api/common_permission.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ Map<dynamic, dynamic> getLatestLog(
final logEntry = logDataMap[dataKey]['${appsData}log'].first;
final logEntryList = logEntry.split(';');

final ownerWebId = logEntryList[2];
final recepientWebId = logEntryList[5];

if (userWebId != null) {
if (ownerWebId == userWebId) {
if (recepientWebId != userWebId) {
continue;
}
}
Expand Down
8 changes: 6 additions & 2 deletions lib/src/solid/api/grant_permission_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import 'package:solidpod/src/solid/api/rest_api.dart';
import 'package:solidpod/src/solid/constants/common.dart';
import 'package:solidpod/src/solid/constants/schema.dart';
import 'package:solidpod/src/solid/constants/web_acl.dart';
import 'package:solidpod/src/solid/utils/authdata_manager.dart';
// import 'package:solidpod/src/solid/utils/authdata_manager.dart';
import 'package:solidpod/src/solid/utils/permission.dart';
import 'package:solidpod/src/solid/utils/misc.dart';

Expand All @@ -51,6 +51,7 @@ import 'package:solidpod/src/solid/utils/misc.dart';
/// representing the result of the operation.
Future<String> setPermissionAcl(
String resourceUrl,
String ownerWebId,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For methods that now take ownerWebID and removerWebId as required positional parameters:

  1. Will callers that still use the old signatures fail to compile?
  2. Could we potentially make these new parameters optional named arguments (with sensible defaults) to preserve source compatibility?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ashley, this, unfortunately, cannot be made optional. The old function did not have the functionality to set permission when the permission giver and the owner are two different people. So adding that functionality means we have to stop using the old version.

RecipientType recipientType,
List<dynamic> recipientWebIdList,
List<dynamic> permissionList, [
Expand All @@ -63,7 +64,9 @@ Future<String> setPermissionAcl(
// Extract permission details to a map
final permMap = extractAclPerm(aclContent);

final ownerWebId = await AuthDataManager.getWebId();
// av: owner webid is now an input parameter for the function to allow other
// owners from external resources.
//final ownerWebId = await AuthDataManager.getWebId();

// Updated individual permission map
final updatedIndPermMap = <String, Set<AccessMode>>{};
Expand Down Expand Up @@ -158,6 +161,7 @@ Future<String> setPermissionAcl(

final aclFullContentStr = await genAclTurtle(
resourceUrl,
externalWebId: ownerWebId,
fileFlag: fileFlag,
ownerAccess: {AccessMode.read, AccessMode.write, AccessMode.control},
publicAccess: publicPermSet,
Expand Down
6 changes: 4 additions & 2 deletions lib/src/solid/api/rest_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,10 @@ Future<({List<String> subDirs, List<String> files})> getResourcesInContainer(
}

/// Check if a file is encrypted
Future<bool> checkFileEnc(String fileUrl) async =>
KeyManager.hasIndividualKey(fileUrl);
Future<bool> checkFileEnc(String fileUrl, {bool isExternalRes = false}) async =>
isExternalRes
? KeyManager.hasSharedIndividualKey(fileUrl)
: KeyManager.hasIndividualKey(fileUrl);

/// Update ACL file of a resource by http put request
///
Expand Down
7 changes: 5 additions & 2 deletions lib/src/solid/api/revoke_permission_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ import 'package:solidpod/src/solid/api/rest_api.dart';
import 'package:solidpod/src/solid/constants/common.dart';
import 'package:solidpod/src/solid/constants/schema.dart';
import 'package:solidpod/src/solid/constants/web_acl.dart';
import 'package:solidpod/src/solid/utils/authdata_manager.dart';
import 'package:solidpod/src/solid/utils/permission.dart';
import 'package:solidpod/src/solid/utils/misc.dart';

/// Remove permission from ALC file by running a Sparql DELETE query
Future<String> removePermissionAcl(
String resourceName,
String resourceUrl,
String ownerWebId,
String removerId,
RecipientType recipientType, [
bool fileFlag = true,
Expand All @@ -56,7 +56,9 @@ Future<String> removePermissionAcl(
// Extract permission details to a map
final permMap = extractAclPerm(aclContent);

final ownerWebId = await AuthDataManager.getWebId();
// av: owner webid is now an input parameter for the function to allow other
// owners from external resources.
// final ownerWebId = await AuthDataManager.getWebId();

// Updated individual permission map
final updatedIndPermMap = <String, Set<AccessMode>>{};
Expand Down Expand Up @@ -124,6 +126,7 @@ Future<String> removePermissionAcl(

final aclFullContentStr = await genAclTurtle(
resourceUrl,
externalWebId: ownerWebId,
fileFlag: fileFlag,
ownerAccess: {AccessMode.read, AccessMode.write, AccessMode.control},
publicAccess: publicPermSet,
Expand Down
63 changes: 44 additions & 19 deletions lib/src/solid/grant_permission.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,35 +47,45 @@ import 'package:solidpod/src/solid/api/grant_permission_api.dart';

/// Grant permission to [fileName] for a given [recipientWebIdList].
/// Parameters:
/// [fileName] is the name of the file providing permission to
/// [fileName] is the name of the file providing permission to. In case where
/// [isExternalRes] is set to true, [fileName] should be the full URL of the file
/// [fileFlag] is the flag to identify if the resources is a file or not
/// [permissionList] is the list of permission to be granted
/// [recipientType] is the type of the recipient
/// [recipientWebIdList] is the list of webIds of the permission receivers
/// [isFileEncrypted] is the flag to determine if the file is encrypted or not
/// [ownerWebId] is the web ID of the owner of the file
/// [child] is the child widget to return to
/// [isExternalRes] is the flag to identify if the resource is external
/// [groupName] is the name of the group permission

Future<dynamic> grantPermission(
String fileName,
bool fileFlag,
List<dynamic> permissionList,
RecipientType recipientType,
List<dynamic> recipientWebIdList,
bool isFileEncrypted,
String ownerWebId,
BuildContext context,
Widget child, [
Widget child, {
bool isExternalRes = false,
String? groupName,
]) async {
}) async {
final loggedIn = await loginIfRequired(context);

if (loggedIn) {
await getKeyFromUserIfRequired(context, child);

// Get the file path
final filePath = [await getDataDirPath(), fileName].join('/');
var resourceUrl = '';

// Get the url of the file
final resourceUrl = await getFileUrl(filePath);
if (!isExternalRes) {
// Get the file path
final filePath = [await getDataDirPath(), fileName].join('/');

// Get the url of the file
resourceUrl = await getFileUrl(filePath);
} else {
resourceUrl = fileName;
}

// Check if file exists
final resStatus =
Expand All @@ -95,20 +105,24 @@ Future<dynamic> grantPermission(
// Add the permission line to the relevant ACL file
await setPermissionAcl(
resourceUrl,
ownerWebId,
recipientType,
recipientWebIdList,
permissionList,
groupName,
);

// Check if the file is encrypted
final fileIsEncrypted = await checkFileEnc(resourceUrl);
final fileIsEncrypted =
await checkFileEnc(resourceUrl, isExternalRes: isExternalRes);

// If the file is encrypted then share the individual encryption key
// with the receiver
if (fileIsEncrypted) {
// Get the individual encryption key for the file
final indKey = await KeyManager.getIndividualKey(resourceUrl);
final indKey = isExternalRes
? await KeyManager.getSharedIndividualKey(resourceUrl)
: await KeyManager.getIndividualKey(resourceUrl);

if ([RecipientType.individual, RecipientType.group]
.contains(recipientType)) {
Expand Down Expand Up @@ -158,10 +172,6 @@ Future<dynamic> grantPermission(
}

// Add log entry to owner, granter, and receiver permission log files
// av20240703: At this instance the owner and the granter are the same
// At some point we might need to change this function so that
// it can be used in the instances where owner is different from
// the granter

// Get user webID
final userWebId = await AuthDataManager.getWebId() as String;
Expand All @@ -170,23 +180,38 @@ Future<dynamic> grantPermission(
final logEntryRes = createPermLogEntry(
permissionList,
resourceUrl,
userWebId,
ownerWebId,
'grant',
userWebId,
recipientWebId as String,
);

// Log file urls of the owner, granter, and receiver
final logFilePath = await getPermLogFilePath();
final ownerLogFileUrl = await getFileUrl(logFilePath);

// Run log entry insert query for the owner
// Owner
final ownerLogFileUrl = await getFileUrl(logFilePath, ownerWebId);

// Granter
final granterLogFileUrl = await getFileUrl(logFilePath);

// Run log entry insert query for the granter
await addPermLogLine(
ownerLogFileUrl,
granterLogFileUrl,
logEntryRes[0] as String,
logEntryRes[1] as String,
);

// If owner and the granter is not the same add another log file entry
// for the owner
if (ownerLogFileUrl != granterLogFileUrl) {
await addPermLogLine(
ownerLogFileUrl,
logEntryRes[0] as String,
logEntryRes[1] as String,
);
}

// Add log entry if the recipient is either an individual or group of WebIDs
if ([RecipientType.individual, RecipientType.group]
.contains(recipientType)) {
Expand Down
Loading