I want to use the Stripe.com on the server-side. When I try to create card token via
curl https://api.stripe.com/v1/tokens \
-u sk_test_qMabFX3j5ApELqUH8mEy6NDp: \
-d card[number]=4242424242424242 \
-d card[exp_month]=12 \
-d card[exp_year]=2019 \
-d card[cvc]=123
or via
Stripe.apiKey = "sk_test_qMabFX3j5ApELqUH8mEy6NDp";
Map<String, Object> tokenParams = new HashMap<String, Object>();
Map<String, Object> cardParams = new HashMap<String, Object>();
cardParams.put("number", "4242424242424242");
cardParams.put("exp_month", 6);
cardParams.put("exp_year", 2019);
cardParams.put("cvc", "314");
tokenParams.put("card", cardParams);
Token.create(tokenParams);
I see the message in my dashboard:
"We saw nnn requests in the last m days with raw credit card numbers"
My questions are:
1) Can I safely use the Java API to create a card token? If yes, how to avoid such messages?
2) Or I have to use Stripe elements and one of their scripts for this?
QUESTION 1:
Can I safely use the Java API to create a card token? If yes, how to avoid such messages?
ANSWER:
Yes, but it needs the highest level of permission, instead of SAQ A you need SAQ D verification.
Validation Process: https://stripe.com/docs/security#validating-pci-compliance
(Select tab "API Direct")
Summary:
Your transactions must be secure both physically, in code and fill all the requirements (encrypted card information over internet, keep your wifi connection secure, documentation if you are storing card data etc.)
You need to fill out this PDF and upload to Stripe annually: https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-D_Merchant.pdf
Your application should have PCI DSS Compliance and has to be filled in to the form above and be versioned: https://www.pcicomplianceguide.org/faq/
If you got over 6 million transactions a year, you must fill out this PDF once a year: https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-ROC-Reporting-Template.pdf
As I understand this should also remove the message in the Stripe dashboard you are referring to.
Stripe's Radar functionality will not work
For reference, the API endpoint documentation:
Create a token: https://stripe.com/docs/api/tokens/create_card
Create a charge: https://stripe.com/docs/api/charges/create
QUESTION 2:
Or I have to use Stripe elements and one of their scripts for this?
ANSWER:
No, you don't have to. Only if you want a faster solution with lower level of permissions and less struggle, you can use the pre built Stripe element scripts.
ADDITIONAL INFORMATION:
Using Stripe.js v2 (Not JAVA but Javascript) to collect card information yourself and create a token, SAQ A-EP is required which needs a lower level of permission then the API which has SAQ D. See: https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A_EP.pdf
But using Stripe.js v2 without Element is deprecated: https://stripe.com/docs/stripe-js/v2
So I do not know if this will remove the security warning in dashboard and the functionality could be removed later. So the safest way to go if you require to handle Card Information yourself is getting the SAQ D verification and fill out the forms annually. (For a website shop this should not be necessary and you should go with Elements, but for custom hardware integrations like Terminals, NFC scanners etc, this could be the simplest / only way to go if you have to integrate yourself).
If you create card tokens server-side in Java, this means that your servers received raw card details. Even if you don't save the information in your database, you still fall under a higher level of PCI compliance which would be a lot of work to comply with.
Instead, you should tokenize client-side, using Elements or Checkout. This would let you create a card token securely client-side and then send that token to your server. This would also let you fall under SAQ-A which is the easiest level for PCI compliance. You can read more about the differences in Stripe's docs here.
Related
We have an app that's getting license info about our clients' Google organizations. We've been using SKU IDs before but now we've faced with non-profit organization and Google support says there's no SKU IDs for nonprofits.
We've been investigating a way to use ProductId instead but I see no suitable ProductIds for non profits here
For regular organizations we're using com.google.api.services.licensing Java package
and something like
var productLicensing = new Licensing.Builder(HTTP_TRANSPORT, JSON_FACTORY, oAuth2Credentials)
.setApplicationName(APPLICATION_NAME).build();
var request = productLicensing.licenseAssignments()
.listForProductAndSku(productId, skuId, domain);
var assignments = request.execute();
// further operations
Is there any idea how we can distinguish regular organizations from non-profit ones using Google API? Do nonprofits have special ProductId?
Answer:
I don't think there are product ids for Nonprofit licenses. Therefore, I don't think there's any API that will return this kind of information.
Feature requests:
I went ahead and filed a feature request in Issue Tracker to add productIds to Non-profit licenses:
Add productId for Nonprofit licenses
There's also a feature request to list all available products and SKUs. It might be useful in this kind of situations:
Google API Call for All Available Licenses and SKUs
Consider subscribing to these issues in order to keep track of them and to help prioritizing them.
I'm finding a way to programatically list Google Cloud projects inside an organization. I'm trying to use a service account exported json credential to achieve such purpose in this way:
// More info on the endpoint here:
// https://cloud.google.com/resource-manager/reference/rest/v1/projects/list
final CloudResourceManager cloudResourceManagerService = createCloudResourceManagerService();
final CloudResourceManager.Projects.List listRequest = cloudResourceManagerService
.projects()
.list()
.setFilter("labels.it-restoring:false name:IT-TEST-*");
final ListProjectsResponse listResponse = listRequest.execute();
if (listResponse.isEmpty()) {
throw new RuntimeException("The API did not get any response"); // I never get past here
}
log.info("Listing projects returned: {}", listResponse);
The problem I find is that I always get an empty response. Even though I assigned the service account the role of owner. According to docs, I could use roles/
resourcemanager.organizationAdmin which I also set but with no luck. I create the CloudResourceManagement api object using getApplicationDefault.
However if I do gcloud beta auth application-default login which triggers an auth flow in the browser and authenticate with the user which is the owner of the organization this works and lists all the projects that I have.
Can anybody explain to me what I should do to store a proper credential which would emulate he user owner? I already set the service account with the Owner role which in theory gives virtually access to all resources and still no luck.
In order to list the projects on your organization, you need the permission resourcemanager.projects.get. Please find more information in this link The service account might have the owner role of 1 project, and not enought to list them all.
An alternative solution is to grant the account the cloudasset.assets.searchAllResources permission at org level by using one of the following roles:
roles/cloudasset.viewer
roles/cloudasset.owner
roles/viewer
roles/editor
roles/owner
With this permission, you can list all the projects within an organization 456:
gcloud asset search-all-resources \
--asset-types="cloudresourcemanager.googleapis.com/Project"
--scope=organizations/456
Documentation: https://cloud.google.com/asset-inventory/docs/searching-resources
Related post: How to find, list, or search resources across services (APIs) and projects in Google Cloud Platform?
I am developing an app that gets Facebook unread inbox message .
The following v2.0 FQL query works fine:
SELECT sender, body FROM unified_message
WHERE thread_id IN
(SELECT thread_id FROM unified_thread WHERE folder = 'inbox' AND unread=1)
AND unread=1
ORDER BY timestamp DESC
As a result, we have a list of all unread messages.
But, Facebook says:
Version 2.0 of the Facebook Platform API is the last version where FQL
will be available. Versions after 2.0 will not support FQL. Please
migrate your applications to use Graph API instead of FQL. Please see
our changelog for current version information.
So, I am looking for a way to do that with Graph API only. I tried the following:
Bundle params = new Bundle();
params.putString("unread", ">0");
new Request(session,"/me/inbox/",params,HttpMethod.GET,new Request.Callback() {
public void onCompleted(Response response) {
...
}
}
).executeAsync();
without success. I get all the threads whereas I only need the unread threads. How to do that then?
I am sorry for the advice I gave when I blindly quoted the following Facebook notice:
However, you should not use FQL anymore:
Version 2.0 of the Facebook Platform API is the last version where FQL will be available. Versions after 2.0 will not support FQL. Please
migrate your applications to use Graph API instead of FQL. Please see
our changelog for current version information.
This statement is true, but to follow it isn't very smart.
Indeed, I checked further and found out:
v2.0 is available until August 7th 2016,
the Graph API is not yet suitable for your current usage.
I didn't expect the Graph API to be so weak. The Graph API makes it impossible to build a request by filtering any field. For example, we can't do simple things such as:
me/threads?unread_count>0,
me/threads?fields=unread_count.more(0).
Right now with Graph, you would have to iterate through all the threads and check which one have unread > 0. You would lose time and bandwidth. Moreover, the message table doesn't even have an unread field which would make it impossible for you to find any specific unread message(s).
So, the best is to keep using FQL. You are safe for now. By 2016, Facebook will probably have improved the way we query with Graph API.
Wait and see...
I am building a client application for Intra Office Messaging System using Openfire as server. Using Roster class I can find the list of buddies (friends/contacts) using:
Roster rs= con.getRoster();
Collection<RosterEntry> list=rs.getEntries();
System.out.println("\n\n" + list.size() + " buddy(ies):");
for (RosterEntry r : list) {
System.out.println(r.getName());
}
But since this is an IOMS (Intra Office Messaging System), the requirement is diferent. There is no need to add contact. All users should see every other user and his status. Is there a way to achieve this?
One way to do this would be to integrating your openfire with AD. Add all users in a single common group and then import that group in the client. That way a user will automatically appear as a member of that group, and his/her online status will be available to all members of that group. And make sure whenever a new user is added, it becomes member of this group. This way everybody is imported at once in user's list.
Here is a reference link regarding same: Openfire Automatic Roster Population via Shared Groups and here is the guide to integrate Openfire with LDAP
Another way would be to update Openfire code and change registration process to add code for automatically adding all users to buddy list of the newly registered user. You can also do the same code on client side. But this is not a good path to walk on, as it will cause problem as the number of users in system grows.
I am Using Google App Engine for Java and I want to be able to share session data between subdomains:
www.myapp.com
user1.myapp.com
user2.myapp.com
The reason I need this is that I need to be able to detect if the user was logged in on www.myapp.com when trying to access user1.myapp.com. I want to do this to give them admin abilities on their own subdomains as well as allow them to seamlessly switch between subdomains without having to login again.
I am willing to share all cookie data between the subdomains and this is possible using Tomcat as seen here: Share session data between 2 subdomains
Is this possible with App Engine in Java?
Update 1
I got a good tip that I could share information using a cookie with the domain set to ".myapp.com". This allows me to set something like the "current_user" to "4" and have access to that on all subdomains. Then my server code can be responsible for checking cookies if the user does not have an active session.
This still doesn't allow me to get access to the original session (which seems like it might not be possible).
My concern now is security. Should I allow a user to be authenticated purely on the fact that the cookie ("current_user" == user_id)? This seems very un-secure and I certainly hope I'm missing something.
Shared cookie is most optimal way for your case. But you cannot use it to share a session on appengine. Except the case when you have a 3rd party service to store sessions, like Redis deployed to Cloud Instances.
You also need to add some authentication to your cookie. In cryptography there is a special thing called Message Authentication Code (MAC), or most usually HMAC.
Basically you need to store user id + hash of this id and a secret key (known to both servers, but not to the user). So each time you could check if user have provided valid id, like:
String cookie = "6168165_4aee8fb290d94bf4ba382dc01873b5a6";
String[] pair = cookie.split('_');
assert pair.length == 2
String id = pair[0];
String sign = pair[1];
assert DigestUtils.md5Hex(id + "_mysecretkey").equals(sign);
Take a look also at TokenBasedRememberMeServices from Spring Security, you can use it as an example.