Twitterizer - how to get the username - vb.net

I'm trying to get the username of an authorised user. I've already managed to get the OAuth to work, have got the token, directed the user to retrieve the PIN, entered that and sent a tweet successfully. But what I don't understand is WHEN and HOW to get the username.
I used this VB.NET code to get the URL:
Dim ReqTokens = OAuthUtility.GetRequestToken("XXX", "XXX", "oob")
Dim url = (OAuthUtility.BuildAuthorizationUri(ReqTokens.Token).AbsoluteUri)
TextBox2.Text = url
This code then confirmed authorisation and allows me to tweet using the app:
OAuthUtility.GetAccessToken("XXX", "XXX", "XXX", "1234567")
But at which stage, and HOW, do I retrieve the username and user ID?
Any help in VB.NET, and simplified for the dunce I clearly am, would be much appreciated!

OAuthUtility.GetAccesToken() returns a OAuthTokenResponse which contains the ScreenName and Id property. Doc is here
Dim accessTokens = OAuthUtility.GetAccessToken("")
Dim screenName as String = accessTokens.ScreenName

Related

Hangout OAuth - Invalid Scope : Some requested scopes cannot be shown

I am facing the below error while generating token for service account for the Hangout Scope - https://www.googleapis.com/auth/chat.bot.
Where i receive 400 response code after making a post request to this url -
https://www.googleapis.com/oauth2/v4/token
the params are
Content-Type:application/x-www-form-urlencoded
httpMode:POST
body:grant_type=jwt-bearer&assertion=assertion-token
Note:This was completely working fine. Suddenly am facing this issue.
cross verified: jwt generation,service_account_id and etc...
Error Response : { "error": "invalid_scope", "error_description": "Some requested scopes cannot be shown": [https://www.googleapis.com/auth/chat.bot]}
code for generating assertion:
//FORMING THE JWT HEADER
JSONObject header = new JSONObject();
header.put("alg", "RS256");
header.put("typ", "JWT");
//ENCODING THE HEADER
String encodedHeader = new String(encodeUrlSafe(header.toString().getBytes("UTF-8")));
//FORMING THE JWT CLAIM SET
JSONObject claimSet = new JSONObject();
claimSet.put("iss","123#hangout.iam.gserviceaccount.com");
claimSet.put("sub","one#domain.com");
claimSet.put("scope","https://www.googleapis.com/auth/chat.bot");
claimSet.put("aud","https://oauth2.googleapis.com/token");
long time = System.currentTimeMillis() / 1000;
claimSet.put("exp",time+3600);
claimSet.put("iat",time);
//ENCODING THE CLAIM SET
String encodedClaim = new String(encodeUrlSafe(claimSet.toString().getBytes("UTF-8")));
//GENERATING THE SIGNATURE
String password = "secretofkey", alias = "privatekey";
String signInput = encodedHeader + "." + encodedClaim;
Signature signature = Signature.getInstance("SHA256withRSA");
String filepath = "/check/PrivateKeys/hangoutPKEY.p12";
KeyStore kstore = KeyStore.getInstance("PKCS12");
fis = new FileInputStream(filepath);
kstore.load(fis, password.toCharArray());
KeyStore.PrivateKeyEntry pke = (KeyStore.PrivateKeyEntry) kstore.getEntry(alias, new KeyStore.PasswordProtection(password.toCharArray()));
PrivateKey pKey = pke.getPrivateKey();
signature.initSign(pKey);
signature.update(signInput.getBytes("UTF-8"));
String encodedSign = new String(encodeUrlSafe(signature.sign()), "UTF-8");
//JWT GENERATION
String JWT = signInput + "." + encodedSign;
String grant_type = URLEncoder.encode("urn:ietf:params:oauth:grant-type:jwt-bearer");
reqBody = "grant_type=" + grant_type + "&assertion=" + JWT;
public static byte[] encodeUrlSafe(byte[] data) {
Base64 encoder = new Base64();
byte[] encode = encoder.encodeBase64(data);
for (int i = 0; i < encode.length; i++) {
if (encode[i] == '+') {
encode[i] = '-';
} else if (encode[i] == '/') {
encode[i] = '_';
}
}
return encode;
}
Does anyone have any idea, where am going wrong?
Short answer:
You are trying to use domain-wide authority to impersonate a regular account. This is not supported in Chat API.
Issue detail:
You are using the sub parameter when building your JWT claim:
claimSet.put("sub","one#domain.com");
Where sub refers to:
sub: The email address of the user for which the application is requesting delegated access.
I noticed that, if I add the sub parameter to my test code, I get the same error as you.
Solution:
Remove this line from your code in order to authorize with the service account (without impersonation) and handle bot data:
claimSet.put("sub","one#domain.com");
Background explanation:
Chat API can be used for bots to manage their own data, not to manage end-user data. Therefore, you can only use a service account to act as the bot, without impersonating an end-user.
From this Issue Tracker comment:
At the present moment, Chat API can only be used to manage bot-related data (listing the spaces in which the bot is included, etc.). Using domain-wide delegation to manage regular users' data is not currently possible.
Feature request:
If you'd like to be able to access regular users' data with your service account and domain-wide delegation via Chat API, you are not alone. This feature has been requested before in Issue Tracker:
Accessing the Google Chats of regular users using domain-wide delegated permission and service account credentials
I'd suggest you to star the referenced issue in order to keep track of it and to help prioritizing it.
Reference:
Using service accounts
Delegating domain-wide authority to the service account
Preparing to make an authorized API call

Get Sitefinitys Generated Password Reset URL

I am trying to get the URL from the password reset which I receive via email of the sitefinity frontend login.
I need to send the URL with the username which is enterd in the form to a server to send the email.
I already tried to override the SendResetPasswordEmail of the LoginFormModel but that only gives me the URL where the reset is located at. (localhost/login/resetpassword)
It looks like the URL is generated in the method SendRecoveryPasswordMail of the Telerik.Sitefinity.Security.UserManager which is not overridable.
Is there a way to get the generated recovery URL to use it in a custom method?
Thanks in advance
Since you already have the URL of the reset password page, I guess your issue is getting the proper query string to pass to that page.
Looking at the source code with JustDecompile, the query string is made up of this:
?vk=userValidationKeyEncoded&cp=pr
The cp=pr seems to be hardcoded, so we leave it as is, the question is how the userValidationKeyEncoded is made.
Again, looking in the code, it is this line:
string userValidationKeyEncoded = UserManager.GetUserValidationKeyEncoded(userByEmail);
And finally:
private static string GetUserValidationKeyEncoded(User user)
{
object[] providerName = new object[] { user.ProviderName, ',', user.Id, ',', DateTime.UtcNow };
string str = string.Format("{0}{1}{2}{3}{4}", providerName);
return SecurityManager.EncryptData(str).UrlEncode();
}
You can use the above code to manually generate the validationKey.

How to new a new access token from a refresh token using vb.net?

I don't know if you can help me understand the right way forward with this issue. I need to provide a little bit of background first.
I have a VB.Net Console Utility that uses the Google V3 Calendar API. This utility has the following process to authenticate:
Private Function DoAuthentication(ByRef rStrToken As String, ByRef rParameters As OAuth2Parameters) As Boolean
Dim credential As UserCredential
Dim Secrets = New ClientSecrets() With {
.ClientId = m_strClientID,
.ClientSecret = m_strClientSecret
}
'm_Scopes.Add(CalendarService.Scope.Calendar)
m_Scopes.Add("https://www.googleapis.com/auth/calendar https://www.google.com/m8/feeds/ https://mail.google.com/")
Try
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
"user", CancellationToken.None,
New FileDataStore("PublicTalkSoftware.Calendar.Application")).Result()
' Create the calendar service using an initializer instance
Dim initializer As New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "~~~~~~~~~~"
}
m_Service = New CalendarService(initializer)
rStrToken = credential.Token.AccessToken.ToString()
rParameters.AccessToken = credential.Token.AccessToken
rParameters.RefreshToken = credential.Token.RefreshToken
Catch ex As Exception
' We encountered some kind of problem, perhaps they have not yet authenticated?
Return False
End Try
Return True
End Function
This part of the application process works fine. The data store file gets created and once the user has authenticated it all seems to just work find from there on. The user will be able to update the calendar without any further authenticating on there part.
Now, I also have a part of my MFC (the main application) project that sends emails for the user. This uses the following CkMainManW library.
For the most part that works too. If the user has correctly set up their credentials it is fine. However, if they are using GMail, then I do things slightly differently. This is to avoid the need to have the "Allow third party apps" option to be ticked in the Google account.
So, for GMail users, we send emails like this:
mailman.put_SmtpUsername(strUsername);
mailman.put_OAuth2AccessToken(strGoogleToken);
As you can see, I use the OAuth2AccessToken. This actual value passed is the credential.Token.AccessToken.ToString() value stored from when the user authenticated. Now, I have since understood that this actual token only lasts for one hour. This would explain why some users have to repeatedly run my calendar authentication again to get a new access token.
Clearly, when I do the calendar authentication which uses the data store file, it does something under the hood the avoid the user being asked all the time to authenticate.
Now, I have read this tutorial about using the Chilkat Library for this. I notice now that in the sample code it has a comment:
// Now that we have the access token, it may be used to send as many emails as desired
// while it remains valid. Once the access token expires, a new access token should be
// retrieved and used.
So, with all the background, how do I resolve my issue? So I have a data store file that contains the original access token from when they authorised and a refresh token. This file was created by the VB.Net command line module.
By the sounds of it, the Chilkat routine needs an access token that is valid. So, what is the right way for me to get an updated access token from the refresh token, so that when I send emails it won't fail after an hour?
Update
I am getting myself confused. I changed my code so that it called the DoAuthentification call above to get the refresh token and access token. But I am finding that the actual data store file is not getting revised. The text file is not being revised.
I have to revoke access and then do the authentication to get the data store file revised. And it is only once it has been revised that the access token will work for sending emails.
I think I have found the solution. I saw this answer:
https://stackoverflow.com/a/33813994/2287576
Based on the answer I added this method:
Private Function RefreshAuthentication(ByRef rStrAccessToken As String, ByRef rStrRefreshToken As String) As Boolean
Dim parameters As New OAuth2Parameters
With parameters
.ClientId = m_strClientID
.ClientSecret = m_strClientSecret
.AccessToken = rStrAccessToken ' Needed?
.RefreshToken = rStrRefreshToken
.AccessType = "offline"
.TokenType = "refresh"
.Scope = "https://www.googleapis.com/auth/calendar https://www.google.com/m8/feeds/ https://mail.google.com/"
End With
Try
Google.GData.Client.OAuthUtil.RefreshAccessToken(parameters)
rStrAccessToken = parameters.AccessToken
rStrRefreshToken = parameters.RefreshToken
RefreshAuthentication = True
Catch ex As Exception
RefreshAuthentication = False
End Try
End Function
I am not sure if I need to pass in the existing access token or not before refreshing. But either way, the tokens get updated and I can proceed with sending emails.
FYI, in the end it became apparent that I did not need any bespoke Refresh at all because the system manages it for you under the hood.
Private Async Function DoAuthenticationAsync() As Task(Of Boolean)
Dim credential As UserCredential
Dim Secrets = New ClientSecrets() With {
.ClientId = m_strClientID,
.ClientSecret = m_strClientSecret
}
Try
credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
"user", CancellationToken.None,
New FileDataStore("xxx.Calendar.Application"))
' Create the calendar service using an initializer instance
Dim initializer As New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "yy"
}
m_Service = New CalendarService(initializer)
Catch ex As Exception
' We encountered some kind of problem, perhaps they have not yet authenticated?
' Can we isolate that as the exception?
m_logger.Error(ex, "DoAuthenticationAsync")
Return False
End Try
Return True
End Function
I have not required any bespoke Refresh of tokens for a long time now.

