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();

        }
Example #2
0
        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");
            }
        }
Example #3
0
        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 );
        }
Example #4
0
        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);
        }
Example #7
0
        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();
        }
Example #8
0
 //-----------------------------------------------------------------------------
 public virtual JsonObject Publish( AccessToken accessToken, String content, String absPic )
 {
     if (strUtil.IsNullOrEmpty( absPic )) {
         return PublishPost( accessToken, content );
     }
     else {
         return PublishPic( accessToken, content, absPic );
     }
 }
Example #9
0
        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;
        }
Example #10
0
        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;
        }
Example #11
0
        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);
        }
Example #12
0
        /// <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;
		}
Example #14
0
		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;

		}
Example #15
0
 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" });
     }
 }
Example #16
0
		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;

		}
Example #17
0
		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;

		}
Example #18
0
		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;
		}
Example #19
0
        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;
        }
Example #20
0
    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);
        }
Example #24
0
 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 );
		}
Example #26
0
		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;

		}
Example #27
0
        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;
        }
Example #31
0
 /// <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);
Example #32
0
 /// <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);
Example #33
0
 /// <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());
Example #34
0
 /// <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());
Example #35
0
 /// <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);
Example #36
0
 /// <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);
Example #37
0
 /// <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();
             });
         }
     }
 }
Example #40
0
        private void handleFacebookAccessToken(AccessToken accessToken)
        {
            AuthCredential credential = FacebookAuthProvider.GetCredential(accessToken.Token);

            mAuth.SignInWithCredential(credential).AddOnCompleteListener(this, this);
        }
Example #41
0
 /// <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);
Example #42
0
 /// <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);
Example #43
0
 /// <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);
Example #44
0
 /// <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);
Example #45
0
 /// <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);
Example #46
0
 public BdApiController(DataContext context, AccessToken accessToken)
 {
     _DbContext   = context;
     _accessToken = accessToken;
 }
Example #47
0
 /// <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);
Example #48
0
 internal HTTPClient(Configuration configuration)
 {
     accessToken        = new AccessToken(this);
     this.configuration = configuration;
 }
Example #49
0
 /// <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
        }
Example #51
0
 /// <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);
Example #52
0
 public AzureDevOpsRepositoryTarget(string url, AccessToken accessToken)
     : base(url, accessToken)
 {
 }
Example #53
0
 /// <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;
 }
Example #55
0
 /// <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);
Example #56
0
        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);
        }
Example #57
0
        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
            });
        }
Example #59
0
 /// <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());
Example #60
0
 /// <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);