Skip to content
This repository has been archived by the owner on Jan 31, 2021. It is now read-only.

Commit

Permalink
Merge pull request #8 from halonproject/rewrite
Browse files Browse the repository at this point in the history
Rewrite to handle permissions and public/private buckets
  • Loading branch information
cpurta committed Aug 10, 2018
2 parents 49941b4 + fb7d9d6 commit 6e42449
Show file tree
Hide file tree
Showing 6 changed files with 1,481 additions and 1,872 deletions.
176 changes: 127 additions & 49 deletions contracts/Bucket.sol
Original file line number Diff line number Diff line change
@@ -1,77 +1,155 @@
pragma solidity ^0.4.18;
pragma solidity ^0.4.21;

import "./Ownable.sol";

contract Bucket is Ownable {
address public owner;
string[] private fileNames;
mapping (string => string) private fileHashes;
mapping (string => bool) private fileExists;
uint public lastFileId = 0;
mapping (uint => File) private files;

event FileAdded(string _filename, string _ipfsHash);
event FileRemoved(string _filename, string ipfsHash);
event FileHashUpdated(string _filename, string _newIPFSHash);
event FileRename(address indexed entity, uint fileId);
event FileContentUpdate(address indexed entity, uint fileId);
event NewFile(address indexed entity, uint fileId);
event NewWritePermission(address indexed entity, uint fileId);
event NewReadPermission(address indexed entity, uint fileId);
event DeleteFile(address indexed entity, uint fileId);

function Bucket() public {
struct File {
string storageRef;
string name;
uint fileSize;
bool isPublic;
bool isDeleted;
address fileOwner;
uint lastModified;
mapping (address => Permission) permissions;
address[] permissionAddresses;
}

struct Permission {
bool read;
bool write;
bool exists;
}

constructor() public {
owner = msg.sender;
}

function destroy() onlyOwner public {
function destroy() public onlyOwner {
selfdestruct(owner);
}

function addFile(string _filename, string _ipfsHash) public onlyOwner returns (bool) {
bytes memory _filenameBytes = bytes(_filename);
bytes memory _hashBytes = bytes(_filename);
if (fileExists[_filename] || _filenameBytes.length == 0 || _hashBytes.length == 0) {
return false;
}
function addFile(string _storageRef, string _name, uint _fileSize, bool _isPublic) public onlyOwner returns (uint) {
lastFileId = lastFileId + 1;

fileNames.push(_filename);
fileHashes[_filename] = _ipfsHash;
fileExists[_filename] = true;
emit FileAdded(_filename, _ipfsHash);
return true;
files[lastFileId] = File({
storageRef: _storageRef,
name: _name,
fileSize: _fileSize,
isPublic: _isPublic,
isDeleted: false,
fileOwner: owner,
lastModified: now,
permissionAddresses: new address[](0)
});
emit NewFile(owner, lastFileId);
return lastFileId;
}

function removeFile(string _filename) public onlyOwner returns (bool) {
if (!_fileExists(_filename)) {
return false;
}
function getFile(uint _fileId)
public
view
returns (
string storageRef,
string name,
uint fileSize,
bool isPublic,
bool isDeleted,
address fileOwner,
bool isOwner,
uint lastModified,
address[] permissionAddresses,
bool writeAccess
)
{
File storage file = files[_fileId];

for (uint i = 0; i < fileNames.length; i++) {
string memory filename = fileNames[i];
if (keccak256(filename) == keccak256(_filename)) {
fileNames[i] = fileNames[fileNames.length - 1];
delete fileNames[fileNames.length - 1];
fileNames.length--;
break;
}
}
storageRef = file.storageRef;
name = file.name;
fileSize = file.fileSize;
isPublic = file.isPublic;
isDeleted = file.isDeleted;
fileOwner = file.fileOwner;
isOwner = msg.sender == owner;
lastModified = file.lastModified;
permissionAddresses = file.permissionAddresses;
writeAccess = hasWriteAccess(_fileId, msg.sender);
}

function removeFile(uint _fileId) public onlyOwner {
files[_fileId].isDeleted = true;
files[_fileId].lastModified = now;
emit DeleteFile(owner, lastFileId);
}

string storage fileHash = fileHashes[_filename];
fileHashes[_filename] = "";
fileExists[_filename] = false;
emit FileRemoved(_filename, fileHash);
return true;
function setFileName(uint _fileId, string _newName) public {
require(hasWriteAccess(_fileId, msg.sender), "sender not authorized");

files[_fileId].name = _newName;
files[_fileId].lastModified = now;
emit FileRename(msg.sender, lastFileId);
}

function ipfsHash(string _filename) public view onlyOwner returns (string) { return fileHashes[_filename]; }
function setFileContent(uint _fileId, string _storageRef, uint _fileSize) public {
require(hasWriteAccess(_fileId, msg.sender), "sender not authorized");

files[_fileId].storageRef = _storageRef;
files[_fileId].fileSize = _fileSize;
files[_fileId].lastModified = now;
emit FileRename(msg.sender, lastFileId);
}

function setIPFSHash(string _filename, string _ipfsHash) public onlyOwner returns (bool) {
bytes memory _hashBytes = bytes(_ipfsHash);
if (!_fileExists(_filename) || _hashBytes.length == 0) {
return false;
function getPermissionAddresses(uint _fileId) public view returns (address[] addresses) {
return files[_fileId].permissionAddresses;
}

function getPermission(uint _fileId, address _entity) public view returns (bool write, bool read) {
Permission storage permission = files[_fileId].permissions[_entity];

write = permission.write;
read = permission.read;
}

function setWritePermission(uint _fileId, address _entity, bool _permission) public onlyOwner {
if (!files[_fileId].permissions[_entity].exists) {
files[_fileId].permissionAddresses.push(_entity);
files[_fileId].permissions[_entity].exists = true;
}

files[_fileId].permissions[_entity].write = _permission;
emit NewWritePermission(msg.sender, lastFileId);
}

function setReadPermission(uint _fileId, address _entity, bool _permission) public onlyOwner {
if (!files[_fileId].permissions[_entity].exists) {
files[_fileId].permissionAddresses.push(_entity);
files[_fileId].permissions[_entity].exists = true;
}

fileHashes[_filename] = _ipfsHash;
emit FileHashUpdated(_filename, _ipfsHash);
return true;
files[_fileId].permissions[_entity].read = _permission;
emit NewWritePermission(msg.sender, lastFileId);
}

function totalFiles() public view returns (uint256) { return fileNames.length; }
function hasWriteAccess(uint _fileId, address _entity) public view returns (bool){
return isOwner(_entity) || files[_fileId].permissions[_entity].write;
}

function hasReadAccess(uint _fileId, address _entity) public view returns (bool){
return isOwner(_entity) || files[_fileId].permissions[_entity].read;
}

function _fileExists(string _filename) internal view returns (bool) {
return fileExists[_filename];
function isOwner(address _entity) internal view returns (bool) {
return _entity == owner;
}
}
2 changes: 1 addition & 1 deletion contracts/Migrations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ contract Migrations {
if (msg.sender == owner) _;
}

function Migrations() public {
constructor() public {
owner = msg.sender;
}

Expand Down
10 changes: 5 additions & 5 deletions contracts/Ownable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ contract Ownable {
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
constructor() public {
owner = msg.sender;
}

/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
require(msg.sender == owner, "sender is not contract owner");
_;
}

Expand All @@ -35,7 +35,7 @@ contract Ownable {
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
require(newOwner != address(0), "cannot make 0 address as owner");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
Expand All @@ -44,8 +44,8 @@ contract Ownable {
* @dev Allows the current owner to relinquish control of the contract.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipRenounced(owner);
owner = address(0);
emit OwnershipRenounced(owner);
owner = address(0);
}

}
Loading

0 comments on commit 6e42449

Please sign in to comment.