How to use facebook authentication with asp.net login control?

I have been digging on facebook authentication for a week. I came across so many things such as facebook_connect, Facebook C# SDK from CodePlex and other ways to connect with facebook which are absolute now. Finally after reading http://developers.facebook.com for many times, I did manage to have a login button and get user's information for facebook using the new and standard Graph API stuffs. There are in Javascript such as.
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
var name = response.name
var username = response.username
var gender = response.gender
On another world, I have Login Control and asp.net Form authentication managing the whole website.
Protected Sub Login1_Authenticate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs) Handles Login1.Authenticate
Dim userName As String = Login1.UserName
Dim password As String = Login1.Password
Dim result As Boolean = UserLogin(userName, password)
If (result) Then
e.Authenticated = True
Else
e.Authenticated = False
End If
End Sub
Private Function UserLogin(ByVal userName As String, ByVal password As String) As Boolean
//validate user // if valid, return true
//return false if invalid user
End
I can't remove all form authentication from the existing website. Facebook login should be value added feature to the website. Now the few bits I don't get is ...
How to authenticate the asp.net Form authentication when someone Login to the website using facebook Login.
How do I pass all the value in the javascript to aspx.vb to connect to database and store the information.
I understand I would need to create a new table in the database, probably called FacebookUsers. But I can't think a way that facebook authentication and asp.net Login control to work together. My website is in VB.net by the way.
*How do I pass all the value in the javascript to aspx.vb to connect to database and store the information*.
Check out the following articles they may help you out a bit.
http://www.codeproject.com/Tips/371917/Get-user-Facebook-details-in-ASP-NET-and-Csharp
1.-Don't create a new table just add a new field to your current users table...
2.-Name the Field FaceBookUID or FB_ID.
3.-Store the facebook user id .
4.-Set the default Value of the FACEBOOK UID to 0.
5.-Now you'll have a unique value between a regular user and a FacebookUser.

