ejabberd behavior b/w user disconnected vs user unavailable - ejabberd

What is the ejabbered behavior for user who is un-expectedly disconnected from internet
vs
user who explicitly sent an 'unavailable' presence?
Would they both be considered offline (for both single user chat or MUC)?
I want a behavior where if a user is disconnected from internet, offline messages to be sent
If user sent a explicit unavailble presence, I dont want offline messages to be sent.
How can that be accomplished? I can write my hook. But I need to know in which situations, the hook will be called.

When the user gets offline, the default behaviour is the same, no matter which method is used (explicit session close or unvoluntary disconnect). This is per XMPP specification.
If you want to customise the behaviour, it will not be easy as there is no way to know the reason why a user if offline.
What I would do: I would use the last module and support an optional reason for disconnect and store it. When you disconnect unvoluntarily, I would modify code to store reason being something like "timeout". When you disconnect explicitely, I would store another flag. When you get an offline message, you can then check the reason from being offline coming from mod_last storage.

Related

Invalidating JWTs on Permissions

Do people typically store permissions in a JWT? I've seen example that might have admin: true or scopes: ['add_foo', 'delete_foo', 'read_foo']. And this seems fine, other that the potentially large size that the JWT could become if there are a lot of permissions/scopes. It seems like it would be really useful as you wouldn't need to hit a DB or cache to get the users permissions as long as the JWT can be verified.
My main question though is how these would be invalidated in the event of a permissions change.
For example, sys admin Joe, revokes the 'add_foo' and 'delete_foo' permissions from user Bob, but keeps the 'read_foo' permission. In this scenario user Bob should not have his token entirely invalidated and need to log back in, he should basically be forced to get a new JWT with the new permissions and carry on as normal.
I've seen examples explaining issuing a new JWT in the event of a password change, but the difference here is that sys admin Joe does the update to user Bob. Thus, there is no opportunity in this workflow for user Bob to get the new token immediately.
Most examples suggest for invalidation maintaining a black list of revoked tokens, or changing a DB record ID so the token is no longer valid, or having a per-user secret and changing that.
I see that all of these would work for the revoking of the token and test that its invalid, but how does the user then get a new token? their current JWT is now invalid? Trying to do anything with it should fail.
I've seen mention of a "refresh token". Are these widely use? Are they secure on the web or mainly used for mobile apps where the refresh token is harder to obtain. It seems like it would be reasonably easy to steal a refresh token via browser dev tools or similar and then someone would have access forever to that account until the unauthorized access was noticed and the refresh token revoked.
Maybe in this scenario forcing user Bob to re-authenticate is not such a big deal? Permissions probably don't change too often.
Thanks, Mike.
You can set expiration date (for Web app we are usually using 15 min - 30 min, for mobile 1 week). When you set Issued at claims parameter ("iat"). Then every time when you validate token you should check the token's "age". If it older than 5 min you load data from DB and create new token with current "iat" value.
When permissions change you should invalidate the issued tokens for this user. There are different techniques to use. See Invalidating client side JWT session
But consider that revoking tokens is not a recommended practice because you lose one of the main advantages of JWT: It does not require server storage.
The objective of Refresh tokens, as defined in Oauth2.0, is allow applications to obtain a new access token without re-authenticate
Refresh tokens are credentials used to obtain access tokens. Refresh tokens are issued to the client by the authorization server and are used to obtain a new access token when the current access token becomes invalid or expires,
If the permissions do not change frequently it may be easier to re-authenticate user, and if they change much consider whether they really should be included in the token

Service now api how to comment as specific user

