Skip to content

Commit 32c50e1

Browse files
authored
Completed initial support for OAuth2 (#252)
* Working on OAuth2 * Working on OAuth2. * Completed initial OAuth2 support for ASP.NET MVC.
1 parent 3779a10 commit 32c50e1

38 files changed

+1207
-96
lines changed

Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Controllers/HomeController.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ public HomeController(ILogger<HomeController> logger)
1616

1717
public IActionResult Index()
1818
{
19-
if (!new SessionStateCredentialStore(HttpContext.Session).HasAllCredentials())
20-
return RedirectToAction("Index", "OAuth");
19+
if (!new OAuth2SessionCredentialStore(HttpContext.Session).HasAllCredentials())
20+
return RedirectToAction("Index", "OAuth2");
2121

2222
return View();
2323
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Microsoft.Extensions.Logging;
3+
using System;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Http.Extensions;
6+
using LinqToTwitter.OAuth;
7+
using Microsoft.Extensions.Primitives;
8+
using System.Collections.Generic;
9+
10+
namespace LinqToTwitter.MVC.CSharp.Controllers
11+
{
12+
public class OAuth2Controller : Controller
13+
{
14+
private readonly ILogger<OAuth2Controller> logger;
15+
16+
public OAuth2Controller(ILogger<OAuth2Controller> logger)
17+
{
18+
this.logger = logger;
19+
}
20+
21+
public ActionResult Index()
22+
{
23+
return View();
24+
}
25+
26+
public async Task<ActionResult> BeginAsync()
27+
{
28+
string twitterCallbackUrl = Request.GetDisplayUrl().Replace("Begin", "Complete");
29+
30+
var auth = new MvcOAuth2Authorizer
31+
{
32+
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
33+
{
34+
ClientID = Environment.GetEnvironmentVariable(OAuthKeys.TwitterClientID),
35+
ClientSecret = Environment.GetEnvironmentVariable(OAuthKeys.TwitterClientSecret),
36+
Scopes = new List<string>
37+
{
38+
"tweet.read",
39+
"tweet.write",
40+
"tweet.moderate.write",
41+
"users.read",
42+
"follows.read",
43+
"follows.write",
44+
"offline.access",
45+
"space.read",
46+
"mute.read",
47+
"mute.write",
48+
"like.read",
49+
"like.write",
50+
"block.read",
51+
"block.write"
52+
},
53+
RedirectUri = twitterCallbackUrl,
54+
}
55+
};
56+
57+
return await auth.BeginAuthorizeAsync("MyState");
58+
}
59+
60+
public async Task<ActionResult> CompleteAsync()
61+
{
62+
var auth = new MvcOAuth2Authorizer
63+
{
64+
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
65+
};
66+
67+
Request.Query.TryGetValue("code", out StringValues code);
68+
Request.Query.TryGetValue("state", out StringValues state);
69+
70+
await auth.CompleteAuthorizeAsync(code, state);
71+
72+
return RedirectToAction("Index", "Home");
73+
}
74+
}
75+
}

Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Controllers/OAuthController.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ namespace LinqToTwitter.MVC.CSharp.Controllers
88
{
99
public class OAuthController : Controller
1010
{
11-
private readonly ILogger<OAuthController> _logger;
11+
private readonly ILogger<OAuthController> logger;
1212

1313
public OAuthController(ILogger<OAuthController> logger)
1414
{
15-
_logger = logger;
15+
this.logger = logger;
1616
}
1717

1818
public ActionResult Index()
@@ -36,7 +36,7 @@ public async Task<ActionResult> BeginAsync()
3636
//var parameters = new Dictionary<string, string> { { "my_custom_param", "val" } };
3737
//string twitterCallbackUrl = Request.GetDisplayUrl().Replace("Begin", "Complete");
3838
//return await auth.BeginAuthorizationAsync(new Uri(twitterCallbackUrl), parameters);
39-
39+
await auth.CredentialStore.ClearAsync();
4040
string twitterCallbackUrl = Request.GetDisplayUrl().Replace("Begin", "Complete");
4141
return await auth.BeginAuthorizationAsync(new Uri(twitterCallbackUrl));
4242
}

Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Controllers/StatusDemosController.cs Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Controllers/TweetDemosController.cs

+44-26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using LinqToTwitter;
2+
using LinqToTwitter.Common;
23
using LinqToTwitter.MVC.CSharp.Models;
34
using Microsoft.AspNetCore.Hosting;
45
using Microsoft.AspNetCore.Mvc;
@@ -10,11 +11,11 @@
1011

1112
namespace MvcDemo.Controllers
1213
{
13-
public class StatusDemosController : Controller
14+
public class TweetDemosController : Controller
1415
{
1516
readonly IWebHostEnvironment webHostEnvironment;
1617

17-
public StatusDemosController(IWebHostEnvironment webHostEnvironment)
18+
public TweetDemosController(IWebHostEnvironment webHostEnvironment)
1819
{
1920
this.webHostEnvironment = webHostEnvironment;
2021
}
@@ -38,14 +39,14 @@ public ActionResult Tweet()
3839
[ActionName("Tweet")]
3940
public async Task<ActionResult> TweetAsync(SendTweetViewModel tweet)
4041
{
41-
var auth = new MvcAuthorizer
42+
var auth = new MvcOAuth2Authorizer
4243
{
43-
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
44+
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
4445
};
4546

4647
var ctx = new TwitterContext(auth);
4748

48-
Status responseTweet = await ctx.TweetAsync(tweet.Text);
49+
Tweet responseTweet = await ctx.TweetAsync(tweet.Text);
4950

5051
var responseTweetVM = new SendTweetViewModel
5152
{
@@ -56,40 +57,57 @@ public async Task<ActionResult> TweetAsync(SendTweetViewModel tweet)
5657
return View(responseTweetVM);
5758
}
5859

59-
[ActionName("HomeTimeline")]
60-
public async Task<ActionResult> HomeTimelineAsync()
60+
[ActionName("TweetTimeline")]
61+
public async Task<ActionResult> TweetTimelineAsync()
6162
{
62-
var auth = new MvcAuthorizer
63+
var auth = new MvcOAuth2Authorizer
6364
{
64-
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
65+
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
6566
};
6667

6768
var ctx = new TwitterContext(auth);
6869

69-
var tweets =
70+
var userQuery =
71+
await
72+
(from usr in ctx.TwitterUser
73+
where usr.Type == UserType.UsernameLookup &&
74+
usr.Usernames == "Linq2Twitr" &&
75+
usr.UserFields == UserField.ProfileImageUrl
76+
select usr)
77+
.SingleOrDefaultAsync();
78+
79+
TwitterUser user = userQuery.Users.FirstOrDefault();
80+
81+
var tweetQuery =
7082
await
71-
(from tweet in ctx.Status
72-
where tweet.Type == StatusType.Home
83+
(from tweet in ctx.Tweets
84+
where tweet.Type == TweetType.TweetsTimeline &&
85+
tweet.ID == user.ID.ToString()
86+
select tweet)
87+
.SingleOrDefaultAsync();
88+
89+
var tweets =
90+
(from tweet in tweetQuery.Tweets
7391
select new TweetViewModel
7492
{
75-
ImageUrl = tweet.User.ProfileImageUrl,
76-
ScreenName = tweet.User.ScreenNameResponse,
77-
Text = tweet.Text
93+
ImageUrl = user.ProfileImageUrl,
94+
ScreenName = user.Name,
95+
Text = tweet.Text
7896
})
79-
.ToListAsync();
97+
.ToList();
8098

8199
return View(tweets);
82100
}
83101

84102
[ActionName("UploadImage")]
85103
public async Task<ActionResult> UploadImageAsync()
86104
{
87-
var auth = new MvcAuthorizer
105+
var auth = new MvcOAuth2Authorizer
88106
{
89-
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
107+
CredentialStore = new OAuth2SessionCredentialStore(HttpContext.Session)
90108
};
91109

92-
var twitterCtx = new TwitterContext(auth);
110+
var ctx = new TwitterContext(auth);
93111

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

108126
await Task.WhenAll(imageUploadTasks);
109127

110-
List<ulong> mediaIds =
128+
List<string> mediaIds =
111129
(from tsk in imageUploadTasks
112-
select tsk.Result.MediaID)
130+
select tsk.Result.MediaID.ToString())
113131
.ToList();
114132

115-
Status tweet = await twitterCtx.TweetAsync(status, mediaIds);
133+
Tweet tweet = await ctx.TweetMediaAsync(status, mediaIds);
116134

117135
return View(
118-
new TweetViewModel
136+
new MediaViewModel
119137
{
120-
ImageUrl = tweet.User.ProfileImageUrl,
121-
ScreenName = tweet.User.ScreenNameResponse,
138+
MediaUrl = tweet.Entities.Urls.FirstOrDefault()?.Url,
139+
Description = tweet.Entities.Urls.FirstOrDefault()?.Description,
122140
Text = tweet.Text
123141
});
124142
}

Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp.csproj

+10-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="LinqToTwitter.AspNet" Version="6.0.1" />
8+
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
9+
</ItemGroup>
10+
11+
<ItemGroup>
12+
<Reference Include="LinqToTwitter">
13+
<HintPath>..\..\..\..\..\src\LinqToTwitter6\LinqToTwitter.AspNet\bin\Debug\net5.0\LinqToTwitter.dll</HintPath>
14+
</Reference>
15+
<Reference Include="LinqToTwitter.AspNet">
16+
<HintPath>..\..\..\..\..\src\LinqToTwitter6\LinqToTwitter.AspNet\bin\Debug\net5.0\LinqToTwitter.AspNet.dll</HintPath>
17+
</Reference>
918
</ItemGroup>
1019

1120
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.ComponentModel;
2+
using System.ComponentModel.DataAnnotations;
3+
4+
namespace LinqToTwitter.MVC.CSharp.Models
5+
{
6+
public class MediaViewModel
7+
{
8+
[DisplayName("Image")]
9+
[DataType(DataType.ImageUrl)]
10+
public string MediaUrl { get; set; }
11+
12+
[DisplayName("Screen Name")]
13+
public string Description { get; set; }
14+
15+
[DisplayName("Tweet")]
16+
public string Text { get; set; }
17+
}
18+
}

Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Properties/launchSettings.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"windowsAuthentication": false,
44
"anonymousAuthentication": true,
55
"iisExpress": {
6-
"applicationUrl": "http://localhost:62333",
6+
"applicationUrl": "http://127.0.0.1:62333",
77
"sslPort": 44395
88
}
99
},
@@ -19,7 +19,7 @@
1919
"commandName": "Project",
2020
"dotnetRunMessages": "true",
2121
"launchBrowser": true,
22-
"applicationUrl": "https://localhost:5001;http://localhost:5000",
22+
"applicationUrl": "https://127.0.0.1:5001;http://127.0.0.1:5000",
2323
"environmentVariables": {
2424
"ASPNETCORE_ENVIRONMENT": "Development"
2525
}

Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Startup.cs

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public void ConfigureServices(IServiceCollection services)
2525

2626
services.AddSession(options =>
2727
{
28-
options.IdleTimeout = TimeSpan.FromSeconds(10);
2928
options.Cookie.HttpOnly = true;
3029
options.Cookie.IsEssential = true;
3130
});
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@{
2-
ViewBag.Title = "Authorizing Application";
2+
ViewBag.Title = "Authorizing Application with OAuth 1.0A";
33
}
44

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

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@{
2+
ViewBag.Title = "Authorizing Application with OAuth 2.0";
3+
}
4+
5+
<h2>Authorize with OAuth 2.0</h2>
6+
@Html.ActionLink("Begin the Authorization Process", "Begin")
7+

Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Views/Shared/_Layout.cshtml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
2323
</li>
2424
<li class="nav-item">
25-
<a class="nav-link text-dark" asp-area="" asp-controller="StatusDemos" asp-action="Index">Status Demos</a>
25+
<a class="nav-link text-dark" asp-area="" asp-controller="TweetDemos" asp-action="Index">Tweet Demos</a>
2626
</li>
2727
<li class="nav-item">
2828
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>

Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Views/StatusDemos/Index.cshtml

-11
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@{
2+
ViewBag.Title = "Tweet Demos";
3+
}
4+
5+
<h2>Tweet Demos</h2>
6+
7+
<p>@Html.ActionLink("Tweet Demo", "Tweet")</p>
8+
9+
<p>@Html.ActionLink("Tweet Timeline Demo", "TweetTimeline")</p>
10+
11+
<p>@Html.ActionLink("Upload Image Demo", "UploadImage")</p>

Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Views/StatusDemos/HomeTimeline.cshtml Samples/LinqToTwitter6/ASP.NET/LinqToTwitter.MVC.CSharp/LinqToTwitter.MVC.CSharp/Views/TweetDemos/TweetTimeline.cshtml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
@model IEnumerable<LinqToTwitter.MVC.CSharp.Models.TweetViewModel>
22

33
@{
4-
ViewBag.Title = "Home Timeline";
4+
ViewBag.Title = "Tweet Timeline";
55
}
66

7-
<h2>Home Timeline Demo</h2>
7+
<h2>Tweet Timeline Demo</h2>
88

99
<table class="table">
1010
<tr>

0 commit comments

Comments
 (0)