public void saveAccessToken(AccessToken token) { var accesstokenInsertQuery = Resource.ResourceManager.GetString("socialmedia_insert"); sql_con = new SQLiteConnection(Common.localDatabasePath, true); sql_cmd = new SQLiteCommand(accesstokenInsertQuery, sql_con); sql_cmd.Parameters.Add("@id", DbType.String); sql_cmd.Parameters["@id"].Value = Common.userName; sql_cmd.Parameters.Add("@socialMediaType", DbType.String); sql_cmd.Parameters["@socialMediaType"].Value = token.tokenType; sql_cmd.Parameters.Add("@user_oauth_token", DbType.String); sql_cmd.Parameters["@user_oauth_token"].Value = token.tokenValue; sql_cmd.Parameters.Add("@is_user_oauth_done", DbType.Int16); sql_cmd.Parameters["@is_user_oauth_done"].Value = 1; sql_cmd.Parameters.Add("@user_oauth_token_expire_in", DbType.UInt64); sql_cmd.Parameters["@user_oauth_token_expire_in"].Value = 1; sql_cmd.Parameters.Add("@user_oauth_token_secret_key", DbType.String); sql_cmd.Parameters["@user_oauth_token_secret_key"].Value = token.tokenValue; sql_con.Open(); sql_cmd.ExecuteNonQuery(); sql_con.Close(); }
public virtual void SetupClient() { Configure(); FreeAgentClient.UseSandbox = KeyStorage.UseSandbox; if (KeyStorage.UseProxy) FreeAgentClient.Proxy = new WebProxy("127.0.0.1", 8888); Client = new FreeAgentClient(KeyStorage.AppKey, KeyStorage.AppSecret); var sandbox_bttest_token = new AccessToken { access_token = "", refresh_token = KeyStorage.RefreshToken, token_type = "bearer" }; Client.CurrentAccessToken = sandbox_bttest_token; Token = Client.RefreshAccessToken(); if (Token == null || string.IsNullOrEmpty(Token.access_token) || string.IsNullOrEmpty(Token.refresh_token)) { throw new Exception("Could not setup the Token"); } }
public override void After( object returnValue, MethodInfo method, object[] args, object target ) { Microblog blog = args[0] as Microblog; if (blog == null || blog.ParentId > 0) return; if (blog.User == null || blog.User.Id <= 0) return; if (QQWeiboJobHelper.IsQQWeiboSync( blog.Id )) return; // 是否已经同步过 UserConnect uc = connectService.GetConnectInfo( blog.User.Id, typeof( QQConnect ).FullName ); // 1. 检查:用户是否绑定,是否允许同步 if (uc == null) return; // 绑定 if (uc.NoSync == 1) { logger.Info( "取消同步,因为用户明确禁止" ); return; } // 2. 获取 access token AccessToken x = new AccessToken(); x.Token = uc.AccessToken; x.Uid = uc.Uid; // 3. 同步 QQConnect connect = AuthConnectFactory.GetConnect( typeof( QQConnect ).FullName ) as QQConnect; connect.Publish( x, _blogContent, getPicDiskPath( blog.Pic ) ); // 设置已经同步标记 QQWeiboJobHelper.AddQQWeiboSyncItem( blog.Id ); }
public ActionResult Create(AccessToken accessToken) { var accessTokenToCreate = new AccessToken(); Mapper.Map(accessToken, accessTokenToCreate); accessTokenToCreate.SetNewToken(); accessTokenToCreate.TransferValidationMessagesTo(ModelState); if (ModelState.IsValid) { _accessTokenRepository.EnsurePersistent(accessTokenToCreate); Message = "AccessToken Created Successfully"; return RedirectToAction("Details", new { id = accessTokenToCreate.Id }); } else { var viewModel = AccessTokenViewModel.Create(Repository); viewModel.AccessToken = accessToken; return View(viewModel); } }
protected void btnAddResources_Click(object sender, EventArgs e) { try { if (ddlGroupName.SelectedIndex != 0) { //GetPermission(TireTraxLib.ResourceType.PagePermissions, ref canView, ref canAdd, ref canUpdate, ref canDelete,ddlGroupName.SelectedValue); //if (!canUpdate) //{ // lblInfo.Text = "Sorry, you dont have right to change the premission"; //} //else //{ int groupId = Convert.ToInt32(ddlGroupName.SelectedValue.ToString()); AccessToken token = new AccessToken(); string accessToken = AccessToken.ReturnEmptyToken(); if (chkAdmin.Checked) accessToken = token.AdminToken(64, accessToken); else accessToken = ReadPermissions(accessToken, token); RoleManagement.UpdateSecurityToken(groupId, accessToken); //it is used to update the Security token for Roles DataTable dt = RoleManagement.getDistinctRolesByGroupId(groupId); if (dt != null && dt.Rows.Count > 0) { for (int i = 0; i < dt.Rows.Count; i++) { int TempRoleId = Conversion.ParseInt(dt.Rows[i]["RoleId"]); int TempSubRoleId = Conversion.ParseInt(dt.Rows[i]["SubRoleId"]); regenerateSecurityTokens(TempRoleId, TempSubRoleId); } } lblInfo.ForeColor = System.Drawing.Color.Green; lblInfo.Text = "Permission is Successfully Added"; //Update Cookies // UserInfo user = UserInfo.GetCurrentUserInfo(); Response.Cookies["securityToken"].Expires = DateTime.Now.AddMinutes(-1); string securityToken = string.Empty; securityToken = RoleManagement.GetSecurityTokenByRoleId(groupId); //HttpCookie securityCookie = new HttpCookie("securityToken"); //Decoder d= Encoding.UTF8.GetDecoder(); //securityCookie.Value = Server.UrlEncode(securityToken); //HttpContext.Current.Response.Cookies.Add(securityCookie); // } } else { lblInfo.ForeColor = System.Drawing.Color.Red; lblInfo.Text = "Please Select the Group"; } } catch (Exception ex) { new SqlLog().InsertSqlLog(0, "PagePermission.aspx btnAddResources_Click", ex); } }
/// <summary> /// Saves the user access token. /// </summary> /// <param name="username">The username.</param> /// <param name="serviceId">The service id.</param> /// <param name="accessToken">The access token.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The task that represents the save action.</returns> public Task SaveUserAccessToken(string username, string serviceId, AccessToken accessToken, CancellationToken cancellationToken) { Requires.NotNullOrEmpty(username, "username"); Requires.NotNullOrEmpty(serviceId, "serviceId"); Requires.NotNull(accessToken, "accessToken"); return this.SaveAccessToken(NormalizeUsername(username), serviceId, accessToken, cancellationToken); }
public static string SendEmailNotifications() { StringBuilder output = new StringBuilder(); NetflixConnection conn = new NetflixConnection(ConfigurationManager.AppSettings["NetflixConsumerKey"], ConfigurationManager.AppSettings["NetflixConsumerSecret"]); DatabaseDataContext db = new DatabaseDataContext(); foreach (returnflix.Common.User u in db.Users) { try { output.AppendFormat("Executing Netflix account for {0} {1}...<br />", u.FirstName, u.LastName); AccessToken accTok = new AccessToken(u.NetflixUserID, u.NetflixAccessToken, u.NetflixAccessTokenSecret); System.Xml.Linq.XElement atHomeFeed = conn.RequestXmlResource(NetflixUrls.GetUsersAtHome(accTok, 0, 10, DateTime.Now.AddDays(-7)), accTok); string currentMovie = atHomeFeed.Elements("at_home_item").First().Element("title").Attribute("regular").Value; int currentMovieDays = DateTime.Now.Subtract(UnixTimeToDateTime(atHomeFeed.Elements("at_home_item").First().Element("estimated_arrival_date").Value)).Days; System.Xml.Linq.XElement queueFeed = conn.RequestXmlResource(NetflixUrls.GetUsersQueuesDiscAvailable(accTok, QueueSortOrder.QueueSequence, 0, 10, DateTime.Now.AddYears(-1)), accTok); string nextMovie = queueFeed.Elements("queue_item").First().Element("title").Attribute("regular").Value; output.AppendFormat("\"{0}\" has been at home for {1} days.<br />", currentMovie, currentMovieDays); if (DateTime.Now.Subtract(u.LastNotificationDate).Days >= 3 && currentMovieDays >= 7) { System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(); msg.From = new System.Net.Mail.MailAddress(ConfigurationManager.AppSettings["SmtpEmailAddress"], "Returnflix"); msg.To.Add(u.EmailAddress); msg.Subject = string.Format("Don't Forget to Return \"{0}\" to Netflix", currentMovie); msg.Body = string.Format("Hi {0},\n\nHave you had a chance to watch \"{1}\"? This movie has been at home for a week now. You should return this DVD to Netflix soon so that you can receive your next movie, \"{2}\".\n\nThanks!\n\n--\nReturnflix\nhttp://returnflix.com\n\nTired of the reminders? Unsubscribe at http://returnflix.com/unsubscribe.aspx?id={3}", u.FirstName, currentMovie, nextMovie, u.NetflixUserID); msg.IsBodyHtml = false; System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient(); smtp.Host = ConfigurationManager.AppSettings["SmtpHost"]; smtp.Port = Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"]); smtp.Credentials = new System.Net.NetworkCredential(ConfigurationManager.AppSettings["SmtpUsername"], ConfigurationManager.AppSettings["SmtpPassword"]); output.AppendFormat("Sending message to {0} {1} ({2}).<br />", u.FirstName, u.LastName, u.EmailAddress); smtp.Send(msg); u.LastNotificationDate = DateTime.Now; } } catch (Exception ex) { output.AppendFormat("Failed due to {0}.<br />", ex.Message); } output.AppendFormat("Done.<br /><br />"); } db.SubmitChanges(); return output.ToString(); }
//----------------------------------------------------------------------------- public virtual JsonObject Publish( AccessToken accessToken, String content, String absPic ) { if (strUtil.IsNullOrEmpty( absPic )) { return PublishPost( accessToken, content ); } else { return PublishPic( accessToken, content, absPic ); } }
public override BaseResponse Execute() { if (string.IsNullOrEmpty(appid)) { throw new Exception("invalid appid"); } if (string.IsNullOrEmpty(secret)) { throw new Exception("invalid secret"); } AccessTokenResponse tokenRes = null; NameValueCollection col = new NameValueCollection(); col.Add("grant_type", "client_credential"); col.Add("appid", this.appid); col.Add("secret", this.secret); DateTime now = DateTime.Now; string res = HttpSercice.PostHttpRequest(this.url, col, RequestType.GET, null); if(!string.IsNullOrEmpty(res)) { JObject json = null; try { json = JObject.Parse(res); if(json!=null) { tokenRes = new AccessTokenResponse(); AccessToken accessToken = new AccessToken(); accessToken.Access_Token = json["access_token"]!=null? json["access_token"].ToString():""; if(!string.IsNullOrEmpty(accessToken.Access_Token)) { accessToken.ExpiresIn = json["expires_in"] != null ? int.Parse(json["expires_in"].ToString()) : 0; } accessToken.ExpiresTime = now.AddSeconds(accessToken.ExpiresIn); if(!string.IsNullOrEmpty(accessToken.Access_Token) && accessToken.ExpiresIn>0) { tokenRes.Access_Token = accessToken; } if(json["errcode"]!=null) { tokenRes.err_code = json["errcode"].ToString(); } if (json["errmsg"] != null) { tokenRes.err_code_des = json["errmsg"].ToString(); } } } catch { } } return tokenRes; }
public static AccessToken AccessToken(int? counter) { var rtValue = new AccessToken(); rtValue.Reason = "Reason" + counter.Extra(); rtValue.SetNewToken(); rtValue.ContactEmail = "test" + counter.Extra() + "@testy.com"; rtValue.Application = new Application(); //Need to replace... return rtValue; }
public SinaWeiboService(string accessToken, string accessTokenSecret) { if (accessToken.IsNullOrEmpty()) throw new ArgumentException("accessToken不能为空", "accessToken"); if (accessTokenSecret.IsNullOrEmpty()) throw new ArgumentException("accessTokenSecret不能为空", "accessTokenSecret"); var token = new AccessToken(ConsumerFactory.SinaConsumer, accessToken, accessTokenSecret); _weiboClient = new WeiboClient(token, ResultFormat.json); }
/// <summary> /// <para>Direct auth with login and password.</para> /// <para>See also: <seealso cref="http://vk.com/pages?oid=-1&p=Прямая_авторизация"/></para> /// </summary> /// <param name="login">Login</param> /// <param name="password">Password</param> /// <param name="scopeSettings">Scope settings</param> /// <param name="captchaSid">Captcha sid</param> /// <param name="captchaKey">Captcha key</param> /// <returns><see cref="AccessToken"/></returns> public async Task<AccessToken> Login(string login, string password, VkScopeSettings scopeSettings = VkScopeSettings.CanAccessFriends, string captchaSid = null, string captchaKey = null) { if (string.IsNullOrEmpty(_vkontakte.AppId)) throw new NullReferenceException("App id must be specified."); if (string.IsNullOrEmpty(_vkontakte.ClientSecret)) throw new NullReferenceException("Client secret must be specified."); var parameters = new Dictionary<string, string> { {"username", login}, {"password", password}, {"grant_type", "password"}, {"scope", ((int) scopeSettings).ToString(CultureInfo.InvariantCulture)} }; if (!string.IsNullOrEmpty(captchaSid) && !string.IsNullOrEmpty(captchaKey)) { parameters.Add("captcha_sid", captchaSid); parameters.Add("captcha_key", captchaKey); } parameters.Add("client_id", _vkontakte.AppId); parameters.Add("client_secret", _vkontakte.ClientSecret); var request = new VkRequest(new Uri(VkConst.DirectAuthUrl), parameters); var response = await request.Execute(); if (response["error"] != null) { switch (response["error"].Value<string>()) { case "need_captcha": throw new VkCaptchaNeededException(response["captcha_sid"].Value<string>(), response["captcha_img"].Value<string>()); case "invalid_client": throw new VkInvalidClientException(); case "need_validation": throw new VkNeedValidationException() { RedirectUri = new Uri(response["redirect_uri"].Value<string>()) }; } return null; } var token = new AccessToken(); token.Token = response["access_token"].Value<string>(); token.UserId = response["user_id"].Value<long>(); token.ExpiresIn = response["expires_in"].Value<long>() == 0 ? DateTime.MaxValue : DateTimeExtensions.UnixTimeStampToDateTime(response["expires_in"].Value<long>()); _vkontakte.AccessToken = token; return token; }
/// <summary> /// Reads an access token to find out what data it authorizes access to. /// </summary> /// <param name="message">The message carrying the access token.</param> /// <param name="accessToken">The access token's serialized representation.</param> /// <returns>The deserialized, validated token.</returns> /// <exception cref="ProtocolException">Thrown if the access token is expired, invalid, or from an untrusted authorization server.</exception> public virtual AccessToken DeserializeAccessToken(IDirectedProtocolMessage message, string accessToken) { ErrorUtilities.VerifyProtocol(!string.IsNullOrEmpty(accessToken), ResourceServerStrings.MissingAccessToken); var accessTokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServerPublicSigningKey, this.ResourceServerPrivateEncryptionKey); var token = new AccessToken(); try { accessTokenFormatter.Deserialize(token, accessToken, message, Protocol.access_token); } catch (IOException ex) { throw new ProtocolException(ResourceServerStrings.InvalidAccessToken, ex); } return token; }
public IToken IssueAccessTokenForResourceOwner(ITokenContext context) { AccessToken token = new AccessToken { ExpiresIn = 120, Token = Guid.NewGuid().ToString(), RefreshToken = Guid.NewGuid().ToString(), Scope = new string[] { "create", "delete", "view" }, }; TokenRepo.AddAccessToken(token); return token; }
public static void SetLoginVk(AccessToken token) { if (token == null || token.Token == null) { throw new ArgumentException("AccessToken is empty"); } else { _vkontakte.AccessToken = token; Settings.Instance.AccessToken = token; Settings.Instance.Save(); Messenger.Default.Send(new LoginMessage() { Type = LoginType.LogIn, Service = "vk" }); } }
public IToken IssueAccessTokenForResourceOwner(ITokenContext context) { var authorizationGrant = this.TokenRepo.FindAuthorizationGrant(context.AuthorizationCode); AccessToken token = new AccessToken { ExpiresIn = 120, Token = Guid.NewGuid().ToString(), RefreshToken = Guid.NewGuid().ToString(), //Scope = authorizationGrant.Scope.Split(' '), }; TokenRepo.AddAccessToken(token); return token; }
public IToken IssueAccessToken(IAuthorizationGrant grant) { //typically here you'd fetch your access AccessToken token = new AccessToken { ExpiresIn = 120, Token = Guid.NewGuid().ToString(), Grant = (AuthorizationGrant)grant }; token.Scope = ((AuthorizationGrant)grant).Scope.Split(' '); TokenRepo.AddAccessToken(token); return token; }
public IToken IssueAccessToken(ClientBase client) { AccessToken token = new AccessToken { ExpiresIn = 120, Token = Guid.NewGuid().ToString(), Scope = new string[] { "create-member" }, Client = (Client)client }; TokenRepo.AddAccessToken(token); return token; }
public static string GetAccessToken() { string newAccessToken = String.Empty; int weChatExpiresIn = 0; using (WeChatDbContext entity = new WeChatDbContext()) { var accesstoken = (from item in entity.AccessTokens orderby item.AccessTokenId descending select item).FirstOrDefault(); if (accesstoken == null) { WebClient wc = new WebClient(); byte[] data = null; data = wc.DownloadData(String.Format(WeChatWebAPI.GetAccessToken, appId, appSecret)); string strWebData = Encoding.Default.GetString(data); var accessTokenModel = (JObject)JsonConvert.DeserializeObject(strWebData); newAccessToken = accessTokenModel["access_token"].ToString(); weChatExpiresIn = Int32.Parse(accessTokenModel["expires_in"].ToString()); AccessToken at = new AccessToken(); at.AccessTokenStr = newAccessToken; at.ExpiresIn = weChatExpiresIn; at.LastUpdateTime = DateTime.Now; entity.AccessTokens.Add(at); entity.SaveChanges(); } else { newAccessToken = accesstoken.AccessTokenStr; TimeSpan expires_in = DateTime.Now - accesstoken.LastUpdateTime; if ((expires_in.TotalMinutes * 60) > (accesstoken.ExpiresIn - 100)) { WebClient wc = new WebClient(); byte[] data = null; data = wc.DownloadData(String.Format(WeChatWebAPI.GetAccessToken, appId, appSecret)); string strWebData = Encoding.Default.GetString(data); var accessTokenModel = (JObject)JsonConvert.DeserializeObject(strWebData); newAccessToken = accessTokenModel["access_token"].ToString(); weChatExpiresIn = Int32.Parse(accessTokenModel["expires_in"].ToString()); entity.Entry(accesstoken).State = System.Data.Entity.EntityState.Modified; accesstoken.AccessTokenStr = newAccessToken; accesstoken.ExpiresIn = weChatExpiresIn; accesstoken.LastUpdateTime = DateTime.Now; entity.SaveChanges(); } } } return newAccessToken; }
protected void bTwitter_Click(object sender, EventArgs e) { OAuthConsumer oauth = new OAuthConsumer(); RequestToken requestToken = new RequestToken(); AccessToken accessToken = new AccessToken(); //string Token = "", TokenSecret = ""; string authUrl = GeneralUtils.GetRouteableUrlFromRelativeUrl("AuthorizeServices.aspx/twitter/"); requestToken = oauth.GetOAuthRequestToken(appSettings["Twitter_RequestURL"], appSettings["Twitter_Realm"], appSettings["Twitter_ConsumerKey"], appSettings["Twitter_ConsumerSecret"], authUrl); Session["TwitterToken"] = requestToken; Response.Redirect(appSettings["Twitter_AuthURL"] + "?oauth_token=" + requestToken.Token); }
/// <summary> /// 获取通行令 /// </summary> /// <param name="currentAccount">当前账号信息</param> /// <returns>通行令</returns> public static string GetAccessToken(Account currentAccount) { Monitor.Enter(DicAccessToken); try { AccessToken accessToken; if (DicAccessToken.ContainsKey(currentAccount.ID)) { accessToken = DicAccessToken[currentAccount.ID]; if (accessToken.ExpireTime > DateTime.Now) { return accessToken.Value; } DicAccessToken.Remove(currentAccount.ID); } var result = HttpHelper.GetResponseResultByGet( string.Format(GetTokenUrlFormat, currentAccount.AppID, currentAccount.AppSecret) , timeout: 1000); if (result.Status != ResponseStatus.Success) { return ""; } JObject jObject = JsonConvert.DeserializeObject<JObject>(result.ResponseString); JToken value, time; if (!jObject.TryGetValue("access_token", out value) || !jObject.TryGetValue("expires_in", out time)) { return ""; } accessToken = new AccessToken { Value = value.ToString(), ExpireTime = DateTime.Now.AddSeconds(time.ToObject<double>()) }; DicAccessToken.Add(currentAccount.ID, accessToken); return accessToken.Value; } finally { Monitor.Exit(DicAccessToken); } }
public async void ProvisionAccessTokenAsync_TokenIsAlreadyCachedButIsWithinGracePeriod_NewTokenIsProvisionedAndCached() { IAccessToken accessToken = new AccessToken( BuildTestToken() ); m_serviceTokenCacheMock.Setup( x => x.GetAsync( It.IsAny<string>() ) ) .Returns( Task.FromResult( new CacheResponse( true, BuildTestToken( tokenExpiryInSeconds: 60 ) ) ) ); m_serviceTokenCacheMock.Setup( x => x.SetAsync( It.IsAny<string>(), It.IsAny<string>(), It.IsAny<TimeSpan>() ) ) .Returns( Task.FromResult( 0 ) ); m_accessTokenProviderMock.Setup( x => x.ProvisionAccessTokenAsync( m_claims, m_scopes ) ) .Returns( Task.FromResult( accessToken ) ); const int gracePeriodThatIsBiggerThanTimeToExpiry = TOKEN_EXPIRY_IN_SECONDS + 60; IAccessTokenProvider cachedAccessTokenProvider = GetCachedAccessTokenProvider( gracePeriodThatIsBiggerThanTimeToExpiry ); IAccessToken token = await cachedAccessTokenProvider.ProvisionAccessTokenAsync( m_claims, m_scopes, m_serviceTokenCacheMock.Object ).SafeAsync(); Assert.NotNull( token ); }
public void CanGetList() { FreeAgentClient.UseSandbox = true; //FreeAgentClient.Proxy = new WebProxy("127.0.0.1", 8888); var sandbox_bttest_token = new AccessToken { access_token = "", refresh_token = KeyStorage.RefreshToken, token_type = "bearer" }; { var Client = new FreeAgentClient(KeyStorage.AppKey, KeyStorage.AppSecret); Client.CurrentAccessToken = sandbox_bttest_token; try { var co = Client.Company.Single(); } catch { } } FreeAgentClient.UseSandbox = false; var LiveClient = new FreeAgentClient(KeyStorage.AppKey, KeyStorage.AppSecret); LiveClient.CurrentAccessToken = sandbox_bttest_token; try { var co = LiveClient.Company.Single(); } catch { } Assert.IsTrue(true); }
public void AddAccessToken(AccessToken token) { Models.AccessToken accessToken = new Models.AccessToken() { ClientId = Convert.ToInt32(token.Client.ClientId), ExpiresIn = token.ExpiresIn, IssuedOn = token.IssuedOn, RefreshToken = token.RefreshToken, Scope = string.Join(" ", token.Scope), Token = token.Token, TokenType = token.TokenType, AuthorizationGrantCode = token.Grant.Code, }; using (Models.OAuthWebAPIContext context = new Models.OAuthWebAPIContext()) { context.AccessTokens.Add(accessToken); context.SaveChanges(); } }
public async void ProvisionAccessTokenAsync_NotCached_CallsThroughToAccessTokenProviderAndValueIsThenCached() { IAccessToken accessToken = new AccessToken( BuildTestToken() ); m_accessTokenProviderMock.Setup( x => x.ProvisionAccessTokenAsync( It.IsAny<IEnumerable<Claim>>(), It.IsAny<IEnumerable<Scope>>() ) ).Returns( Task.FromResult( accessToken ) ); m_serviceTokenCacheMock.Setup( x => x.GetAsync( It.IsAny<string>() ) ) .Returns( Task.FromResult( new CacheResponse( false, null ) ) ); m_serviceTokenCacheMock.Setup( x => x.SetAsync( It.IsAny<string>(), It.IsAny<string>(), It.IsAny<TimeSpan>() ) ) .Returns( Task.FromResult( 0 ) ); IAccessTokenProvider cachedAccessTokenProvider = GetCachedAccessTokenProvider(); IAccessToken token = await cachedAccessTokenProvider.ProvisionAccessTokenAsync( m_claims, m_scopes, m_serviceTokenCacheMock.Object ).SafeAsync(); Assert.AreEqual( accessToken.Token, token.Token ); }
public IToken IssueAccessToken(IAuthorizationGrant grant) { var authorizationGrant = (AuthorizationGrant)grant; //typically here you'd fetch your access AccessToken token = new AccessToken { ExpiresIn = 120, Token = Guid.NewGuid().ToString(), Grant = (AuthorizationGrant)grant }; token.Scope = ((AuthorizationGrant)grant).Scope.Split(' '); token.Client = authorizationGrant.Client; token.IssuedOn = SharpOAuth2.Provider.Utility.Epoch.ToEpoch(DateTime.Now); token.RefreshToken = Guid.NewGuid().ToString(); TokenRepo.AddAccessToken(token); return token; }
public override OAuthUserProfile GetUserProfile( AccessToken accessToken ) { JsonObject user = OAuthClient.Init( this.UserProfileUrl, accessToken.Token, HttpMethod.Get ) .AddParam( "uid", accessToken.Uid ) .RunJson(); if (user.Get<long>( "id" ) <= 0) { logger.Error( "无法获取正常 user profile" ); return null; } OAuthUserProfile x = new OAuthUserProfile(); x.Uid = accessToken.Uid; x.Name = user.Get( "name" ); x.FriendlyUrl = user.Get( "domain" ); x.PicUrlSmall = user.Get( "profile_image_url" ); x.PicUrlBig = user.Get( "avatar_large" ); return x; }
public FakeProvider(string name) : base(name, "Fake/Custom") { // Defaults. AccessToken = new AccessToken { PublicToken = "EstSularusOthMithas-MyHonorIsMyLife", ExpiresOn = DateTime.UtcNow.AddDays(30), }; UserInformation = UserInformation ?? new UserInformation { Gender = GenderType.Male, Id = "FakeId-ABCDEFGHIJKLMNOPQRSTUVWXYZ", Locale = "en-au", Name = "Sturm Brightblade", Picture = "data:image/jpeg;base64,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", UserName = "******" }; }
protected void Page_Load(object sender, EventArgs eventArgs) { LoginInfo loginInfo = (LoginInfo)Session["loginInfo"]; if (loginInfo != null) { openID = loginInfo.openID; extensionData = loginInfo.extensionData; accessToken = loginInfo.accessToken; } else { openID = null; extensionData = null; accessToken = null; } if (Request["logout"] == "true") { Session.RemoveAll(); } }
/// <summary> /// Get the application's token. Renew it if needed. /// </summary> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task<AccessToken> CheckAndRenewTokenAsync(CancellationToken cancellationToken) { if (token == null || token.Expiration < DateTime.UtcNow) { // This is not thread safe. Unfortunately, portable class library requirements prevent use of // asynchronous locking mechanisms. The risk here is authenticating multiple times in parallel // which is bad from a performance standpoint but is transparent from a functional standpoint. AzureDataMarketAuthenticationResponse authenticationResponse = await client.AuthenticateAsync(clientId, clientSecret, cancellationToken); if (authenticationResponse != null) { token = new AccessToken { Token = authenticationResponse.AccessToken, Expiration = DateTime.UtcNow.AddSeconds(authenticationResponse.ExpiresIn) }; } } return token; }
/// <summary> /// 获取群发的视频MediaId /// </summary> /// <param name="token"></param> /// <param name="media_id">原视频的MediaId</param> /// <param name="title">群发视频标题</param> /// <param name="description">群发视频描述</param> /// <returns></returns> public static MediaUpload MassMessageGetVideoMediaId(this AccessToken token, string media_id, string title, string description) => Api.Mass.SendVideoPreGetMediaId(token.access_token, media_id, title, description);
/// <summary> /// 群发视频消息 /// </summary> /// <param name="token"></param> /// <param name="media_id">从方法AccessToken.MassMessageGetVideoMediaId获取到的MediaId</param> /// <param name="tag_id">群发到的标签的tag_id,参加用户管理中用户分组接口,可不填写tag_id以发送到全部用户</param> /// <returns></returns> public static MassResult MassVideo(this AccessToken token, string media_id, int tag_id = 0) => Api.Mass.SendVideo(token.access_token, media_id, tag_id);
/// <summary> /// 群发视频消息 /// </summary> /// <param name="token"></param> /// <param name="media_id">原视频的MediaId</param> /// <param name="title">群发视频标题</param> /// <param name="description">群发视频描述</param> /// <param name="openid">填写图文消息的接收者,一串OpenID列表,OpenID最少2个,最多10000个</param> /// <returns></returns> public static MassResult MassVideoByOpenId(this AccessToken token, string media_id, string title, string description, params string[] openid) => token.MassTextByOpenId(media_id, openid.ToList());
/// <summary> /// 上传图文消息素材 /// </summary> /// <param name="token"></param> /// <param name="items">图文列表</param> /// <returns></returns> public static MediaUpload MassMessageNewsUpload(this AccessToken token, params Article[] items) => token.MassMessageNewsUpload(items.ToList());
/// <summary> /// 群发卡券消息 /// </summary> /// <param name="token"></param> /// <param name="card_id">需要通过卡券接口获得</param> /// <param name="tag_id">群发到的标签的tag_id,参加用户管理中用户分组接口,可不填写tag_id以发送到全部用户</param> /// <returns></returns> public static MassResult MassCard(this AccessToken token, string card_id, int tag_id = 0) => Api.Mass.SendCard(token.access_token, card_id, tag_id);
/// <summary> /// 群发卡券消息 /// </summary> /// <param name="token"></param> /// <param name="card_id">需要通过卡券接口获得</param> /// <param name="openid">填写图文消息的接收者,一串OpenID列表,OpenID最少2个,最多10000个</param> /// <returns></returns> public static MassResult MassCardByOpenId(this AccessToken token, string card_id, List <string> openid) => Api.Mass.SendCard(token.access_token, card_id, openid);
/// <summary> /// 删除群发 /// </summary> /// <param name="token"></param> /// <param name="msgId">发送出去的消息ID</param> /// <param name="article_idx">图文序号</param> /// <returns></returns> public static JsonResult MassMessageSentDelete(this AccessToken token, long msgId, byte?article_idx = null) => Api.Mass.SentDelete(token.access_token, msgId, article_idx);
public ChangePasswordResponse(AccessToken accessToken, string refreshToken) { AccessToken = accessToken; RefreshToken = refreshToken; }
protected override void OnCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) { if (Element != null) { var session = Xamarin.Facebook.AccessToken.CurrentAccessToken; if (session == null) { Device.BeginInvokeOnMainThread(() => { Element.SendShowingLoggedOutUser(); }); } } }
private void handleFacebookAccessToken(AccessToken accessToken) { AuthCredential credential = FacebookAuthProvider.GetCredential(accessToken.Token); mAuth.SignInWithCredential(credential).AddOnCompleteListener(this, this); }
/// <summary> /// 群发文本消息 /// </summary> /// <param name="token"></param> /// <param name="text">文本信息</param> /// <param name="tag_id">群发到的标签的tag_id,参加用户管理中用户分组接口,可不填写tag_id以发送到全部用户</param> /// <returns></returns> public static MassResult MassText(this AccessToken token, string text, int tag_id = 0) => Api.Mass.SendText(token.access_token, text, tag_id);
/// <summary> /// 图文消息预览 /// </summary> /// <param name="token"></param> /// <param name="media_id">图文Id</param> /// <param name="openid">预览账号的OpenId</param> /// <param name="wxname">预览微信账号</param> /// <returns></returns> public static MassResult MassNewsPreview(this AccessToken token, string media_id, string openid = null, string wxname = null) => Api.Mass.PreviewMpNews(token.access_token, media_id, openid, wxname);
/// <summary> /// 群发图文消息 /// </summary> /// <param name="token"></param> /// <param name="media_id">图文Id</param> /// <param name="sendIgnoreReprint">图文消息被判定为转载时,是否继续群发。true为继续群发(转载),false为停止群发。该参数默认为false。</param> /// <param name="openid">填写图文消息的接收者,一串OpenID列表,OpenID最少2个,最多10000个</param> /// <returns></returns> public static MassResult MassNewsByOpenId(this AccessToken token, string media_id, bool sendIgnoreReprint = false, List <string> openid = null) => Api.Mass.SendMpNews(token.access_token, media_id, openid, sendIgnoreReprint);
/// <summary> /// 群发图文消息 /// </summary> /// <param name="token"></param> /// <param name="media_id">图文Id</param> /// <param name="tag_id">群发到的标签的tag_id,参加用户管理中用户分组接口,可不填写tag_id以发送到全部用户</param> /// <param name="sendIgnoreReprint">图文消息被判定为转载时,是否继续群发。true为继续群发(转载),false为停止群发。该参数默认为false。</param> /// <returns></returns> public static MassResult MassNews(this AccessToken token, string media_id, int tag_id = 0, bool sendIgnoreReprint = false) => Api.Mass.SendMpNews(token.access_token, media_id, tag_id, sendIgnoreReprint);
/// <summary> /// 查询群发消息发送状态 /// </summary> /// <param name="token"></param> /// <param name="msgId">群发消息后返回的消息id</param> /// <returns></returns> public static MassState MassMessageSentStateQuery(this AccessToken token, long msgId) => Api.Mass.MassMessageSentStateQuery(token.access_token, msgId);
public BdApiController(DataContext context, AccessToken accessToken) { _DbContext = context; _accessToken = accessToken; }
/// <summary> /// 卡券消息预览 /// </summary> /// <param name="token"></param> /// <param name="card_id">需要通过卡券接口获得</param> /// <param name="code"></param> /// <param name="timestamp"></param> /// <param name="signature"></param> /// <param name="openid">预览账号的OpenId</param> /// <param name="wxname">预览微信账号</param> /// <returns></returns> public static MassResult MassCardPreview(this AccessToken token, string card_id, string code, string timestamp, string signature, string openid = null, string wxname = null) => Api.Mass.PreviewCard(token.access_token, card_id, code, timestamp, signature, openid, wxname);
internal HTTPClient(Configuration configuration) { accessToken = new AccessToken(this); this.configuration = configuration; }
/// <summary> /// 群发卡券消息 /// </summary> /// <param name="token"></param> /// <param name="card_id">需要通过卡券接口获得</param> /// <param name="openid">填写图文消息的接收者,一串OpenID列表,OpenID最少2个,最多10000个</param> /// <returns></returns> public static MassResult MassCardByOpenId(this AccessToken token, string card_id, params string[] openid) => token.MassTextByOpenId(card_id, openid.ToList());
public static string AddInstagramAccount(string client_id, string client_secret, string redirect_uri, string code, long userId, long groupId, Model.DatabaseRepository dbr, ILogger _logger, Helper.Cache _redisCache, Helper.AppSettings _appSettings) { string ret = string.Empty; oAuthInstagram objInsta = new oAuthInstagram(); ConfigurationIns configi = new ConfigurationIns("https://api.instagram.com/oauth/authorize/", client_id, client_secret, redirect_uri, "https://api.instagram.com/oauth/access_token", "https://api.instagram.com/v1/", ""); oAuthInstagram _api = new oAuthInstagram(); _api = oAuthInstagram.GetInstance(configi); AccessToken access = new AccessToken(); access = _api.AuthGetAccessToken(code); UserController objusercontroller = new UserController(); if (access != null) { Domain.Socioboard.Models.Instagramaccounts Instagramaccounts = new Domain.Socioboard.Models.Instagramaccounts(); Domain.Socioboard.Models.Instagramaccounts objInstagramAccount; #region InstagramAccount InstagramResponse <User> objuser = objusercontroller.GetUserDetails(access.user.id, access.access_token); objInstagramAccount = new Domain.Socioboard.Models.Instagramaccounts(); objInstagramAccount.AccessToken = access.access_token; objInstagramAccount.InstagramId = access.user.id; try { objInstagramAccount.bio = access.user.bio; } catch { objInstagramAccount.bio = ""; } try { objInstagramAccount.ProfileUrl = access.user.profile_picture; } catch (Exception ex) { _logger.LogError("Instagram.asmx.cs >> AddInstagramAccount >> " + ex.StackTrace); } try { objInstagramAccount.InsUserName = access.user.username; } catch (Exception ex) { _logger.LogError("Instagram.asmx.cs >> AddInstagramAccount >> " + ex.StackTrace); } try { objInstagramAccount.TotalImages = objuser.data.counts.media; } catch (Exception ex) { _logger.LogError("Instagram.asmx.cs >> AddInstagramAccount >> " + ex.StackTrace); } try { objInstagramAccount.FollowedBy = objuser.data.counts.followed_by; } catch (Exception ex) { _logger.LogError("Instagram.asmx.cs >> AddInstagramAccount >> " + ex.StackTrace); } try { objInstagramAccount.Followers = objuser.data.counts.follows; } catch (Exception ex) { _logger.LogError("Instagram.asmx.cs >> AddInstagramAccount >> " + ex.StackTrace); } objInstagramAccount.UserId = userId; objInstagramAccount.IsActive = true; objInstagramAccount.lastUpdate = DateTime.UtcNow; if (objInstagramAccount.InstagramId != null) { Instagramaccounts = Api.Socioboard.Repositories.InstagramRepository.getInstagramAccount(objInstagramAccount.InstagramId, _redisCache, dbr); if (Instagramaccounts != null && Instagramaccounts.IsActive == true) { return("This Account is added by some body else."); } } else { return("Issue while fetching instagram userId"); } if (Instagramaccounts == null) { int isSaved = dbr.Add <Domain.Socioboard.Models.Instagramaccounts>(objInstagramAccount); if (isSaved == 1) { List <Domain.Socioboard.Models.Instagramaccounts> lstinsAcc = dbr.Find <Domain.Socioboard.Models.Instagramaccounts>(t => t.InstagramId.Equals(objInstagramAccount.InstagramId)).ToList(); if (lstinsAcc != null && lstinsAcc.Count() > 0) { isSaved = GroupProfilesRepository.AddGroupProfile(groupId, lstinsAcc.First().InstagramId, lstinsAcc.First().InsUserName, userId, lstinsAcc.First().ProfileUrl, Domain.Socioboard.Enum.SocialProfileType.Instagram, dbr); if (isSaved == 1) { _redisCache.Delete(Domain.Socioboard.Consatants.SocioboardConsts.CacheUserProfileCount + userId); _redisCache.Delete(Domain.Socioboard.Consatants.SocioboardConsts.CacheGroupProfiles + groupId); GetInstagramSelfFeeds(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, _appSettings); GetInstagramUserDetails(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, _redisCache, dbr); GetInstagramFollowing(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, 1, _appSettings); GetInstagramFollower(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, 1, _appSettings); new Thread(delegate() { GetInstagramPostLikes(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, 1, _appSettings); GetInstagramPostComments(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, _appSettings); }).Start(); return("Added_Successfully"); } } } } else { objInstagramAccount.id = Instagramaccounts.id; int isSaved = dbr.Update <Domain.Socioboard.Models.Instagramaccounts>(objInstagramAccount); if (isSaved == 1) { List <Domain.Socioboard.Models.Instagramaccounts> lstinsAcc = dbr.Find <Domain.Socioboard.Models.Instagramaccounts>(t => t.InstagramId.Equals(objInstagramAccount.InstagramId)).ToList(); if (lstinsAcc != null && lstinsAcc.Count() > 0) { isSaved = GroupProfilesRepository.AddGroupProfile(groupId, lstinsAcc.First().InstagramId, lstinsAcc.First().InsUserName, userId, lstinsAcc.First().ProfileUrl, Domain.Socioboard.Enum.SocialProfileType.Instagram, dbr); if (isSaved == 1) { _redisCache.Delete(Domain.Socioboard.Consatants.SocioboardConsts.CacheUserProfileCount + userId); _redisCache.Delete(Domain.Socioboard.Consatants.SocioboardConsts.CacheGroupProfiles + groupId); //todo : codes to update feeds GetInstagramSelfFeeds(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, _appSettings); GetInstagramUserDetails(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, _redisCache, dbr); GetInstagramFollowing(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, 1, _appSettings); GetInstagramFollower(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, 1, _appSettings); new Thread(delegate() { GetInstagramPostLikes(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, 1, _appSettings); GetInstagramPostComments(objInstagramAccount.InstagramId, objInstagramAccount.AccessToken, _appSettings); }).Start(); return("Added_Successfully"); } } } } } return("issue in access token fetching"); #endregion }
/// <summary> /// 视频消息预览 /// </summary> /// <param name="token"></param> /// <param name="media_id">原视频的MediaId</param> /// <param name="title">群发视频标题</param> /// <param name="description">群发视频描述</param> /// <param name="openid">预览账号的OpenId</param> /// <param name="wxname">预览微信账号</param> /// <returns></returns> public static MassResult MassVideoPreview(this AccessToken token, string media_id, string title, string description, string openid = null, string wxname = null) => Api.Mass.PreviewVideo(token.access_token, media_id, openid, wxname);
public AzureDevOpsRepositoryTarget(string url, AccessToken accessToken) : base(url, accessToken) { }
/// <summary> /// 群发视频消息 /// </summary> /// <param name="token"></param> /// <param name="media_id">原视频的MediaId</param> /// <param name="title">群发视频标题</param> /// <param name="description">群发视频描述</param> /// <param name="openid">填写图文消息的接收者,一串OpenID列表,OpenID最少2个,最多10000个</param> /// <returns></returns> public static MassResult MassVideoByOpenId(this AccessToken token, string media_id, string title, string description, List <string> openid) => Api.Mass.SendVideo(token.access_token, media_id, title, description, openid);
public LoginResponse(AccessToken accessToken, string refreshToken, bool success = false, string message = null) : base(success, message) { AccessToken = accessToken; RefreshToken = refreshToken; }
/// <summary> /// 群发视频消息 /// </summary> /// <param name="token"></param> /// <param name="media_id">原视频的MediaId</param> /// <param name="title">群发视频标题</param> /// <param name="description">群发视频描述</param> /// <param name="tag_id">群发到的标签的tag_id,参加用户管理中用户分组接口,可不填写tag_id以发送到全部用户</param> /// <returns></returns> public static MassResult MassVideo(this AccessToken token, string media_id, string title, string description, int tag_id = 0) => Api.Mass.SendVideo(token.access_token, token.MassMessageGetVideoMediaId(media_id, title, description).media_id, tag_id);
private async Task <AccessToken> ObtainAccessTokenAsync(string consumerKey, string consumerSecret, RequestToken token, string verifier) { //https://dev.DoYouBuzz.com/docs/authentication _logger.WriteVerbose("ObtainAccessToken"); var nonce = Guid.NewGuid().ToString("N"); var authorizationParts = new SortedDictionary <string, string> { { "oauth_consumer_key", consumerKey }, { "oauth_nonce", nonce }, { "oauth_signature_method", "HMAC-SHA1" }, { "oauth_token", token.Token }, { "oauth_timestamp", GenerateTimeStamp() }, { "oauth_verifier", verifier }, { "oauth_version", "1.0" }, }; var parameterBuilder = new StringBuilder(); foreach (var authorizationKey in authorizationParts) { parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); } parameterBuilder.Length--; var parameterString = parameterBuilder.ToString(); var canonicalRequestBuilder = new StringBuilder(); canonicalRequestBuilder.Append(HttpMethod.Post.Method); canonicalRequestBuilder.Append("&"); canonicalRequestBuilder.Append(Uri.EscapeDataString(AccessTokenEndpoint)); canonicalRequestBuilder.Append("&"); canonicalRequestBuilder.Append(Uri.EscapeDataString(parameterString)); var signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalRequestBuilder.ToString()); authorizationParts.Add("oauth_signature", signature); authorizationParts.Remove("oauth_verifier"); var authorizationHeaderBuilder = new StringBuilder(); authorizationHeaderBuilder.Append("OAuth "); foreach (var authorizationPart in authorizationParts) { authorizationHeaderBuilder.AppendFormat( "{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); } authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; var request = new HttpRequestMessage(HttpMethod.Post, AccessTokenEndpoint); request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString()); var formPairs = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("oauth_verifier", verifier) }; request.Content = new FormUrlEncodedContent(formPairs); var response = await _httpClient.SendAsync(request, Request.CallCancelled); if (!response.IsSuccessStatusCode) { _logger.WriteError("AccessToken request failed with a status code of " + response.StatusCode); response.EnsureSuccessStatusCode(); // throw } var responseText = await response.Content.ReadAsStringAsync(); var responseParameters = WebHelpers.ParseForm(responseText); var accessToken = new AccessToken { Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), UserId = "", }; var userInfo = GetUserInfo(consumerKey, consumerSecret, accessToken); accessToken.UserId = userInfo.Id.ToString(); return(accessToken); }
private async Task <AccessToken> GetUserInfo(string consumerKey, string consumerSecret, AccessToken token) { _logger.WriteVerbose("ObtainAccessToken"); var nonce = Guid.NewGuid().ToString("N"); var authorizationParts = new SortedDictionary <string, string> { { "oauth_consumer_key", consumerKey }, { "oauth_nonce", nonce }, { "oauth_signature_method", "HMAC-SHA1" }, { "oauth_token", token.Token }, { "oauth_timestamp", GenerateTimeStamp() }, { "oauth_version", "1.0" }, }; var parameterBuilder = new StringBuilder(); foreach (var authorizationKey in authorizationParts) { parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value)); } parameterBuilder.Length--; var parameterString = parameterBuilder.ToString(); var canonicalRequestBuilder = new StringBuilder(); canonicalRequestBuilder.Append(HttpMethod.Post.Method); canonicalRequestBuilder.Append("&"); canonicalRequestBuilder.Append(Uri.EscapeDataString(UserInfoEndpoint)); canonicalRequestBuilder.Append("&"); canonicalRequestBuilder.Append(Uri.EscapeDataString(parameterString)); var signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalRequestBuilder.ToString()); authorizationParts.Add("oauth_signature", signature); authorizationParts.Remove("oauth_verifier"); var authorizationHeaderBuilder = new StringBuilder(); authorizationHeaderBuilder.Append("OAuth "); foreach (var authorizationPart in authorizationParts) { authorizationHeaderBuilder.AppendFormat("{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value)); } authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2; var request = new HttpRequestMessage(HttpMethod.Post, UserInfoEndpoint); request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString()); var response = await _httpClient.SendAsync(request, Request.CallCancelled); if (!response.IsSuccessStatusCode) { _logger.WriteError("AccessToken request failed with a status code of " + response.StatusCode); response.EnsureSuccessStatusCode(); // throw } var responseText = await response.Content.ReadAsStringAsync(); var document = new XmlDocument(); document.LoadXml(responseText); var json = JsonConvert.SerializeXmlNode(document, Formatting.None); var userInfo = JsonConvert.DeserializeObject <UserInfo>(json); return(new AccessToken { Token = token.Token, TokenSecret = token.TokenSecret, UserId = userInfo.Id.ToString(), }); }
protected override UserInformation RetrieveUserInformation(AccessToken accessToken) { if (accessToken == null) { throw new ArgumentNullException("accessToken"); } if (string.IsNullOrEmpty(accessToken.PublicToken)) { throw new ArgumentException("accessToken.PublicToken"); } IRestResponse <UserInfoResult> response; try { var restRequest = new RestRequest("/oauth2/v2/userinfo", Method.GET); restRequest.AddParameter(AccessTokenKey, accessToken.PublicToken); var restClient = RestClientFactory.CreateRestClient("https://www.googleapis.com"); TraceSource.TraceVerbose("Retrieving user information. Google Endpoint: {0}", restClient.BuildUri(restRequest).AbsoluteUri); response = restClient.Execute <UserInfoResult>(restRequest); } catch (Exception exception) { var errorMessage = string.Format("Failed to retrieve any UserInfo data from the Google Api. Error Messages: {0}", exception.RecursiveErrorMessages()); TraceSource.TraceError(errorMessage); throw new AuthenticationException(errorMessage, exception); } if (response == null || response.StatusCode != HttpStatusCode.OK) { var errorMessage = string.Format( "Failed to obtain some UserInfo data from the Google Api OR the the response was not an HTTP Status 200 OK. Response Status: {0}. Response Description: {1}. Error Message: {2}.", response == null ? "-- null response --" : response.StatusCode.ToString(), response == null ? string.Empty : response.StatusDescription, response == null ? string.Empty : response.ErrorException == null ? "--no error exception--" : response.ErrorException.RecursiveErrorMessages()); TraceSource.TraceError(errorMessage); throw new AuthenticationException(errorMessage); } // Lets check to make sure we have some bare minimum data. if (string.IsNullOrEmpty(response.Data.Id)) { const string errorMessage = "We were unable to retrieve the User Id from Google API, the user may have denied the authorization."; TraceSource.TraceError(errorMessage); throw new AuthenticationException(errorMessage); } return(new UserInformation { Id = response.Data.Id, Gender = string.IsNullOrEmpty(response.Data.Gender) ? GenderType.Unknown : GenderTypeHelpers.ToGenderType(response.Data.Gender), Name = response.Data.Name, Email = response.Data.Email, Locale = response.Data.Locale, Picture = response.Data.Picture, UserName = response.Data.GivenName }); }
/// <summary> /// 群发图文消息 /// </summary> /// <param name="token"></param> /// <param name="media_id">图文Id</param> /// <param name="sendIgnoreReprint">图文消息被判定为转载时,是否继续群发。true为继续群发(转载),false为停止群发。该参数默认为false。</param> /// <param name="openid">填写图文消息的接收者,一串OpenID列表,OpenID最少2个,最多10000个</param> /// <returns></returns> public static MassResult MassNewsByOpenId(this AccessToken token, string media_id, bool sendIgnoreReprint = false, params string[] openid) => token.MassNewsByOpenId(media_id, sendIgnoreReprint, openid.ToList());
/// <summary> /// 上传图文消息素材 /// </summary> /// <param name="token"></param> /// <param name="items">图文列表</param> /// <returns></returns> public static MediaUpload MassMessageNewsUpload(this AccessToken token, List <Article> items) => Api.Mass.UploadNews(token.access_token, items);