is there any way by which we change the presence of other contacts using ApplicationEndPoint, one way which i came across was to create a UserEndpoint and then make presence related changes, but that required credentials to establish UserEndPoint.
Presence is aggregated value, even if you publish extra UserEndPoint it would affect only aggregated value taking in consideration all over published UserEndPoint from the same user. Then what is the meaning of changes in presentity value?
You cannot publish presence from an Application Endpoint, you will need to create a UserEndpoint using the SIP uri of the Application Endpoint, and then publish presence using _userEndPoint.LocalOwnerPresence.BeginPublishPresence()
Related
I am working on an API endpoint that returns a list of products:
"api/products"
The endpoint accepts the following parameters:
page_size
page_number
Each product has a boolean property named IsApproved.
In the web application used by common users I always want to return only the Approved products ... On the web ADMIN application used by administrators I want to return all products, Approved or Not ...
My idea would be to add a new parameter (enumeration) named:
ApprovedStatus
And the values would be Approved, NotApproved and All.
On each API call I would check the user permissions ... If is admin I will consider the value on this parameter. If not then I will always return only approved products.
Another solution would be to have different endpoints ...
Any advice on which approach to take or is there other options?
The approval status is part of the product, therefore, in a perfect REST world, you don't want a different endpoint at all since you're accessing the same resource.
Then, for filtering a resource based on a property value, I think the convention is that if you specify that property as a query parameter it will only return those matching the value, and if not, it will return all of them, so I don't see the need to define a special ApprovedStatus parameter with some special values. Just query by isApproved!
Finally, about how to handle authorization. This, I think, should be handled at a completely separate layer**. If authorization is involved, you should have an explicit authorization layer that decides, for a specific resource and user, wether access is granted or not. This means the query would be triggered and if one of the resources generated by the query fails to be authorized for the user that triggered the query, it's taken out of the results. This accomplishes the behaviour you want without having any code that is checking specific users against specific query parameters, which is good because if tomorrow you have another endpoint that exposes this objects you won't have to implement the same authorization policy twice. Pundit is a perfect example on how to do this with Ruby elegantly.
**Of course, this approach retrieves data from the database unnecessarily which could matter to you, and also opens your endpoint up to timing attacks. Even then, I would consider tackling these problems premature optimizations and should be ignored unless you have a very good reason.
You're right about your ideas:
You can create a new endpoint just for admins, that will return all products
You can use a kind of authorization (e.g. Authorization Header) in order to check if the API is being called through admin or normal user. Then you can route internally to get all products or just IsApproved products.
You can add a proxy in front of your API to route to the right action, but it can also be achieved directly in the API but I think the second solution is easier.
Adding one more property is a bad idea.
In my opinion, adding another end point is very good. Because it will increase the protection in the admin end point.
Otherwise, since it is a web application, Simply set a cookie and a session to identify and separate the admin and user.
Going with the principle of least astonishment, I'd be in favour of adding a second endpoint for admin users. Such that you'll have:
GET /api/products (for regular users)
GET /api/admin/products (for admins)
This allows your code and API documentation to be nicely separated, and all of the admin-specific authentication details can live under the "admin" namespace.
The intention behind each API call is also clearer this way, which helps developers; and means that you can differentiate between admin vs regular usage in any usage stats that you track.
With ApprovedStatus, I think the specifics here don't matter much, but - considering what a developer using the API might reasonably expect / assume - it would be good to:
Ensure the ApprovalStatus parameter name matches the property name for "approval" that you return with each product object
Defaults to "approved" if it is not specified
Alert the user when an invalid value is specified, or one that they don't have access to
Bottom line: to answer your headline question - I think it's bad practice to ignore user input... sometimes. Design your API such that distinctions around when input can be passed in is very clear; and always alert the user if you receive input values that are technically acceptable, but not in the way that the user has requested, or for their access level. Ignoring values that are plain wrong (e.g. an argument that doesn't exist) is another story, and can be useful for future proofing or backwards compatibility.
Imagine a simple REST API that allows to create a user account, by sending a JSON resource to POST /users as in the following. By default it sends out a confirmation email to the user.
{
"username": "john#appleseed.com",
"password": "secret"
}
However sometimes there are good reasons for not sending out a confirmation based on the use case, e.g. another API client, or admins signing up users on their behalf.
Since it doesn't have any implications on the created resource but is more of an instruction how to create the user, should it be separate from the request body? What's the best way to do this?
Specify a custom header Confirmation: no-confirmation
Add a query param ?confirmation=false
Add a send_confirmation field to the request body
Let's take the options in order:
Adding a header value to indicate some semantic difference should be generally avoided. The API should be "browseable", meaning it should be discoverable following links only.
Adding a query parameter is, from REST perspective completely equal to creating another URI. It does not really matter how you expose it, the point is that the client needs to follow some links from the previous "state" it was in. This is actually ok, as long as the links to these resources indicate the different semantics you described: like creating users by admin, users creating themselves, etc.
Also note, that the API should not necessarily expose whether a confirmation is sent. The API should expose the "purpose", the server then can decide whether the use-case warrants a confirmation email.
Putting a send_confirmation in the JSON representation itself. This is ok, if this is a functionality available for the user. For example I can ask for a confirmation email. If I can't, and it is only used for differentiating different use-cases, then I would rather prefer option 2.
Summary: For the case you are describing I would pick option 2: different resources for admins and normal users.
So I have a nice set of Spring Data REST repositories and they work great. Now I want to secure the data they produce. The URLs to the repositories are secure, in that, only an authenticated user has authorization to call them. However, only data in the database associated to the user should be sent to the client.
I have implemented an interceptor which gets called prior to the repository call which contains information about the logged in user, but I'm not sure how I can ensure only data produced by the REST call is data associated to the logged in user.
Obviously the client is coded to only make calls with links associated to the currently logged in user, but a user could simply change the URL to look at data they are not supposed to see.
Has anyone solved this issue?
Thanks,
Cory.
If you're using spring security, you can insert additional filters (ideally, based upon the url, or domain object.)
If you want object level security, you can still do the same thing, but you're going to have to somehow specify who/what role is allowed to access which domain object/id combinations, in either case, I don't think spring data rest handles (or should handle) any of that.
Spring Security's #PostFilter allows you to filter collection or arrays on the basis of authorization.
#PostFilter ("filterObject.owner == authentication.name")
public List<Book> getBooks();
Check these documented examples
https://github.com/spring-projects/spring-data-examples/tree/master/rest/security
I have an API that provides an Account resource based on the authentication (login) that is supplied. As a user can only have one account, and can only see it's own account and not those of others, this API will basically be a single resource API in all cases.
So to keep things simple, I have this resource under the url accounts/ and when you access accounts/?username=dude&password=veryhard you'll get your account data (if you dohn't supply authentication you'll get a 403).
Now I wonder if this is RESTful. Also, you should be able to update your account info, and I wonder if PUT would be appropriate. In my knowledge, PUT should be done on a unique URI for the resource. Well, is this a unique URI for the resource? Generally a URI for an account would look like accounts/3515/ where 3515 is the account id. However, users don't know their account id. Also, there should be more ways to log in, instead of a username + password you should also be able to use a token (like accounts/?token=d3r90jfhda139hg). So then we got 2 URL's that point to the same resource, which also isn't really beautiful for a RESTful URI, is it?
So, what would be the most RESTful solution? Or should I not do this RESTful?
REST purists will consider that use of /accounts/ to obtain a single account is bad practice as it should specify a collection. Instead consider a key which cannot be mistaken for an ID, for example if your IDs are UUIDs then use a token such as 'me' so your URL is /accounts/me. This has the advantage that if later on you wish to obtain different account information, say for example you need to list users or you have an administration system using the same API, then you can expand it easily.
Putting username and password in the URL is also not pure REST. The query parameters should be directly related to the resource you are obtaining; commonly filtering and limiting the resources returned. Instead you should seriously consider using something like HTTP Basic authentication over an encrypted (HTTPS) connection so that you separate out your authentication/authorisation and resource systems. If you prefer to use a token system then take a look at oauth or hawk.
Finally, yes if you use PUT you should supply a full resource identifier. Given that it is very common for systems to read data before updating it the lack of ID won't be a problem as that will come back as part of the prior GET.
Yes accounts/?username=dude&password=veryhard is a correct REST URL.
PUT is used with an id if it used to update a resource, if you use it to create you must supply an ID. otherwise you use post to create a resource without id
We are currently looking into implementing our own STS (Microsoft WIF) for authenticating our users, and in that process we have come up with a few questions that we haven’t been able to answer.
We have different kinds of users, using different kinds of applications. Each kind of user needs some special types of claims only relevant for that kind of users and the application belonging.
Note that we do not control all the clients.
Let’s say that all users are authorized using simple https using username and password (.NET MVC3). A user is uniquely identified by its type, username and password (not username and password alone). So I will need to create an endpoint for each user type, to be able to differentiate between them. When a user authorize, I’ll issue a token containing a claim representing the user type. Is there an easier way for doing this? Can I avoid an endpoint for each user type (currently there are three)?
My token service can then examine the authorized users’ token and transform the claims, issuing a token containing all the users’ type specific claims. So far so good, except for the multiple endpoints I think?
If I need to have multiple endpoints, should I expose different metadata documents as well, one for each endpoint? Having one big metadata document containing a description of all claims, doesn’t make any sense since there is no application that needs all claims.
Update
Some clarifications.
Certain applications are only used by certain types of users. Not one application can be used by multiple user types.
Depending on what type of application the request is coming from, username and passwords needs to be compared for that user type. There are user stores for each type of application. That is why I need to know what application type the request is coming from. I can't resolve the type by the username and password alone.
Based on your problem description, it sounds like you have three indepent user "repositories" (one for each user type).
So imho this would be a valid scenario for three STS or a STS with multiple endpoints.
Another way to solve this could be to distinguish the user type by the indentifier of the replying party redirecting the user to the sts. This identifier is submitted in the wtrealm parameter.
The processing sequence could look like the following:
Get configuration for relying party (wtrealm) from configuration store (I'd suggest a database for your rather complex case)
Validate user with username, password and user type (from relying party configuration)
Add claims depending on user type or relying party specific configuration.
The datasbase/class structure for this could look similiar to this:
Need some more information to answer:
Are certain applications only used by certain types of users? Or can any user type access any application? If the former, you can configure the STS for that application to pass that user type as a claim. Each application can be configured to have its own subset of claims.
Where is the user type derived from? If from a repository, could you not simply construct a claim for it?
Update:
#Peter's solution should work.
Wrt. the 3 STS vs. 3 endpoints,
Many STS - can use same standard endpoint with different "code-behind". Would still work if you migrated to an out-the box solution . Extra work for certificate renewals.
One STS - custom endpoints won't be able to be migrated. Only one STS to update for certificate renewals.
Metadata - given that it can be generated dynamically, doesn't really matter. Refer Generating Federation Metadata Dynamically.