Update Hyperledger ACL from transactions - blockchain

I have User and Buyer participants on the network. Generally, the buyers cannot READ the user's data but I want to make GrantAccess and RevokeAccess transactions so the Users to have the option to grant and revoke the READ access from Buyers
I haven't been able to find anything on how to do this, would appreciate any help.

You would run a 'tx_GrantAccess' transaction that firstly, updates a particular BUYER's record (eg. id buyer123 - a participant modeled with a field called access, which is set to true by this transaction).
I can use a condition match (as a boolean) on the target BUYER records (resources) and if the BUYER, say buyer123 (ie that's accessing the business network) has access=true then he can READ the USER records.
Transaction rule (needed by User to access the transaction classes)
rule rule_1 {
description: "grant access to User, for the 2 x Transactions themselves"
participant: "org.acme.example.User"
operation: CREATE
resource: "org.acme.example.tx_*"
action: ALLOW
}
User Access rule:
rule rule_2 {
description: "if granted access, allow READ of User by buyer"
participant(m): "org.acme.example.Buyer"
operation: READ
resource(v): "org.acme.example.User"
condition: (m.access)
action: ALLOW
}
where Buyer has a field (eg.
participant Buyer identified by id {
o String id
o Boolean access default=false
}
and your transaction tx_GrantAccess has a function that will set access to true on a particular Buyer's record and tx_RevokeAccess will set it to false etc.

Related

AWS Amplify combine authorization rules

I have a multi tenant application in AWS Amplify, I'm using the Custom-attribute-based multi-tenancy described here
All models have a composite key with "company" being the unique tenant ID, and the cognito user pool has a custom attribute custom:company which links the user to the tenant data.
Example type below:
type Customer #model
#key(fields: ["company", "id"])
#auth(rules: [
{ allow: owner, ownerField: "company", identityClaim: "custom:company"},
{ allow: groups, groups: ["Member"], operations: [read] },
{ allow: groups, groups: ["Admin"]},
])
{
company: ID!
id: ID!
...
}
I want to add user groups to cognito to manage the operations that different users can perform - e.g. Admin users can perform all operations, but Member users can only perform read
The problem is the first owner auth rule will match for anyone with the matching custom:company attribute, regardless of their Group.
Is there a way to combine owner and group #auth rules - i.e. both owner and groups needs to pass to have access to an item?
For example - users of the Member group is allowed but only when their custom:company attribute matches the company of the model
Another example - anyone with a matching custom:company attribute have access to an item but Members can only read

How to restrict user from accessing pages in Oracle Apex

I am very upset with this oracle apex, their is no proper practical example or demonstration on Oracle Apex
I have built one application where I have 4 pages -> Home , My account , Calculate gross
If my Role : Admin and Name : Raj … I should have access to all my above pages
If my Role : user and Name : Bob … I should have access only to page : Home and Calculate gross and remaining pages should be hide
Following is my table details : employee
Name , Age , Role
Raj , 24 , Admin
Bob , 26 , User
Note : I am using SSO login
You should create authorization schemes - it is done within "Shared components" section. For example, you can create the one whose name is "full_access", its type is "PL/SQL function returning Boolean".
Code depends on what "role" and "name" actually represent; I presume that they are stored into some table. In that case, and if you created Apex users whose username matches name you mentioned (e.g. Raj and Bob), that would be
declare
l_role t_users.role%type;
begin
select t.role
into l_role
from t_users
where name = :APP_USER; --> APP_USER is username of currently logged user
return l_role = 'Admin'; --> if role is "Admin", function would return TRUE
end;
(Feel free to improve it.)
Then go to the page itself, check its (page's) properties - scroll down to the "Security" section and set the "Authorization scheme" property to "full access".
Doing so, any APP_USER whose role isn't "Admin", won't have access to that page.

Handle a transaction with 2 signers and make one of them pay

I have this account:
#[derive(Accounts)]
pub struct SignupEmployee<'info> {
#[account(init, payer = company_account, space = 8 + 32 + 32)]
pub employee_account: Account<'info, EmployeeState>,
#[account(mut)]
pub company_account: Signer<'info>,
#[account(mut)]
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
}
And this test function
const employeeAccount = anchor.web3.Keypair.generate();
await program.rpc.signupEmployee({
accounts: {
authority: provider.wallet.publicKey,
companyAccount: companyAccount.publicKey,
employeeAccount: employeeAccount.publicKey,
systemProgram: SystemProgram.programId,
},
signers: [employeeAccount, companyAccount],
});
What I want to achieve is to make the company pay for the employee signup.
Basically on my system I will have both the keys of the company and the keys of the employee.
The employee will signup with his key and the company would have to pay for the transaction.
I see that the signers is an array, so I imagine that I can enter both, the company and the employee accounts.
How can I achieve this?
The Transaction object in the solana web3 package has a feePayer field which you are supposed to set to the public key of the account you wish to pay for the transaction. Then that account needs to also sign the transaction.
Feel free to look into the documentation for the Transaction class here
in your instruction you already assigning company_account as payer for the new account initialisation, so i'm assuming that you are wondering how to pay gas fee with the same account. You could use program.instruction.signupEmployee which will output transaction instruction that you could add to the custom transaction where you can specify a gas fee payer. This way you would need to sign and send transaction using your custom code.

