Skip to content

Commit

Permalink
Completed initial support for OAuth2 (#252)
Browse files Browse the repository at this point in the history
* Working on OAuth2

* Working on OAuth2.

* Completed initial OAuth2 support for ASP.NET MVC.
  • Loading branch information
JoeMayo authored Jan 24, 2022
1 parent 3779a10 commit 32c50e1
Show file tree
Hide file tree
Showing 38 changed files with 1,207 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public HomeController(ILogger<HomeController> logger)

public IActionResult Index()
{
if (!new SessionStateCredentialStore(HttpContext.Session).HasAllCredentials())
return RedirectToAction("Index", "OAuth");
if (!new OAuth2SessionCredentialStore(HttpContext.Session).HasAllCredentials())
return RedirectToAction("Index", "OAuth2");

return View();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Extensions;
using LinqToTwitter.OAuth;
using Microsoft.Extensions.Primitives;
using System.Collections.Generic;

namespace LinqToTwitter.MVC.CSharp.Controllers
{
public class OAuth2Controller : Controller
{
private readonly ILogger<OAuth2Controller> logger;

public OAuth2Controller(ILogger<OAuth2Controller> logger)
{
this.logger = logger;
}

public ActionResult Index()
{
return View();
}

public async Task<ActionResult> BeginAsync()
{
string twitterCallbackUrl = Request.GetDisplayUrl().Replace("Begin", "Complete");

var auth = new MvcOAuth2Authorizer
{
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
{
ClientID = Environment.GetEnvironmentVariable(OAuthKeys.TwitterClientID),
ClientSecret = Environment.GetEnvironmentVariable(OAuthKeys.TwitterClientSecret),
Scopes = new List<string>
{
"tweet.read",
"tweet.write",
"tweet.moderate.write",
"users.read",
"follows.read",
"follows.write",
"offline.access",
"space.read",
"mute.read",
"mute.write",
"like.read",
"like.write",
"block.read",
"block.write"
},
RedirectUri = twitterCallbackUrl,
}
};

return await auth.BeginAuthorizeAsync("MyState");
}

public async Task<ActionResult> CompleteAsync()
{
var auth = new MvcOAuth2Authorizer
{
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
};

Request.Query.TryGetValue("code", out StringValues code);
Request.Query.TryGetValue("state", out StringValues state);

await auth.CompleteAuthorizeAsync(code, state);

return RedirectToAction("Index", "Home");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ namespace LinqToTwitter.MVC.CSharp.Controllers
{
public class OAuthController : Controller
{
private readonly ILogger<OAuthController> _logger;
private readonly ILogger<OAuthController> logger;

public OAuthController(ILogger<OAuthController> logger)
{
_logger = logger;
this.logger = logger;
}

public ActionResult Index()
Expand All @@ -36,7 +36,7 @@ public async Task<ActionResult> BeginAsync()
//var parameters = new Dictionary<string, string> { { "my_custom_param", "val" } };
//string twitterCallbackUrl = Request.GetDisplayUrl().Replace("Begin", "Complete");
//return await auth.BeginAuthorizationAsync(new Uri(twitterCallbackUrl), parameters);

await auth.CredentialStore.ClearAsync();
string twitterCallbackUrl = Request.GetDisplayUrl().Replace("Begin", "Complete");
return await auth.BeginAuthorizationAsync(new Uri(twitterCallbackUrl));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using LinqToTwitter;
using LinqToTwitter.Common;
using LinqToTwitter.MVC.CSharp.Models;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -10,11 +11,11 @@

namespace MvcDemo.Controllers
{
public class StatusDemosController : Controller
public class TweetDemosController : Controller
{
readonly IWebHostEnvironment webHostEnvironment;

public StatusDemosController(IWebHostEnvironment webHostEnvironment)
public TweetDemosController(IWebHostEnvironment webHostEnvironment)
{
this.webHostEnvironment = webHostEnvironment;
}
Expand All @@ -38,14 +39,14 @@ public ActionResult Tweet()
[ActionName("Tweet")]
public async Task<ActionResult> TweetAsync(SendTweetViewModel tweet)
{
var auth = new MvcAuthorizer
var auth = new MvcOAuth2Authorizer
{
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
};

var ctx = new TwitterContext(auth);

Status responseTweet = await ctx.TweetAsync(tweet.Text);
Tweet responseTweet = await ctx.TweetAsync(tweet.Text);

var responseTweetVM = new SendTweetViewModel
{
Expand All @@ -56,40 +57,57 @@ public async Task<ActionResult> TweetAsync(SendTweetViewModel tweet)
return View(responseTweetVM);
}

[ActionName("HomeTimeline")]
public async Task<ActionResult> HomeTimelineAsync()
[ActionName("TweetTimeline")]
public async Task<ActionResult> TweetTimelineAsync()
{
var auth = new MvcAuthorizer
var auth = new MvcOAuth2Authorizer
{
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
};

var ctx = new TwitterContext(auth);

var tweets =
var userQuery =
await
(from usr in ctx.TwitterUser
where usr.Type == UserType.UsernameLookup &&
usr.Usernames == "Linq2Twitr" &&
usr.UserFields == UserField.ProfileImageUrl
select usr)
.SingleOrDefaultAsync();

TwitterUser user = userQuery.Users.FirstOrDefault();

var tweetQuery =
await
(from tweet in ctx.Status
where tweet.Type == StatusType.Home
(from tweet in ctx.Tweets
where tweet.Type == TweetType.TweetsTimeline &&
tweet.ID == user.ID.ToString()
select tweet)
.SingleOrDefaultAsync();

var tweets =
(from tweet in tweetQuery.Tweets
select new TweetViewModel
{
ImageUrl = tweet.User.ProfileImageUrl,
ScreenName = tweet.User.ScreenNameResponse,
Text = tweet.Text
ImageUrl = user.ProfileImageUrl,
ScreenName = user.Name,
Text = tweet.Text
})
.ToListAsync();
.ToList();

return View(tweets);
}

[ActionName("UploadImage")]
public async Task<ActionResult> UploadImageAsync()
{
var auth = new MvcAuthorizer
var auth = new MvcOAuth2Authorizer
{
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
};

var twitterCtx = new TwitterContext(auth);
var ctx = new TwitterContext(auth);

string status = $"Testing multi-image tweet #Linq2Twitter £ {DateTime.Now}";
string mediaCategory = "tweet_image";
Expand All @@ -102,23 +120,23 @@ public async Task<ActionResult> UploadImageAsync()
var imageUploadTasks =
new List<Task<Media>>
{
twitterCtx.UploadMediaAsync(System.IO.File.ReadAllBytes(path), "image/jpg", mediaCategory),
ctx.UploadMediaAsync(System.IO.File.ReadAllBytes(path), "image/jpg", mediaCategory),
};

await Task.WhenAll(imageUploadTasks);

List<ulong> mediaIds =
List<string> mediaIds =
(from tsk in imageUploadTasks
select tsk.Result.MediaID)
select tsk.Result.MediaID.ToString())
.ToList();

Status tweet = await twitterCtx.TweetAsync(status, mediaIds);
Tweet tweet = await ctx.TweetMediaAsync(status, mediaIds);

return View(
new TweetViewModel
new MediaViewModel
{
ImageUrl = tweet.User.ProfileImageUrl,
ScreenName = tweet.User.ScreenNameResponse,
MediaUrl = tweet.Entities.Urls.FirstOrDefault()?.Url,
Description = tweet.Entities.Urls.FirstOrDefault()?.Description,
Text = tweet.Text
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="LinqToTwitter.AspNet" Version="6.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
</ItemGroup>

<ItemGroup>
<Reference Include="LinqToTwitter">
<HintPath>..\..\..\..\..\src\LinqToTwitter6\LinqToTwitter.AspNet\bin\Debug\net5.0\LinqToTwitter.dll</HintPath>
</Reference>
<Reference Include="LinqToTwitter.AspNet">
<HintPath>..\..\..\..\..\src\LinqToTwitter6\LinqToTwitter.AspNet\bin\Debug\net5.0\LinqToTwitter.AspNet.dll</HintPath>
</Reference>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace LinqToTwitter.MVC.CSharp.Models
{
public class MediaViewModel
{
[DisplayName("Image")]
[DataType(DataType.ImageUrl)]
public string MediaUrl { get; set; }

[DisplayName("Screen Name")]
public string Description { get; set; }

[DisplayName("Tweet")]
public string Text { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:62333",
"applicationUrl": "http://127.0.0.1:62333",
"sslPort": 44395
}
},
Expand All @@ -19,7 +19,7 @@
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"applicationUrl": "https://127.0.0.1:5001;http://127.0.0.1:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ public void ConfigureServices(IServiceCollection services)

services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@{
ViewBag.Title = "Authorizing Application";
ViewBag.Title = "Authorizing Application with OAuth 1.0A";
}

<h2>Authorize with OAuth</h2>
<h2>Authorize with OAuth 1.0A</h2>
@Html.ActionLink("Begin the Authorization Process", "Begin")

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@{
ViewBag.Title = "Authorizing Application with OAuth 2.0";
}

<h2>Authorize with OAuth 2.0</h2>
@Html.ActionLink("Begin the Authorization Process", "Begin")

Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="StatusDemos" asp-action="Index">Status Demos</a>
<a class="nav-link text-dark" asp-area="" asp-controller="TweetDemos" asp-action="Index">Tweet Demos</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@{
ViewBag.Title = "Tweet Demos";
}

<h2>Tweet Demos</h2>

<p>@Html.ActionLink("Tweet Demo", "Tweet")</p>

<p>@Html.ActionLink("Tweet Timeline Demo", "TweetTimeline")</p>

<p>@Html.ActionLink("Upload Image Demo", "UploadImage")</p>
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
@model IEnumerable<LinqToTwitter.MVC.CSharp.Models.TweetViewModel>

@{
ViewBag.Title = "Home Timeline";
ViewBag.Title = "Tweet Timeline";
}

<h2>Home Timeline Demo</h2>
<h2>Tweet Timeline Demo</h2>

<table class="table">
<tr>
Expand Down
Loading

0 comments on commit 32c50e1

Please sign in to comment.