Explanation of Yesod route parsing - haskell

I'm building a library for Yesod which, I hope, will expose an interface for Stripe, the credit card processor. (I plan on releasing it soon. I gave up on Amazon because of its poorly documented API...)
I have created a subsite and typeclass to handle the routes the Stripe API needs. I managed to figure out the "how" of what I need to do, but I don't quite understand it.
The subsite has routes defined by:
mkYesodSubData "Stripe" [parseRoutes|
/charge/#StripeId ChargeR POST
/customer/#StripeId CustomerR POST
|]
and the parent has the route defined as:
/payment/stripe StripeR Stripe appStripe
Now, I'm curious about what this line actually means. For comparison, most other routes are defined like:
/questions QuestionsR GET
As far as I understand, the route generator generates a QuestionsR data type, and dispatches /questions to getQuestionsR. But what exactly is the route generator doing with
/payment/stripe StripeR Stripe appStripe
I suppose it must be creating a StripeR type. And I know that appStripe :: App -> Stripe. But what roles do these things play? How does the parser know to ensure that StripeR takes one of the Stripe routes as an argument? What's going on behind the scenes, and is the GET case a special case of the other pattern?

The GET isn't really a special case as I understand it, as we are explicitly creating a Resource that is a subsite.
The line in question
/payment/stripe StripeR Stripe appStripe
Says that the resource at /payment/stripe we are going to call StripeR and it's a Stripe (which is a subsite) that can be accessed with the appStripe function.
For example, when you are defining your foundation for the subsite you do something like
data Stripe = Stripe
But you could also do
data Stripe = Stripe {
getStripeConfig :: String
}
then in the Master site you co uld do in a handler
handler :: Handler Html
handler = do
app <- getYesod
let stripeConfig = getStripeConfig $ appStripe app
...

Related

How can I get all envelopes status and their signers status in one request?

Is it possible to call the DocuSign API with the "docusign-client"-library in order to get status information about all envelopes with all of their recipients/signers in one request?
When we call the "EnvelopesApi.ListStatusAsync" method of the docusign client library we just retrieve an array of envelopes but without the status information of their signees.
public async Task<EnvelopesInformation> GetListStatus(EnvelopeIdsRequest envelopeIds, ListStatusOptions opt) {
return await Request(async api => await api.ListStatusAsync(settings.AccountId, envelopeIds, opt));
}
It seems that this information have to be determine in second request by calling
"EnvelopesApi.ListRecipientsAsync" method for every envelope.
Maybe someone have an idea or know how to call the API properly.
Are there any options we have to consider by calling the API or do we need to configure something in the DocuSign dashboard?
Thanks!
Remarks: In our environment we can't use webhooks. So we have to poll the DocuSign API.
No, it's not possible and maybe we should understand your statement about "we can't use webhooks".
My guess is that you have firewall or some private network and you can't have calls from outside into these servers. That's not a reason not to use webhooks.
There's a simple solution to this involving an intermediary cloud account that gets your webhooks and a queue mechanism for you to check for messages.
Here is a blog post by Larry that can help if you are willing to consider webhooks.
Yes, you're right. The main reason why we can't use webhooks is because the applicationn is behind a firewall and our customer do not want to make any changes on that.
Also I know the possibility of using DouSign with services like Azure or AWS to get notification about their bus-messaging system but this is something we do not want to implement yet. Maybe in the future.
We found out that we can use the "EnvelopesApi.ListStatusChangesAsync" method to get all of the status information we're interested in.
var options = new ListStatusChangesOptions {
envelopeIds = ids,
include = "recipients"
};
var result = await client.ListStatusChangesAsync(options);

How can I add an header to all endpoints in Yesod appication?

I have an yesod application.
I need to add an specific header to all responses.
It's clear how to do it with an specific endpoint using addHeader.
Let's say this one: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
Question:
How can I configure an header once for all endpoints?
You can alter the yesodMiddleware :: Yesod site => HandlerFor site res -> HandlerFor site res field in the instance Yesod App of your App. For example with:
instance Yesod App where
-- ...
yesodMiddleware handler = do
addHeader "X-Frame-Options" "sameorigin"
defaultYesodMiddleware handler
The yesodMiddleware is thus functionality that is "wrapped around" the target handler. You can do tasks before you query the handler, and after the handler (for example to postprocess the result).