Code fails to update a table on BQ using DML, but succeeds for insertion and deletion with RPC

I wrote some code that uses service-account to write to BQ on google-cloud.
A very strange thing is that only "update" operation using DML fails. (Other insertion, deletion RPC calls succeeds).
def create_table(self, table_id, schema):
table_full_name = self.get_table_full_name(table_id)
table = self.get_table(table_full_name)
if table is not None:
return # self.client.delete_table(table_full_name, not_found_ok=True) # Make an API
# request. # print("Deleted table '{}'.".format(table_full_name))
table = bigquery.Table(table_full_name, schema=schema)
table = self.client.create_table(table) # Make an API request.
print("Created table {}.{}.{}".format(table.project, table.dataset_id, table.table_id))
#Works!
def upload_rows_to_bq(self, table_id, rows_to_insert):
table_full_name = self.get_table_full_name(table_id)
for ads_chunk in split(rows_to_insert, _BQ_CHUNK_SIZE):
errors = self.client.insert_rows_json(table_full_name, ads_chunk,
row_ids=[None] * len(rows_to_insert)) # Make an API request.
if not errors:
print("New rows have been added.")
else:
print("Encountered errors while inserting rows: {}".format(errors))
#Permissions Failure
def update_bq_ads_status_removed(self, table_id, update_ads):
affected_rows = 0
table_full_name = self.get_table_full_name(table_id)
for update_ads_chunk in split(update_ads, _BQ_CHUNK_SIZE):
ad_ids = [item["ad_id"] for item in update_ads_chunk]
affected_rows += self.update_bq_ads_status(f"""
UPDATE {table_full_name}
SET status = 'Removed'
WHERE ad_id IN {tuple(ad_ids)}
""")
return affected_rows
I get this error for update only:
User does not have bigquery.jobs.create permission in project ABC.
I will elaborate on my comment.
In GCP you have 3 types of IAM roles.
Basic Roles
include the Owner, Editor, and Viewer roles.
Predefined Roles
provide granular access for a specific service and are managed by Google Cloud. Predefined roles are meant to support common use cases and access control patterns.
Custom Roles
provide granular access according to a user-specified list of permissions.
What's the difference between predefinied and custom roles? If you change (add/remove) permission for a predefinied role it will become custom role.
Predefinied roles for BigQuery with permissions list can be found here
Mentioned error:
User does not have bigquery.jobs.create permission in project ABC.
Means that IAM Role doesn't have specific BigQuery Permission - bigquery.jobs.create.
bigquery.jobs.create permission can be found in two predefinied roles like:
BigQuery Job User - (roles/bigquery.jobUser)
BigQuery User - (roles/bigquery.user)
Or can be added to a different predefinied role, however it would change to custom role.
Just for addition, in Testing Permission guide, you can find information on how to test IAM permissions.
Please give the service account the bigquery.user role and try to run the code again.
BigQuery Job User
role: bigquery.user

Designing model file in hyperledger composer

Considering a bank scenario , where participants are customers and transaction is money transfer , it can be as
asset Account identified by accountId{
o String accountId
--> Customer owner
o Double balance
}
transaction AccountTransfer {
--> Account from
--> Account to
o Double amount
}
But what if there are different types of Participants who holds accounts. Like one can only transfer(sender) and while other can only receive(receiver)?How to solve this as account cant have two types of owners.
Can this be like this?
asset account identified by accountId{
o String accountId
o Double balance
}
Participant sender identified by sid{
--> Account account
o String sId
}
Participant receiver identified by rid{
--> Account account
o String rId
}
Transaction send {
-->Sender sender
-->Receiver receiver
}
Is it appropriate to design the model like above?
Yes, it should work.
To be sure that only the sender can execute a transfer, you can implement a logic in the transaction processor, which arise an exception if the participant that is invoking the transaction is not a "sender".
Model
asset account identified by accountId{
o String accountId
o Double balance
}
Participant sender identified by sid{
--> Account account
o String sId
}
Participant receiver identified by rid{
--> Account account
o String rId
}
Transaction send {
-->Sender sender
-->Receiver receiver
}
TP
async function send(tx) {
if (currentParticipant.getFullyQualifiedType() !== 'org.example.sender') {
// Throw an error as the current participant is not a sender.
throw new Error('Current participant is not a sender');
}
//Other business logics
}
Otherwise you can implement a rule in the access control file which allow to transfer money only if who is invoking the transaction is a sender
rule AllowSenderToTransferMoney {
description: "Sender can transfer money"
participant(m): "org.example.sender"
operation: ALL
resource(v): "org.example.account"
transaction(tx): "org.example.send"
action: ALLOW
}