Using VB.NET to log into Windows Live Mail?

I want to make a program that tells you if you can login to an email account or not by entering their username and password into Windows Live.
It would connect to the Hotmail server and see if the user/pass combination is correct. If it can log in, it would display a label that the account is valid, if not it would say that the account is not valid.
How would I go about doing this?
Ok here's the totally incorrect code for logging in. I kind of borrowed it from sending an email:
Dim MyMailMessage As New MailMessage
MyMailMessage.From = New MailAddress(TextBox1.Text)
MyMailMessage.To.Add(TextBox1.Text)
Dim SMTP As New SmtpClient("smtp.live.com")
SMTP.Port = 25
SMTP.EnableSsl = True
SMTP.Credentials = New System.Net.NetworkCredential("textbox1.text", "textbox2.text")
SMTP.Send(MyMailMessage) // I have no idea how to get a response here... from the live server if it gives me a correct or incorrect response...
Can someone post an example code if they have a solution to this? Because I have no idea how to make this single handingly.
dim smtp as new smtpclient("smtp.live.com",25)
dim m as new mailmessage()'message must contains from, to, etc
with smtp
.usedefaultcredentials = false 'by default this is true
.credentials = new networkcredential("usuername","password")
.enablessl = true
.ishtmlbody = true
.send(m)
'or async
'.send(m,addresof enviado)' i'm not remember well if addressof is required here
end with
public sub Enviado
msgbox("mail message sended async")
end sub
One option could be to use the WebBrowser control which would allow you to access the username and password input boxes, and would allow you to click the login button. You could then see which page the user is redirected to and that would tell you in the username/password combo is correct or not.
Use Fiddler or HTTP Analyzer to see what happens when you sign in with a Browser.
(I can give you a hand: A http post request is sent to https://login.live.com....)
All you have to do then is to mimic this request with the HttpWebRequest class in .NET.
It's important that you make your request as similar as the one from the Browser as possible.