How to authenticate to REST API and map to Fabric credentials - hyperledger

How can I create a new user account with username/password to authenticate against composer-rest-server?
How would I authenticate with this newly created user account against composer-rest-server?
How would I manage the session for that user?
How can I map this user to a network participant?
Can composer-rest-server user be mapped to more then one network participant (i.e. perform different roles)?
Do I need to create a wallet for each composer-rest-server user?
How would I share wallets across number of instances of composer-rest-server?

In Composer, you can model participant types, such as org.acme.Person. You can then create instances of those participant types, such as org.acme.Person#simon, and those instances are stored in participant registries.
You can then issue an identity to an instance of a participant. This process generates an enrolment ID and secret that can be sent to that participant so they can enrol. One identity is linked to one participant, but one participant can have multiple identities.
When a participant enrols using the enrolment ID and secret, an enrolment certificate is generated and placed into their wallet (configured using the keyValStore property in the connection profile). Once the enrolment certificate has been generated, the enrolment secret is made invalid. The secret can be only used one time - it is not a password.
If an enrolment certificate already exists in the wallet, then enrolment secret is not used. We have planned some future changes to make the enrolment secret optional in all APIs and CLIs so you can omit it.
When that participant submits a transaction using that enrolment certificate, the Composer chaincode extracts the enrolment ID from the enrolment certificate, and uses it to look up the participant instance that the identity was issued to. This is the "current participant".
All Composer based access control, using the rules defined in permissions.acl, is based around the current participant.
Currently, the Composer REST server supports a single enrolment ID which is specified on the command line at startup. All REST API calls to the Composer REST server use this enrolment certificate to submit transactions.
There is work being done at the moment to improve this:
https://github.com/hyperledger/composer/issues/142
Please read this GitHub issue in detail. Since this work is still in-progress, there is no user documentation for configuring Composer REST server security.
There are some interesting requirements in your list:
How would I manage the session for that user?
There are API keys, but there is no easy way to retrieve or manage API keys. I have ideas about extending the REST server UI (Swagger UI) to manage API keys, but nothing concrete yet.
Can composer-rest-server user be mapped to more then one network participant (i.e. perform different roles)?
A users wallet can currently contain multiple identities, but only one of them is used by default. The user can choose the default identity by submitting a REST API call. Is that sufficient?
Do I need to create a wallet for each composer-rest-server user?
Each user has their own set of wallets. A default wallet is created when the user logins for the first time. A user can create multiple wallets, but only one of them is used by default. The user can choose the default wallet by submitting a REST API call. Are you looking to share wallets between users?
How would I share wallets across number of instances of composer-rest-server?
You need to use a persistent data store such as MongoDB to persist the wallet data across multiple instances; again, this is work in-progress and not yet documented.
I suggest that since this is in-progress work we move the discussion to the GitHub issue :-)

Related

Stripe Connect with React and API only Rails

I'm having some issues with Stripe Connect. I have an API only backend in Rails and a frontend in React. I have successfully created Connect Accounts for new businesses which register in my frontend. However when a customer wants to buy something from the business, the payment doesn't work.
I create a Stripe::PaymentIntent in my rails backend when the frontend calls /business/payment_secret and return the client secret which is provided by the Payment Intent. The frontend then calls stripe.confirmCardPayment with the given client secret and the card which was used in the form. However, I always get "No such payment intent" error.
I've read somewhere that I need to add the stripeAccount config to the stripe object which is plugged into Elements. I tried to plug in the stripe account id of the business the customer is purchasing from but it didn't work.
Also it was very awkward to create the stripe object which has the business the customer is purchasing from can change depending on which items the user adds to the cart. Is there a standard way of doing that?
Or how does the payment process for connected accounts look like with an API only backend and a react frontend?
Thanks in advance
You need to review the various charge types to determine which fits your business needs, combined with the account type(s) you're using.
It sounds like you might be creating "direct charge" payment intents using the stripe-account header on your server then trying to confirm them in the client without that. You'll need to initialize Stripe.js using the same stripeAccount option.
The issue you're referring to with multiple potential accounts is one to think about in your customer flow. What if a customer wants to buy two items from two different connected accounts? For that flow you'd need to change your integration to use separate charges and transfers.

Advice on multiple projects sharing authentication (DRF)

I'm looking for some advice on setting up one authentication service for multiple different django projects.
Currently, I have one project that uses AWS Cognito for auth (with django-cognito-jwt). Then I have a separate project that does the same thing using a different AWS Cognito user pool. These projects are not connected in any way. The current flow for each app looks like this:
(1) Go to one project and login via frontend
(2) Use AWS Amplify to authenticate user against cognito and return a JWT
(3) Hit my DRF API and call get_or_create_for_cognito to parse JWT
(4) If account is new, create Django User object in the database storing the ID from cognito
(4) If account already exists, lookup User record by cognito ID and return that
(5) With this returned user object, I can lookup groups and permissions associated with user to allow or disallow various endpoints.
My goal, is to have one cognito account allow a user to authenticate on both of the different projects.
I understand that I can just point both projects to the same "User" table, but a few different sites/blogs have talked about this being bad practice. Some people have mentioned introducing a 3rd django project that's sole responsibility is Authentication. However, most of the examples I have found are using django's built in authentication not cognito.
So at a high level I'm wondering if anyone has any idea for how to architect this, or any example project using cognito that might be helpful for me to read over.
Thanks for any help!!
I've also read over this similar post:
Multiple Django apps, shared authentication
but my requirements are different because I'm using JWT auth and cognito
I don't think you need much architecting. Why not just put two app clients on the same user pool? Then you simply target the same user pool from both apps, with different app ID's. Users will be shared, and each app gets its separate client config.

