Closed pippinsplugins closed 11 years ago
Initially, the API will only provide GET methods, no methods for PUT.
Authentication (for GET methods) will be based on API key / email address.
Started working on the base class for the API. I'll keep everyone updated as development continues.
Any thoughts on where the API should be accessible?
It should be front and back, at least for the GET methods.
You misunderstood the question. I meant in regards to URL structure
Whoops! I would say register a new URL endpoint for "edd-api".
So we want to use edd-api. Ok! That's all I needed.
Just to keep everyone up to date, the API initialization functions have been completed, and I'm about 50% done the key generation and management.
Additionally, the API is being designed as a class to make extension easy on anyone who want to...
Fantastic, thanks for the update!
Why not just use authentication with WP shop admin credentials ?
Because that doesn't work nearly as well for things like mobile apps.
It's better to enter an API key in a mobile app than it is a username and password.
It is also more secure because if the API key gets stolen, then only thing the perpetrator can do is read data, whereas with an admin user account they can do anything.
Good point ! :thumbsup:
It's not the combo of api key + email is it? Just api I hope?
It might be API + email, but not sure. @ghost1227 ?
What's not the combo of api key and email? The access credentials for the API? If so, the answer is yes, unless someone gives me a better idea. As of now, it's set up such that you would pass parameters &username=
Well IMO, the better idea is to just use key=, without username.
Do you have this on Github anywhere? Can we see what you have currently?
I have no issues with the username. The only argument for not including it I can see is it's simpler, but I don't think that's a good enough argument in this case.
What's the argument to keep username? It seems useless.
More secure.
How?
If the api key is compromised, it's logical to assume so is the username.
Not necessarily. Someone could get hold of the API key but not know the username. While a lot of the time they would have both, it's very safe to assume they could also have only gotten one. It's an extra level that can only help.
Seems like a false sense of security to me :/
Most smaller APIs I know of only require an API key to function, eg rottentomatoes or something
I think what'd be safer is to track API key usage in the backend.
No, it's not a false sense of security at all. It may not always make much difference, but there will absolutely be cases where it does. There is zero benefit to not using the username.
Tracking key usage would be great. I'd say we setup another view for the Logs page that shows API access usage.
That sounds like a good idea, I'll add it to the list!
In response to the argument against usernames, it's technically possible (however unlikely) to brute-force a key. Managing to brute-force both key and username is almost impossible without knowing the username.
I would rather see an 'api secret' than username, then. Something not personally identifiable on first glance if compromised.
@ghost1227 could you respond to this one https://github.com/pippinsplugins/Easy-Digital-Downloads/issues/857#issuecomment-13566273
For an API secret, is that really just a separate API key? Similar to how Stripe works?
In response to #857, it's not on Github yet, but will be posted to a branch on my fork of EDD as soon as I finish the core of the class.
API key generation/revocation functions are done
There are several things to do still (beyond normal testing):
Todo:
Hey Pippin,
Before you distribute this you might consider posting an overview of your architecture to the API Craft mailing list. It's really easy to make arbitrarily-chosen architecture mistakes with APIs that haunt you for years and there is both some serious horsepower related to API design on that list and it's small enough and welcoming enough that people there are happy to hear about designs and to offer the expertise, mostly as a way to make sure the start of the art of web APIs keeps improving.
Just a thought...
Also, you might want to consider using the 'do_parse_request'
hook instead of 'template_redirect'
and 'query_vars'
and add_rewrite_endpoint()
. Your API doesn't and shouldn't run by the same rules as your content, and if you use 'template_redirect'
WordPress is going to do a lot of work each API request that your API will just throw away. Do a preg_match()
on $_SERVER['REQUEST_URI']
in 'do_parse_request'
to decide if you want your API to handle a request or not. Take a look at lines Lines 27-28 as well as lines 258-266 to see an example in action, from this plugin.
@mikeschinkel Thanks for the link to the API Craft list. I've been reading through a lot of the links. Good stuff.
I'd say this is ready for some heavy testing. For those interested, here's how:
yoursite.com/?edd-api&user={your email}&key={your API key}&query={query mode}
The API accepts three query modes:
customers
To retrieve a list of all customersproducts
To retrieve a list of all products + info for each productstats
To retrieve sales and earnings statsEach of the three modes has additional parameters that can be used to retrieve specific information as well:
_customers_
customer
Used to retrieve info for a specific customer. This can be a user ID or email (must be an email if you want to retrieve info for a guest customer).
_stats_
type
This determines the kind of stats you want to retrieve, either sales
or earnings
product
The specific product to retrieve either sales or earnings stats for. If present, can be a product ID or all
.
date
The date to retrieve earnings/sales for. Can be yesterday
, today
, or range
. If range
is used, then the following two parameters must also be specified:
startdate
The date to start with in the format of YYYYMMDD: 20130304enddate
The date to end with in the format of YYYMMDD: 20130510The date parameters can not be used for specific products (yet).
_products_
product
The specific product to retrieve info for. Must be a product ID.
The API also accepts a format
parameter, which can be json
(default) or xml
.
A complete query looks like this:
http://localhost/wpms/?edd-api&user=pippin@pippinsplugins.com&key=fa3308eeaee3f78edf3deb1de754353f&query=products
Or like this:
http://localhost/wpms/?edd-api&user=pippin@pippinsplugins.com&key=fa3308eeaee3f78edf3deb1de754353f&query=stats&type=sales
Or:
http://localhost/wpms/?edd-api&user=pippin@pippinsplugins.com&key=fa3308eeaee3f78edf3deb1de754353f&query=stats&type=sales&product=10
Or:
http://localhost/wpms/?edd-api&user=pippin@pippinsplugins.com&key=fa3308eeaee3f78edf3deb1de754353f&query=stats&type=sales&date=range&startdate=20130205&enddate=20130415
The api-dev
branch has been merged into master!
If anyone would like to see an example of what can be built with the new API, check this out (really great on mobile): http://dev.pippinsplugins.com/edd-stats/sales/?user=pippin%40pippinsplugins.com&key=cef3bb1b248928b19754d8be4de1b5ae
I noticed that we're allowing any user (if Allow User API Keys is enabled) to generate API keys, which would allow even basic subscribers to get read access to the API. This needs to be updated to only permit users with "view_shop_reports" caps to generate an API key.
I agree with the limitation, but I have two concerns. The API is not just used for reports, it can be used for other things. Therefore, maybe it should be the store_manager cap instead.
Also, if I'm a plugin author, and I want to use the API (and correct me if I'm wrong), and I want to use it to dynamically generate the prices of a download, then the current user won't have this cap. So maybe certain areas of the API need different cap limits?
On 2/24/13, Pippin Williamson notifications@github.com wrote:
I noticed that we're allowing any user (if Allow User API Keys is enabled) to generate API keys, which would allow even basic subscribers to get read access to the API. This needs to be updated to only permit users with "view_shop_reports" caps to generate an API key.
Reply to this email directly or view it on GitHub: https://github.com/pippinsplugins/Easy-Digital-Downloads/issues/857#issuecomment-14013892
At the moment the API only contains stat/report-related info (with the exception of product info), so "view_shop_reports" works well.
I like the idea of setting cap checks for each area of the API. For example, the product info could require a much lower cap, but would only reveal sale/earnings info to users with a high cap.
Since it's very possible for a store to have hundreds of products, retrieving all products (or customers) wasn't a good idea. I've added a couple of helper functions and pagination for all queries.
You can now control the number of results shown per page by adding &page=#
to the query. The number of items shown per page is controlled with &number=#
.
Need to read through this before we consider this finished: http://info.apigee.com/Portals/62317/docs/web%20api.pdf
I've just pushed up an update to simply things a little.
Instead of doing this:
http://localhost/wordpress/edd-api/?user=pippin@pippinsplugins.com&key=7ede50bc7b8264b15bad22475bf2a0ce&query=customers
One will simply do this:
http://localhost/wordpress/edd-api/customers?user=pippin@pippinsplugins.com&key=7ede50bc7b8264b15bad22475bf2a0ce
Instead of explicitly passing a query
parameter, we simply use the value of edd-api
to set the query mode. This makes it simpler and more intuitive.
In the same way that we would expect a site to use /customers, /products, etc, the API now does the same this:
After the rewrite endpoint is added, flush_rewrite_rules()
should be added because when I went in and enabled the API keys to be generated from EDD settings and then generated one, I tried accessing the edd-api
and it resulted in 404. Had to go into Settings > Permalinks and hit Save Permalinks.
@sunnyratilal Already noted #969
Whoops, didn't see that! :)
On Friday, 8 March 2013, Pippin Williamson wrote:
@sunnyratilal https://github.com/sunnyratilal Already noted #969https://github.com/pippinsplugins/Easy-Digital-Downloads/issues/969
— Reply to this email directly or view it on GitHubhttps://github.com/pippinsplugins/Easy-Digital-Downloads/issues/857#issuecomment-14642955 .
We should add also "predefined dates" to the stats
query:
The numerical index needs to be removed from customers:
"0": {
"info": {
"id": -1,
"username": "Guest",
"display_name": "Guest",
"first_name": "Guest",
"last_name": "Guest",
"email": "johnson@test.com"
},
"stats": {
"total_purchases": 2,
"total_spent": "20",
"total_downloads": 0
}
},
"1": {
"info": {
"id": -1,
"username": "Guest",
"display_name": "Guest",
"first_name": "Guest",
"last_name": "Guest",
"email": "asda@test.com"
},
"stats": {
"total_purchases": 0,
"total_spent": "0",
"total_downloads": 0
}
},
We're going to introduce a new API that makes it possible to retrieve sales data, earnings, product information, etc in a JSON/XML format.
One of the many uses for this API will be mobile sales tracking apps, or mobile store UIs.
Initially, we're looking at incorporating the following features: