PhotobucketNet photo upload - c#

I have a problem with PhotobucketNet user login(I need user to login so I can upload a picture from HDD to his Photobucket account).
Photobucket photobucket = new Photobucket("myapikey", "myapisecret");
photobucket.LaunchUserLogin();
// the problem happens here
photobucket.RequestUserToken();
If I call RequestUserToken() it will happen immediately, so I'll get a crash cause user didn't logged in, and there is no event that's been raised after user logs in. Is there some variable(bool or something else) that I can check to see if user logged in - maybe to put it in a loop with timer?
Also is their a way to know if user canceled logging in?
I know that timer isn't a good solution, so if anyone has anything better as an idea, I'm open for any suggestions...

I've encountered the same problem today and i found your post while i was searching for solutions. Here is how i managed to solve the problem:
Firstly, i got the "user login url" and passed it to a form with a web browser control, called "Login".
Service=new Photobucket ("mykey", "mysecret");
string u=Service.GenerateUserLoginUrl ();
Login l=new Login (u);
l.Show ();
Next, I got the url from this page,
which is the page after the login. If the web browser's url is that page, i asked the photobucket class (in my case Program.Service), to request the token.
The code from the Login form is something like this:
public Login (string url)
{
InitializeComponent ();
webBrowser1.Navigate (url);
webBrowser1.DocumentCompleted+=delegate
{
if (webBrowser1.Url.ToString ()=="http://photobucket.com/apilogin/done")
{
PhotobucketNet.UserToken t=Program.Service.RequestUserToken ();
//save the token
}
}
}
Now you just save the token and use it.

Related

Get users current page when session times out

Lots and lots of examples out there as to how to set and redirect when the session times out. But nothing that I could find for this situation.
A typical situation where a timeout control monitors the session timeout and displays a window warning the user of that when there is 1 minute left. When the session times out, the user is redirected to a page (sessionexpired.aspx) that clears the session and displays information informing the user that they are required to login again.
I would like to log the page the user was on when the session actually timed out and do that in the code behind of the sessionexpired.aspx page.
Any help would be very welcome!
Try looking at the Referer from the current Request object. It's usually found using this:
Request.UrlReferrer
I hope this helps.
You can use one of these code examples to get the current page the user is on:
// Returns something like "http://www.example.com/myUrl/MyPage.aspx"
string page = HttpContext.Current.Request.Url.AbsoluteUri;
// Returns something like "/myUrl/MyPage.aspx"
string page = HttpContext.Current.Request.Url.AbsolutePath;
// Returns something like "MyPage.aspx"
string page = HttpContext.Current.Request.Url.AbsolutePath.Substring(url.LastIndexOf('/') + 1);
So wherever your code is to log you out when your session expires (probably in your master page), just add one of these lines.
Once you have it, you can add it as a query string parameter to your login page or you can save it in a database.

login to ajax web page from c# code