JHipster User Authorization Implemetation

I wanted to block some users for accessing some services in JHipster.
How can I authorize a particular user for accession a ReST web Service in JHipster?
For blocking the access on the backend side, use the #Secured annotation on selected methods (rest entry points) in web/rest/*resource.java.
Example:
#RequestMapping(value = "/data-fields",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
#Secured({AuthoritiesConstants.ADMIN})
public List<DataFieldDTO> getAllDataFields() {
log.debug("REST request to get all DataFields");
return dataFieldService.findAll();
}
As Gaël Marziou says, I believe that what you are trying to do is to block it on frontend's part. If it´s the case a possible way to do it is managing the use of "has-authority". For example: has-authority="ROLE_ADMIN"
So what you should do is the opposite, create an authority which allows some users to have access to ReST web Service
use has-authority and put your expected authority it will work 100% . tasted
write it on your html tag has-authority="ROLE_ADMIN" or your expected user
On /config/SecurityConfiguration.java
You can change access of the api that you want like
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/auth/*").hasAnyAuthority("ADMIN", "USER")
Or you can use auth.inMemoryAuthentication()
for more information read link below:
https://www.baeldung.com/spring-security-expressions

User permission check in Aggregate Root or Application Service?

In my project, there is a concept of user A sending a FriendRequest to user B. In a simplified version, the request looks like this:
class FriendRequest
{
long Id;
int UserId;
int OtherUserId;
string Message;
}
In the Accept method, I need to check whether the current authenticated user equals the OtherUserId in the FriendRequest. The currentAuthenticatedUserId is passed from the controller down to the application service. Now, the question comes that whether I should do the check in the application service or in the FriendRequest aggregate root.
//In application service code:
if(currentAuthenticatedUserId !=friendRequest.OtherUserId)
{
throw new FriendRequestException("Can only accept friend requests sent to you");
}
friendRequest.Accept();
vs.
//In application service, but we are not checking it here.
friendRequest.Accept(currentAuthenticatedUserId); //The check is done inside `FriendRequest` and the exception is also thrown there.
Access control is one of the main responsibilities of application services.
So check the user ID in the app service, not in the entity.
friendRequest.Accept(...)
What does it mean in the domain terms? The request accepts itself or what does it accept? I believe, you need to expand your ubiquitous language with more verbs that correlate to nouns.
As an example, I might think of "a person can accept a friend request that was sent by another person". In this case you would have a person.Accept(friendRequest). It will then be the service responsibility to fetch the Person based on the current authentication details.

Flickr/flickrj: how to get user information after user clicks on web-app?

I'm writing a Java web-app that I created a Flickr-app for.
If a Flickr-user registers my app he/she is automatically sent to the URL I entered in Flickr's authentication flow of the app. Along with that I receive a parameter frob. I can use that one to get the Flickr's user-id of that particular user:
flickrId = flickrj.getAuthInterface().getToken(frob).getUser().getId();
So that works fine.
However, if he/she uses the screen "Apps You're Using" and clicks on my app I don't get any information about the user as far as I can tell. Nonetheless, if I use flickrj like
frob = flickrj.getAuthInterface().getFrob();
I get a frob like 7x1x7x2x2x8x1x1x0-48x9f1xfdbx8ex9d-x00x5x9(note that I x-ed some numbers), whatever that frob is supposed to be. If I then use that frob on
flickrId = flickrj.getAuthInterface().getToken(frob).getUser().getId();
I run into a
com.aetrion.flickr.FlickrException: 108: Invalid frob
at com.aetrion.flickr.auth.AuthInterface.getToken(AuthInterface.java:182)
:
What do I need to do to get information about Flickr's currently logged in user? I had hoped to find something like a place-holder I can use in that URL or Flickr automatically sends some parameter, but I couldn't find information about this.
After some more trial and error I simply use the permission URL that flickrj creates.
String frob = flickrj.getAuthInterface().getFrob();
return "redirect:" + flickrj.getAuthInterface().buildAuthenticationUrl(Permission.READ, frob);
This calls the URL I entered in Flickr's authentication flow of the app. The only problem is to distinguish from such a request to when the user came in from Flickr's authorization form.
But that's another story...

Resources