I'm working on a project that consumes Service Now API (Rest). To do so our client has registered us as a user in order to login and make all service calls we need to. This project has an interface where users can login once they have an account on Service Now as well, the username they type to log in has nothing to do with service now by the way, but later they associate theirs service now users to it. They can do some operations through this interface, where all of them are done using the integration user/pass not their service now users theirselves, even because they do not need to share their passwords with us. But it's needed to track the correct user to register on service now and I'm in trouble specifically about commenting on an incident. The endpoint to comment is the following :
http://hostname/api/now/table/incident/{sys_id}
where request body is a json object just as simple as :
{
"comments": "My comment is foo bar"
}
but when this comment is registered on Service Now it is under integration user instead the user which commented. Is there any way I could keep a specific user, considering I already have the user id on Service Now ready to inform it on the request the way it should be.
I tried reading Service Now documentation but had no clue how to solve it, altought I've found something about impersonate
This is happening because you're being proxied through the "Integration User" instead of your own account. As long as this is the case, your comments are going to be attributed to the Integration User.
I can think of two ways to fix this issue.
Ask the client to log you into their system directly as a user.
Implement a special API (Scripted REST API, available in Geneva or later) that allows you to identify the Incident and enter the comment, and then the script forges the comment on your behalf, attributing authorship correctly.
The first solution can be expensive due to possible additional licensing costs.
The second solution will require a willing client to devote 2-3 hours of development time, depending on the programmer.
Firstly, you need an integration user with suffient rights. Our integration user has suffient rights out of the box, but your story could be different. A quick check is to try impersonate as other user using menu.
Login as integration user to ServiceNow instance.
Go to https://{instance}.service-now.com/nav_to.do
Click on username at top right corner. This is a drop down.
There should be at least three menu items: "Profile", "Impersonate User", and "Logout". If you do not have "Impersonate User" in this menu, your integration user miss some permissions. Contact system administrator if you miss this menu item to configure appropriate permissions.
Then you need to find sys_id of user that you want to impersonate. For example:
https://{instance}.service-now.com/api/now/table/sys_user?sysparm_query=user_name={username}&sysparm_fields=sys_id
If you have suffient privileges, you could invoke the folling endpoint with sys id of user that you want to impersonate:
HTTP POST to https://{instance}.service-now.com/api/now/ui/impersonate/{user_sys_id} with body "{}" and content type "application/json". You need to provide HTTP basic authentication to this query as your integration user.
The response code on success is 200. The response body could be ignored. The interesting result of this response is a set of cookies for impersonated user in response headers. These cookies could be used for subsequent REST API calls until they expire. Use some HTTP rest client dependent method to capture them and to provide them to next calls.
For Apache HTTP Client (Java), I'm creating http client context using:
HttpClientContext context = HttpClientContext.create();
context.setCookieStore(new BasicCookieStore());
Pass thing context to impersonation request and to subsequent API calls until I get 401 reply, after that I'm reaquiring cookies. Setting new cookie store is important, as otherwise some default cookies store is used.
Two things to note:
This API looks like internal one, so it could change at any time. If it happens, look for what "Impresonate User" menu item does, and repeat it youselves.
ServiceNow permissions are quite fine-grained, so the target user could lack permissions to perform operation. In some cases, if there is no permission to update the field the operation PATCH on object returns reponse 200, but field is not updated. This introduces a surprising mode of failure when you use impersonation.

Windows phone 8 push notification how to use ChannelUpdatedUri to detect channel updates

I would like to know what is the clean & correct way to notify my WP8 app that the ChannelUri has changed?
I read that i need to handle this in the ChannelUpdatedUri method. But i have a few queries here. Doesn't this require my app to be running all the time?
Second query is suppose i use ChannelUpdatedUri to listen for changes to the Uri. If there is a change will the app be notified as soon as it launches? Or will it be notified at a later time?
The trouble is if the app is not notified on launch then there is a possibility that it may re-register for a new channel uri before ChannelUpdatedUri is invoked. Isnt it?
Please help!
You'll only get notified of a change in the ChannelUri when you have the listener attached and the app running.
The best approach is to always check for the current Uri and pass it to the server when the app starts. You could leave the listener attached for the lifetime of your app and get a new one if it's lost while the app is running but in reality it's far more likely that the channel will be dropped/disconnected when the phone isn't in use.
There is, of course, the scenario where a channelUri may expire when the app isn't in use but the utility of the app is primarily around sending notifications. Obviously you need the user to restart the app to get a new connection but you can't tell them to restart the app.
This is a generic problem: how do you tell someone that you can't talk to them?
The reality of this situation is that if you really need to tell someone to launch the app again you'll need another way to do it.
Unfortunately, it's not possible to get an updated channelUri from a background agent, but you could query your backend to see if you need one and then raise a toast to the user to prompt them to reopen the app. Or you could just update the tile from the agent when this happens.
Alternatively you'll need to send them the prompt in another way (e.g. email or SMS?) but this is reliant on you capturing and securely storing these details.
There is no perfect solution to this scenario other than creating an app that the user opens regularly regardless of whether there are notifications or not and simply having the notifications as an extra feature.

GMail and POP3 RETR problem - switch to IMAP?

