Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Challenge #194

Merged
merged 2 commits into from
Sep 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion InstaSharper/API/IInstaApi.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using InstaSharper.Classes;
using InstaSharper.Classes.Models;
using InstaSharper.Classes.ResponseWrappers;
using InstaSharper.Classes.ResponseWrappers.BaseResponse;

namespace InstaSharper.API
Expand Down Expand Up @@ -55,6 +56,32 @@ Task<IResult<CreationResponse>> CreateNewAccount(string username, string passwor
/// </returns>
Task<IResult<InstaLoginResult>> LoginAsync();

/// <summary>
/// Search Place
/// </summary>
Task<IResult<FbSearchPlaceResponse>> SearchPlace(string searchQuery, int count = 5);


/// <summary>
/// Reset challenge asynchronously
/// </summary>
Task<IResult<InstaResetChallenge>> ResetChallenge();

/// <summary>
/// Get verify method asynchronously
/// </summary>
Task<IResult<InstaResetChallenge>> GetVerifyStep();

/// <summary>
/// Choose verify method asynchronously
/// </summary>
Task<IResult<InstaResetChallenge>> ChooseVerifyMethod(int choice);

/// <summary>
/// Send verify code asynchronously
/// </summary>
Task<IResult<InstaResetChallenge>> SendVerifyCode(string securityCode);

/// <summary>
/// 2-Factor Authentication Login using a verification code
/// Before call this method, please run LoginAsync first.
Expand Down
129 changes: 128 additions & 1 deletion InstaSharper/API/InstaApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ internal class InstaApi : IInstaApi
private IStoryProcessor _storyProcessor;

private TwoFactorLoginInfo _twoFactorInfo;
private InstaChallenge _challengeInfo;
private UserSessionData _user;
private IUserProcessor _userProcessor;

Expand Down Expand Up @@ -1017,7 +1018,13 @@ public async Task<IResult<InstaLoginResult>> LoginAsync()
//2FA is required!
return Result.Fail("Two Factor Authentication is required", InstaLoginResult.TwoFactorRequired);
}

if (loginFailReason.ChallengeRequired)
{
_challengeInfo = loginFailReason.Challenge;
//Challenge is Required!
return Result.Fail("Challenge is required", InstaLoginResult.ChallengeRequired);
}

return Result.UnExpectedResponse<InstaLoginResult>(response, json);
}

Expand All @@ -1039,6 +1046,126 @@ public async Task<IResult<InstaLoginResult>> LoginAsync()
}
}

/// <summary>
/// Search Place
/// </summary>
public async Task<IResult<FbSearchPlaceResponse>> SearchPlace(string searchQuery, int count)
{
var signature =
$"{_httpRequestProcessor.RequestMessage.GenerateSignature(InstaApiConstants.IG_SIGNATURE_KEY)}" +
$".{_httpRequestProcessor.RequestMessage.GetMessageString()}";
var fbSeachPlaceUri = UriCreator.GetFbSearchPlace(count, _user.RankToken, searchQuery);
var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, fbSeachPlaceUri, _deviceInfo);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION,
InstaApiConstants.IG_SIGNATURE_KEY_VERSION);
var response = await _httpRequestProcessor.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
var fbSeachPlaceResponse = JsonConvert.DeserializeObject<FbSearchPlaceResponse>(json);
return Result.Success(fbSeachPlaceResponse);
}

/// <summary>
/// Reset challenge asynchronously
/// </summary>
public async Task<IResult<InstaResetChallenge>> ResetChallenge()
{
var signature =
$"{_httpRequestProcessor.RequestMessage.GenerateSignature(InstaApiConstants.IG_SIGNATURE_KEY)}" +
$".{_httpRequestProcessor.RequestMessage.GetMessageString()}";
var fields = new Dictionary<string, string>
{
{InstaApiConstants.HEADER_IG_SIGNATURE, signature},
{InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION, InstaApiConstants.IG_SIGNATURE_KEY_VERSION}
};
var token = _challengeInfo.ApiPath.Substring(11);
var instaUri = UriCreator.GetResetChallengeUri(token);
var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
request.Content = new FormUrlEncodedContent(fields);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION,
InstaApiConstants.IG_SIGNATURE_KEY_VERSION);
var response = await _httpRequestProcessor.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
var resetChallengeResponse = JsonConvert.DeserializeObject<InstaResetChallenge>(json);
return Result.Success(resetChallengeResponse);
}

/// <summary>
/// Get verify method asynchronously
/// </summary>
public async Task<IResult<InstaResetChallenge>> GetVerifyStep()
{
var signature =
$"{_httpRequestProcessor.RequestMessage.GenerateSignature(InstaApiConstants.IG_SIGNATURE_KEY)}" +
$".{_httpRequestProcessor.RequestMessage.GetMessageString()}";
var token = _challengeInfo.ApiPath.Substring(11);
var instaUri = UriCreator.GetVerifyMethod(token);
var request = HttpHelper.GetDefaultRequest(HttpMethod.Get, instaUri, _deviceInfo);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION,
InstaApiConstants.IG_SIGNATURE_KEY_VERSION);
var response = await _httpRequestProcessor.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
var resetChallengeResponse = JsonConvert.DeserializeObject<InstaResetChallenge>(json);
return Result.Success(resetChallengeResponse);
}