Authentication in hyperledger-composer app with OAuth2.0

I have built a hyperledger-composer application (angular front-end, connecting to composer-rest-server), from which, so far, authentication is missing.
Here is what I understand:
1.) An identity needs to be issued for each participant in the network
2.) A business network card needs to be created for the identity created in step 1.)
3.) The business network card needs to be added to the wallet of the rest server
4.) steps 1.) and 3.) can be done by calling REST endpoints provided by the REST server
What I don't understand is this:
Let's say the REST server has in its wallet a business network card for "John Doe". The business network card contains the participant ID and the associated identity.
Google OAuth2.0 is used for authentication.
When John Doe wants to login to the hyperledger-composer app, he is redirected to google, where he is asked to type in his google account email + password.
If the business network card contained John Doe's google account email (or his google account password), then a connection could be made between the business network card and the user (John Doe) trying to log in. But the business network card does NOT contain any information from John Doe's Google Account (neither email nor password).
So how can the application know that the user trying to log in has a business network card and is therefore eligible to log in? As far as I can see it, all the application can know is that the user trying to log in has a google account - but this does not mean that he/she also has a business network card and is hence eligible to use the application.
Put differently: I don't understand how OAuth2.0 can help with authentication given that the OAuth2.0 provider does not save any data from the hyperledger-app (such as participant id or identity) and the hyperledger-app does not save any data from the OAuth2.0 provider (such as Facebook user name or Google Account email).
Enabling OAth2.0 merely requires you to login first through your account before accessing the REST server, but does not actually connect to any wallet or participant. So it doesn't have too much use at this current state (in my opinion).
The workaround I've done is building a Node.js app with Passport and adding the desired authentication strategies, then when a user is created through Passport it also creates a participant on the composer-rest-server and links them.

Google Directory user list from an app

I am creating an iOS app for internal use. We have a Google Domain. As part of the functionality of the app, I want to be able to search for all users in that domain. This can already be done in Gmail, the Apple Mail app, and others.
I found that you can use the Admin SDK for users.list to do exactly what I want to do. I created a Client ID for the iOS app and authorized my app to perform users.list.
However, now I get a permissions error for users who sign in with OAuth2:
I found that you can create a service account to make API requests on your behalf if you delegate it to have the authority. I'm not sure if this is what I want to do since this seems more like something for a secure server to do rather than an app. I'm also not sure how this integrates with a user (from our domain) who signs in with OAuth being able to list our users.
Is it possible to list/search the users in a Google domain purely through OAuth / frontend app?
Aside from caching your own list, I think there are two ways to give users the ability to list all users:
A. Undocumented call to this GAL API:
https://www.google.com/m8/feeds/gal/your-domain-goes-here/full?alt=json (source). You can test this in the Google OAuth Playground by selecting the scope for the Contacts V3 API or using the string https://www.google.com/m8/feeds/.
B. In the Admin console, create an "all users" group. Assign to a newly created Admin Role. Grant the admin role "read" in Privileges > Admin API Privileges > Users > Read (checked).

Valence API that replaces the older WS UserManagementService

One of our integrations uses the D2LWS UserManagementService to convert a username to userId. We receive the username, firstname and lastname of the student when they click through an LTI request, but we need the numeric userId for some of the other Valence API calls.
We would like to reduce our dependency on the D2LWS before they are retired, so we are wondering if there is an equivalent Valence API call that can be used to do this conversion?
There are many ways for a client application to fill out its understanding of an LMS user identity's properties. It is also noteworthy to remember that the D2LWS platform is essentially optimized for service-to-service level operational trust, while the newer Valence platform is optimized for user-to-service operational trust -- this means that all Valence calls must happen in the context of some real, authenticated LMS user account (in the sense that in order to make calls, the client application must first request to acquire a user ID/Key pair for an authenticated user).
If your client service will always be contacted or prompted by the LMS with an LTI launch, then you will have enough capacity from that launch to begin (please see this detailed topic on combining Valence calls with LTI around our Remote Plugin service). There should be a real LMS user that would have initiated that launch somehow, from a logged-in LMS session. Therefore, after the LTI launch, your service can turn right around and make a call to the LMS to request user tokens for the currently auth'd user and this user should almost certainly be the LTI-launching user.
Typically, for services that get contacted from an LTI launch and then want to use Valence, we recommend that you establish a user context immediately after the launch and make a whoami call: this can serve multiple purposes -- it can establish that you have a dependable set of user tokens you can use to make Valence calls on behalf of the launching user, and you can use the information retrieved in the WhoAmIUser data structure to assist in filling out the context of your user identity.
For your particular purposes, the WhoAmIUser data structure contains the first name, last name, unique name (user name), and LMS profile identifier for the launching user, as well as the LMS user identifier (Identifier) property that you can use in the context of other Valence calls should you need to. However, you should also strongly consider a shift to the user-to-service approach: when all the calls take place within the context of a particular user, you may discover that your best route is employing all the "my" routes to fill out the user experience you present to a user -- keep in mind that the user's credentials you employ with your Valence API calls restrict your access to functionality and data exactly as that user would be restricted in the course of his or her normal interactions with the LMS through its web UI.

Resources