When I'm accessing GMail inbox using POP3 protocol, it seems that after fetching given email using RETR command, after QUIT-ting and reconnecting, previously RETR-ieved email is not listed anymore when calling LIST.
Then, after going to: GMail settings//Forwarding and POP/IMAP and setting "Enable POP for all mail (even mail that's already been downloaded)", on next login all emails are being LIST-ed again, but if I RETR any of them, it again disappears from LIST after re-logging..
I can then go to GMail settings again and repeat the whole process, but it's a show-stopper for me as I'm writing a script that should work without any manual actions.
Am I missing something, or only IMAP can help here?
(EDIT: RFC http://www.ietf.org/rfc/rfc1939.txt doesn't say a word about RETR command deleting messages)
This is intended behaviour of Gmail. According to this question, "[a]ll messages may be downloaded to another computer once; after downloading mail, it will not download again."
There's also a 'recent mode', in which the last 30 days of mail are fetched, regardless of whether it's been sent to another POP client already.
That said, don't try to fetch all your mail by different computer in a short period of time, as Gmail may block your account for 24 hours.
I strongly suggest using IMAP.
Gmail’s POP3 configuration maybe sometimes confusing. You can find Gmail POP3 behavior here.
Switching to IMAP is very good solution.
This is a common problem, unfortunately, it does not always have the easiest solution. Hopefully, this information will help you and others arrive at the best implementation that suits your needs. Disclaimer: if you have the option or capability to add IMAP to your pop3, it certainly makes things more manageable.
Gmail has its own Pop3 implementation, and with that said, not all of this is relevant to other pop3 providers
Here is the lifecycle of the issue and some information that can help you manage it:
You connect to the pop3 server either in NORMAL mode or RECENT mode. This puts the "session" on the pop server into a "transaction state".
Recent mode is used by prefixing the username on connection with "recent:" + Username. Recent mode will return the last 30 days of email on the server. Note* this will supersede the UIDL command which I will touch on below. I.e. recent mode will return all 30 days worth of email if they have not been removed. Since it always returns the last 30 days, if you have multiple clients, they will all receive the same information in recent mode.
Normal mode is the default. Normal mode will respect the limitations of the commands you choose to use. UIDL will return a chunk of roughly 250 of the oldest emails on the server. If you have 500 emails on the server, and you do not remove any, UIDL will return the id and Unique Identifier for those first 250 emails regardless, so you may not be aware of the new 250. The caveat here is as follows, GMAIL has an option on the web console where you configure pop, to "Enable pop from now on". By selecting that and saving, the timestamp at that moment will be used by the pop server to "refresh" the oldest time. Therefore UIDL will start returning messages back you from that point on up until you reach the 250 mark again (assuming you have not removed them).
It is important to note that the transaction state exists until you issue the QUIT command. Upon issuing that command the server enters the "Update" state, where it will begin issuing the updates you requested, like DELETE commands, or popping them after they have been downloaded. Until QUIT is issued successfully, nothing will be deleted and the server state does not change.
STAT command will show you the number of emails in the pop3 stack, that are on your server.
RETR command will retrieve, or download the email, but it is not marked as downloaded until you successfully end the session
UIDL which many developers use to retrieve the message numbers and unique identifiers is very useful if you maintain the state of the server and pop the email. UIDL will only ever return the oldest 250-ish (I have seen 251-255) emails. If you are constantly polling for new email, this is dangerous if email hasn't been removed. ALSO! if you need to delete email, make sure the GMAIL setting to, Keep a copy in my inbox, is configured in the web console, so that you have access to those emails as a backup.
LIST command would solve your problem in normal mode for getting more than 250 emails back, (note: you still need to maintain an id file locally to cross-check incoming mail in order to know that it is new or old)... HOWEVER: this command also returns mail from the SENT box, which for many, is not a viable solution.
Hints:
If you are managing the inbox quickly and effectively and do not believe 250 to be a limiting factor in your process, UIDL and RETR will work.
If you will not be able to keep your inbox below 250 but also need access to new email, AND you do not expect the inbox to grow to outrageous size and the performance is not concerning, RECENT mode should work.

Email and Reusable Token URLs

I'm building a site that offers functionality to users without requiring them to register. The idea is to send an email to the specified address containing a link with a token. That way the user would could this link anytime they want to make changes to the functionality.
While I realize that there is no way to truly secure such a concept, I'm looking for options to minimize the visibility of the token. In its current state, soon as the user clicks on the link it is added to their browser history, available to anyone who has access to the computer.
In most cases I would over come this with a simple form so that the token could be passed through with a POST request, but forms aren't really supported in emails.
So the question is, does anyone know of an alternative way to hide a token in such an email?
I'm sure you've thought of this, but you could send them a password and a link to a URL where they'd need to enter that password. If the emailed URL contained another password, it would be a smaller compromise to security than usual to make the user-entered password quite short, like a PIN number, say.
You could resend a new token every time the user wants to log in. Have them plop in their email address and send them a new token, while setting previous tokens to 'expired.' Or, if the server detects that an old link/token was used, it could automatically send a new one to the associated email address and ask the user to check their email for a new link.
That would require keeping track of old, expired tokens and the associated email addresses, but still requires no registration - just that a user check their mail every time they want to log in. You'd essentially be piggy backing on their email authentication.
It'd also be counter-intuitive for users.
This would turn the token into a cryptographic nonce, which is primarily used to prevent the replay attack you mentioned.
Another answer, perhaps more useful:
Some browsers (like Chrome) do not record 301 "Moved Permanently" redirects in the browser history. Firefox does, but there's a proposal to change that:
https://wiki.mozilla.org/Browser_History:Redirects
For example, in Chrome, if you navigate directly to
amazon.com
it will follow a 301 Redirect to
www.amazon.com
If you then check your browser history, it will only show
www.amazon.com
Thus, if your server returns a 301 redirect from the login link, the server could record the token, remove it from the redirect link, and the user's browser would only record the redirect link.
(this is my first time responding on stack overflow - let me know if my writing is unclear or if I'm missing other etiquette)