i'm trying to log in a site with username + password through a c# code.
i found out that it uses Ajax to authenticate...
how should i implement such login ?
the elements in the web page doesn't seem to have an "id"...
i tried to implement it using HtmlAgilityPack but i don't think this is the correct direction...
i can't simulate a click button since i don't find "id" for the button.
if (tableNode.Attributes["class"].Value == "loginTable")
{
var userInputNode =
tableNode.SelectSingleNode("//input[#data-logon-popup-form-user-name-input='true']");
var passwordInputNode =
tableNode.SelectSingleNode("//input[#data-logon-popup-form-password-input='true']");
userInputNode.SetAttributeValue("value", "myemail#gmail.com");
passwordInputNode.SetAttributeValue("value", "mypassword");
var loginButton = tableNode.SelectSingleNode("//div[#data-logon-popup-form-submit-btn='true']");
}
This question is quite broad but I'll help you in the general direction:
Use Chrome DevTools (F12) => Network tab => Check the "Preserve Log". An alternative could be Fiddler2
Login manually and look at the request the AJAX sends. Save the endpoint (the URL) and save the Body of the request (the Json data that's in the request with username and password)
Do the post directly in your C# code and forget about HtmlAgilityPack unless you need to actually get some dynamic data from the page, but that's rarely the case
Login with something like this code snippet: POSTing JSON to URL via WebClient in C#
Now you're logged in. You usually receive some data from the server when you're logging in, so save it and use it for whatever you want to do next. I'm guessing it might have some SessionId or some authentication token that your future requests will need as a parameter to prove that you're actually logged in.

Registering a new user overwrites current user session - why?

I've come across an issue when registering new users with my app. The behaviour looks to be by design, but I don't understand why.
My problem is as follows (and I know it's a bit of an edge case):
User browses to my site's login page in two separate tabs in the same browser.
In the first tab, the user logs in and is correctly redirected to my home page.
In the second tab, the user follows my signup logic (which doesn't require any kind of page refresh, it's all done with client side code that culminates in a jQuery AJAX POST to the built in ServiceStack RegistrationService's /register endpoint)
Instead of creating a new user, the second user's details overwrite that of the logged in user's UserAuth record, and the first user can no longer log in.
Looking at the code in ServiceStack.ServiceInterface.Auth.RegistrationService, this behaviour appears to be 100% intentional:
var session = this.GetSession();
var newUserAuth = ToUserAuth(request);
var existingUser = UserAuthRepo.GetUserAuth(session, null);
var registerNewUser = existingUser == null;
var user = registerNewUser
? this.UserAuthRepo.CreateUserAuth(newUserAuth, request.Password)
: this.UserAuthRepo.UpdateUserAuth(existingUser, newUserAuth, request.Password);
Once the first user is logged in, the session cookie for that user gets sent with the registration request, causing the existingUser variable in the code above to be populated with the UserAuth for that user, which is then updated with the registering user details.
Can anyone explain why the code's been written in this way? And is there any way around it without replacing the RegistrationService with my own implementation?
This is the feature that lets you to auto-merge different Auth Providers into the same account in ServiceStack.

How can I handle forms authentication timeout exceptions in ASP.NET?

If the session has expired and the user clicks on a link to another webform, the asp.net authentication automatically redirect the user to the login page.
However, there are cases when the user does not click on links to other webforms. For example: edit link in gridviews, when using AutoCompleteExtender with textboxes and the application attempts to get the information, and basically, in every case when a postback is done and the event is not automatically handled by the asp.net authentication.
What is the best way to handle these exceptions?
UPDATE: I have just modified the question title: forms authentication timeout, instead of the initial session timeout. Thanks for making me aware of this difference.
UPDATE: I have just created a new question with the specific problem I am facing: How to handle exception due to expired authentication ticket using UpdatePanel?. Surprisingly, I have not found much information about it. I would really appreciate your help.
This is why many systems include timers on the page to give approximate timeout times. This is tough with interactive pages. You really need to hook ajax functions and look at the return status code, which is a bit difficult.
One alternative is to use code based on the following which runs early in the page lifecycle and perform an ajax redirect to a login page. Otherwise you are stuck trying to intercept the return code from ajax and in asp.net where the ajax is done 'for you' (ie not a more manual method like jQuery) you lose this ease of detection.
http://www.eggheadcafe.com/tutorials/aspnet/7262426f-3c65-4c90-b49c-106470f1d22a/build-an-aspnet-session-timeout-redirect-control.aspx
for a quick hack you can try it directly in pre_init
http://forums.asp.net/t/1193501.aspx
Edit
what is wanted are for forms auth timeouts, not session timeouts. Forms auth timeouts operate on a different scale than session timeouts. Session timeouts update with every request. Forms auth tickets aren't actually updated until half of the time goes by. So if you have timeouts set to an hour and send in one request 25 minutes into it, the session is reset to an hour timeout, the forms auth ticket isnt touched and expires in 35 minutes! To work around this, sync up the session timeout and the forms auth ticket. This way you can still just check session timeouts. If you don't like this then still - do the below and sync up the timeouts and then parse the auth ticket and read its timeout. You can do that using FormsAuthentication.Decrypt - see:
Read form authentication cookie from asp.net code behind
Note that this code requires that upon login you set some session value - in this case its "UniqueUserId". Also change the login page path below to fit yours.
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
//Only access session state if it is available
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
{
//If we are authenticated AND we dont have a session here.. redirect to login page.
HttpCookie authenticationCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authenticationCookie != null)
{
FormsAuthenticationTicket authenticationTicket = FormsAuthentication.Decrypt(authenticationCookie.Value);
if (!authenticationTicket.Expired)
{
if (Session["UniqueUserId"] == null)
{
//This means for some reason the session expired before the authentication ticket. Force a login.
FormsAuthentication.SignOut();
Response.Redirect("Login.aspx", true);
return;
}
}
}
}
}
If you're using Forms Authentication, the user will be redirected to the login page when the Forms Authentication ticket expires, which is not the same as the Session expiring.
You could consider increasing the Forms Authentication timeout if appropriate. Even to the extent of using a persistent cookie. But if it does expire, there's no real alternative to redirecting to the login page - anything else would be insecure.
One way to deal with Session timeouts is to use Session as a cache - and persist anything important to a backing store such as a database. Then check before accessing anything in Session and refresh if necessary:
MyType MyObject
{
get
{
MyType myObject = Session["MySessionKey"] as MyType
if (myObject == null)
{
myObject = ... get data from a backing store
Session["MySessionKey"] = myObject;
}
return myObject;
}
set
{
Session["MySessionKey"] = value;
... and persist it to backing store if appropriate
}
}
If you're using a master page or a base page, I would add some logic to one of the events in the page lifecycle to check whether the session is new:
protected void Page_Load(object sender, EventArgs e)
{
if (Session.IsNewSession)
{
//do whatever you need to do
}
}

ASP.NET MVC 2 caching problem

I'm writing an app and have come across caching problem which I cannot work out.
I have a default Home controller for the site which checks whether the user is authenticated or not.
If is not then LogOn View is displayed otherwise the client is redirected to another page.
Along with the LogOn view, also a Check cookie is being sent to user to check on response if his browser supports cookies or not.
When I delete the cookie before sending the form with credentials, Home (Post method) in Home controller displays message that cookies must be enabled with a button which
should refresh the page with Logon boxes(http://localhost:1234/)
This button is linked to js refresh function:
var sURL = unescape("/");
function refresh()
{
window.location.href = sURL;
}
I have implemented CacheFilter which is set on the base controller.
public class NoCache : ActionFilterAttribute, IActionFilter
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuting(filterContext);
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
}
}
and the problem is that if I Immediately click the button to refresh LogOn page, browser read it using its cache. But when I do it after a few seconds then the query is sent to the server.
This is wrong, because LogOn page should also create again a Check cookie.
It seems to me that the cache policy is set to 1-2 seconds, and after this time pages are reloaded from the server.
What is wrong? Thanks for help.
I have seen some similar behaviour, related to the javascript in IE7. The browser 'helpfully' realizes that you've recently requested that URL and therefore serves up the cached version. If this is the case, the solution is to make sure the URL is unique every time by adding a pseudo random number. I use something like:
function refresh()
{
window.location.href = sURL + "?rnd="+ Math.random();
}
Am I right in saying you're testing this by running this in Visual Studio?
As far as I know you can't enable things like caching in the Visual Studio Development Server. This is something you will enable on your webserver, which I guess will be IIS in your case.

Categories