/// <summary>
/// Choose verify method asynchronously
/// </summary>
public async Task<IResult<InstaResetChallenge>> ChooseVerifyMethod(int choice)
{
var signature =
$"{_httpRequestProcessor.RequestMessage.GenerateSignature(InstaApiConstants.IG_SIGNATURE_KEY)}" +
$".{_httpRequestProcessor.RequestMessage.GetMessageString()}";
var fields = new Dictionary<string, string>
{
{InstaApiConstants.VEFITY_CHOICE, choice.ToString()},
};
var token = _challengeInfo.ApiPath.Substring(11);
var instaUri = UriCreator.GetVerifyMethod(token);
var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
request.Content = new FormUrlEncodedContent(fields);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION,
InstaApiConstants.IG_SIGNATURE_KEY_VERSION);
var response = await _httpRequestProcessor.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
var resetChallengeResponse = JsonConvert.DeserializeObject<InstaResetChallenge>(json);
return Result.Success(resetChallengeResponse);
}

/// <summary>
/// Send verify code asynchronously
/// </summary>
public async Task<IResult<InstaResetChallenge>> SendVerifyCode(string securityCode)
{
var signature =
$"{_httpRequestProcessor.RequestMessage.GenerateSignature(InstaApiConstants.IG_SIGNATURE_KEY)}" +
$".{_httpRequestProcessor.RequestMessage.GetMessageString()}";
var fields = new Dictionary<string, string>
{
{InstaApiConstants.SECURITY_CODE, securityCode.ToString()},
};
var token = _challengeInfo.ApiPath.Substring(11);
var instaUri = UriCreator.GetVerifyMethod(token);
var request = HttpHelper.GetDefaultRequest(HttpMethod.Post, instaUri, _deviceInfo);
request.Content = new FormUrlEncodedContent(fields);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE, signature);
request.Properties.Add(InstaApiConstants.HEADER_IG_SIGNATURE_KEY_VERSION,
InstaApiConstants.IG_SIGNATURE_KEY_VERSION);
var response = await _httpRequestProcessor.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
if (response.StatusCode != HttpStatusCode.OK )
{
return Result.Fail<InstaResetChallenge>("invalid verify code");
}
var sendVerifyCodeResponse = JsonConvert.DeserializeObject<InstaResetChallenge>(json);
IsUserAuthenticated = sendVerifyCodeResponse.LoggedInUser?.UserName.ToLower() == _user.UserName.ToLower();
return Result.Success(sendVerifyCodeResponse);
}

/// <summary>
/// 2-Factor Authentication Login using a verification code
/// Before call this method, please run LoginAsync first.
Expand Down
10 changes: 8 additions & 2 deletions InstaSharper/API/InstaApiConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ public const string
public const string HEADER_XGOOGLE_AD_IDE = "X-Google-AD-ID";
public const string COMMENT_BREADCRUMB_KEY = "iN4$aGr0m";
public const int TIMEZONE_OFFSET = 43200;

public const string VEFITY_CHOICE = "choice";
public const string SECURITY_CODE = "security_code";


public const string INSTAGRAM_URL = "https://i.instagram.com";
public const string API = "/api";
public const string API_SUFFIX = API + API_VERSION;
Expand Down Expand Up @@ -74,7 +77,10 @@ public const string
public const string GET_USER_FOLLOWING = API_SUFFIX + "/friendships/{0}/following/?rank_token={1}";
public const string GET_TAG_FEED = API_SUFFIX + "/feed/tag/{0}";
public const string GET_RANKED_RECIPIENTS = API_SUFFIX + "/direct_v2/ranked_recipients";

public const string RESET_CHALLENGE = API_SUFFIX + "/challenge/reset/{0}";
public const string VERIFY_METHOD = API_SUFFIX + "/challenge/{0}";
public const string FB_SEARCH_PLACE = API_SUFFIX + "/fbsearch/places/?count={0}&query={1}&rank_token={2}";

public const string GET_LIST_COLLECTIONS = API_SUFFIX + "/collections/list/";
public const string GET_COLLECTION = API_SUFFIX + "/feed/collection/{0}/";
public const string CREATE_COLLECTION = API_SUFFIX + "/collections/create/";
Expand Down
11 changes: 10 additions & 1 deletion InstaSharper/Classes/InstaLoginBaseResponse.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using InstaSharper.Classes.ResponseWrappers;
using Newtonsoft.Json;

namespace InstaSharper.Classes
{
Expand All @@ -19,5 +20,13 @@ internal class InstaLoginBaseResponse
[JsonProperty("two_factor_info")] public TwoFactorLoginInfo TwoFactorLoginInfo { get; set; }

#endregion

#region Challenge Required

[JsonIgnore] public bool ChallengeRequired => ErrorType == "checkpoint_challenge_required";

[JsonProperty("challenge")] public InstaChallenge Challenge { get; set; }

#endregion
}
}
1 change: 1 addition & 0 deletions InstaSharper/Classes/InstaLoginResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public enum InstaLoginResult
BadPassword,
InvalidUser,
TwoFactorRequired,
ChallengeRequired,
Exception
}
}
3 changes: 2 additions & 1 deletion InstaSharper/Classes/ResponseType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public enum ResponseType
WrongRequest = 6,
SomePagesSkipped = 7,
UnExpectedResponse = 8,
InternalException = 9
InternalException = 9,
CheckPointChallengeRequired = 10
}
}
25 changes: 25 additions & 0 deletions InstaSharper/Classes/ResponseWrappers/FbLocation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Newtonsoft.Json;

namespace InstaSharper.Classes.ResponseWrappers
{
public class FbLocation
{
[JsonProperty("pk")] public long Pk { get; set; }

[JsonProperty("name")] public string Name { get; set; }

[JsonProperty("address")] public string Address { get; set; }

[JsonProperty("city")] public string City { get; set; }

[JsonProperty("short_name")] public string ShortName { get; set; }

[JsonProperty("lng")] public double Lng { get; set; }

[JsonProperty("lat")] public double Lat { get; set; }

[JsonProperty("external_source")] public string ExternalSource { get; set; }

[JsonProperty("facebook_places_id")] public object FacebookPlacesId { get; set; }
}
}
20 changes: 20 additions & 0 deletions InstaSharper/Classes/ResponseWrappers/FbPlace.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Collections.Generic;
using Newtonsoft.Json;

namespace InstaSharper.Classes.ResponseWrappers
{
public class FbPlace
{
[JsonProperty("location")]
public FbLocation Location { get; set; }

[JsonProperty("title")]
public string Title { get; set; }

[JsonProperty("subtitle")]
public string Subtitle { get; set; }

[JsonProperty("media_bundles")]
public IList<object> MediaBundles { get; set; }
}
}
16 changes: 16 additions & 0 deletions InstaSharper/Classes/ResponseWrappers/FbSearchPlaceResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Collections.Generic;
using Newtonsoft.Json;

namespace InstaSharper.Classes.ResponseWrappers
{
public class FbSearchPlaceResponse
{
[JsonProperty("items")] public IList<FbPlace> Items { get; set; }

[JsonProperty("has_more")] public bool HasMore { get; set; }

[JsonProperty("rank_token")] public string RankToken { get; set; }

[JsonProperty("status")] public string Status { get; set; }
}
}
19 changes: 19 additions & 0 deletions InstaSharper/Classes/ResponseWrappers/InstaChallenge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Newtonsoft.Json;

namespace InstaSharper.Classes.ResponseWrappers
{
public class InstaChallenge
{
[JsonProperty("url")] public string Url { get; set; }

[JsonProperty("api_path")] public string ApiPath { get; set; }

[JsonProperty("hide_webview_header")] public bool HideWebviewHeader { get; set; }

[JsonProperty("lock")] public bool Lock { get; set; }

[JsonProperty("logout")] public bool Logout { get; set; }

[JsonProperty("native_flow")] public bool NativeFlow { get; set; }
}
}
20 changes: 20 additions & 0 deletions InstaSharper/Classes/ResponseWrappers/InstaNametag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Newtonsoft.Json;

namespace InstaSharper.Classes.ResponseWrappers
{
public class InstaNametag
{

[JsonProperty("mode")]
public int Mode { get; set; }

[JsonProperty("gradient")]
public int Gradient { get; set; }

[JsonProperty("emoji")]
public string Emoji { get; set; }

[JsonProperty("selfie_sticker")]
public int SelfieSticker { get; set; }
}
}
23 changes: 23 additions & 0 deletions InstaSharper/Classes/ResponseWrappers/InstaResetChallenge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Newtonsoft.Json;

namespace InstaSharper.Classes.ResponseWrappers
{
public class InstaResetChallenge
{
[JsonProperty("step_name")] public string StepName { get; set; }

[JsonProperty("step_data")] public InstaStepData StepData { get; set; }

[JsonProperty("user_id")] public long UserId { get; set; }

[JsonProperty("nonce_code")] public string NonceCode { get; set; }

[JsonProperty("status")] public string Status { get; set; }

[JsonProperty("logged_in_user")] public InstaUserResponse LoggedInUser { get; set; }

[JsonProperty("action")] public string Action { get; set; }

[JsonProperty("auto_login")] public bool AutoLogin { get; set; }
}
}
Loading