Skip to content

Commit 394ad22

Browse files
authored
Feature/04 grpc (#14)
* Initial implementation ok for GRPC * Added GRPC.
1 parent 75c6ef7 commit 394ad22

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+619
-172
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,6 @@ dist
112112
/server/WebApplication2/.vs/WebApplication2/v16
113113
/server/WebApplication2/WebApplication2/.config
114114
server/Server/.vs/Server/DesignTimeBuild/.dtbcache.v2
115+
116+
bin/
117+
obj/

client/src/components/Posts.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,13 @@ export const Posts = () => {
356356
let dispatch = useDispatch();
357357

358358
const posts = useSelector(state => {
359-
return state.posts.postList;
359+
return state.postContext.postList;
360360
});
361361

362+
const postContext = useSelector(state => {
363+
return state.postContext;
364+
})
365+
362366
let fetchData = () => {
363367
dispatch({ type: "FETCH_POSTS" });
364368
dispatch({ type: "CLEAR_SELECTION" });
@@ -368,6 +372,12 @@ export const Posts = () => {
368372
fetchData();
369373
}, []);
370374

375+
// useEffect(() => {
376+
// if (postContext.shouldReload || posts.length === 0) {
377+
// fetchData();
378+
// }
379+
// }, [postContext.shouldReload]);
380+
371381
return (
372382
<div className="container">
373383
<div id="blog" className="row">

client/src/reducers/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import PermissionReducer from "./permissionReducer";
77
import UsersReducer from "./usersReducer";
88

99
const rootReducer = combineReducers({
10-
posts: PostsReducer,
10+
postContext: PostsReducer,
1111
userContext: UserReducer,
1212
usersContext: UsersReducer,
1313
resourceContext: ResourceReducer,

client/src/reducers/postsReducer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ const initialState = {
22
postList: [],
33
selectedPost: {},
44
selectedComments: [],
5-
notificationText: ''
5+
notificationText: '',
6+
shouldReload: false
67
};
78

89
export default (state = initialState, action) => {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net5.0</TargetFramework>
5+
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
6+
<DockerfileContext>..\Server</DockerfileContext>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="Grpc.AspNetCore" Version="2.33.1" />
15+
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.0" />
16+
<PackageReference Include="StackExchange.Redis" Version="2.2.3" />
17+
</ItemGroup>
18+
19+
<ItemGroup>
20+
<ProjectReference Include="..\RedisLibrary\AuthLibrary.csproj" />
21+
</ItemGroup>
22+
23+
</Project>

server/AuthGrpcService/Program.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Microsoft.AspNetCore.Hosting;
2+
using Microsoft.Extensions.Hosting;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Linq;
7+
using System.Threading.Tasks;
8+
9+
namespace AuthGrpcService
10+
{
11+
public class Program
12+
{
13+
public static void Main(string[] args)
14+
{
15+
CreateHostBuilder(args).Build().Run();
16+
}
17+
18+
// Additional configuration is required to successfully run gRPC on macOS.
19+
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
20+
public static IHostBuilder CreateHostBuilder(string[] args) =>
21+
Host.CreateDefaultBuilder(args)
22+
.ConfigureWebHostDefaults(webBuilder =>
23+
{
24+
webBuilder.UseStartup<Startup>();
25+
});
26+
}
27+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"profiles": {
3+
"AuthGrpcService": {
4+
"commandName": "Project",
5+
"environmentVariables": {
6+
"ASPNETCORE_ENVIRONMENT": "Development"
7+
},
8+
"dotnetRunMessages": "true",
9+
"applicationUrl": "http://localhost:5004;https://localhost:5005"
10+
}
11+
}
12+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
syntax = "proto3";
2+
3+
option csharp_namespace = "AuthGrpcService";
4+
5+
package greet;
6+
7+
// The greeting service definition.
8+
service Greeter {
9+
// Sends a greeting
10+
rpc SayHello (HelloRequest) returns (HelloReply);
11+
}
12+
13+
// The request message containing the user's name.
14+
message HelloRequest {
15+
string name = 1;
16+
}
17+
18+
// The response message containing the greetings.
19+
message HelloReply {
20+
string message = 1;
21+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using Grpc.Core;
2+
using Microsoft.Extensions.Logging;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Security.Claims;
7+
using System.Threading.Tasks;
8+
using AuthLibrary.Services;
9+
using Microsoft.AspNetCore.Authorization;
10+
using Newtonsoft.Json;
11+
using Newtonsoft.Json.Linq;
12+
13+
namespace AuthGrpcService
14+
{
15+
[Authorize]
16+
public class GreeterService : Greeter.GreeterBase
17+
{
18+
private readonly ILogger<GreeterService> _logger;
19+
private readonly RedisService redisService;
20+
21+
public GreeterService(ILogger<GreeterService> logger, RedisService redisService)
22+
{
23+
this.redisService = redisService;
24+
_logger = logger;
25+
}
26+
27+
public override async Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
28+
{
29+
var user = context.GetHttpContext().User;
30+
var userName = user.Identity.Name;
31+
var claimsIdentity = user.Identities.First() as ClaimsIdentity;
32+
var claim = claimsIdentity.Claims.First(x => x.Type == "jti");
33+
var jti = claim.Value;
34+
string msg = "";
35+
var inValid = string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(jti) || string.IsNullOrWhiteSpace(request.Name);
36+
if (inValid)
37+
{
38+
return new HelloReply
39+
{
40+
Message = "Unauthorized"
41+
};
42+
}
43+
44+
var redisValue = await redisService.Get(userName);
45+
if (string.IsNullOrWhiteSpace(redisValue))
46+
{
47+
return new HelloReply
48+
{
49+
Message = "Unauthorized"
50+
};
51+
}
52+
53+
var dbValue = (dynamic)JsonConvert.DeserializeObject(redisValue);
54+
var jtiArray = ((dbValue as dynamic).jtis as dynamic) as JArray;
55+
var list = jtiArray.ToObject<List<string>>();
56+
var validJti = list.Exists(x => x == jti);
57+
58+
if (!validJti)
59+
{
60+
return new HelloReply
61+
{
62+
Message = "Unauthorized"
63+
};
64+
}
65+
66+
var permissionViewModels = JsonConvert.DeserializeObject<List<dynamic>>(
67+
((dbValue as dynamic).resources as JValue).ToString());
68+
var permitted = permissionViewModels.Exists(x => x.Name == request.Name && Convert.ToBoolean(x.IsAllowed));
69+
70+
if (!permitted)
71+
{
72+
return new HelloReply
73+
{
74+
Message = "Forbid"
75+
};
76+
}
77+
78+
return new HelloReply
79+
{
80+
Message = string.Empty
81+
};
82+
}
83+
}
84+
}

server/AuthGrpcService/Startup.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using Microsoft.AspNetCore.Builder;
2+
using Microsoft.AspNetCore.Hosting;
3+
using Microsoft.AspNetCore.Http;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Hosting;
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
using AuthLibrary.Services;
12+
using Microsoft.IdentityModel.Tokens;
13+
14+
namespace AuthGrpcService
15+
{
16+
public class Startup
17+
{
18+
const string BizBook365Com = "bizbook365.com";
19+
private const string SecretKey = "a55ae165-912d-4052-b61e-aeeb6d6d2c07";
20+
private readonly SymmetricSecurityKey SigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey));
21+
22+
// This method gets called by the runtime. Use this method to add services to the container.
23+
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
24+
public void ConfigureServices(IServiceCollection services)
25+
{
26+
services.AddSingleton<RedisService>();
27+
services.AddGrpc();
28+
services.AddAuthorization();
29+
services.AddTokenValidation(BizBook365Com, BizBook365Com, SigningKey);
30+
}
31+
32+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
33+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, RedisService redisService)
34+
{
35+
if (env.IsDevelopment())
36+
{
37+
app.UseDeveloperExceptionPage();
38+
}
39+
40+
app.UseRouting();
41+
42+
app.UseAuthentication();
43+
app.UseAuthorization();
44+
45+
redisService.Connect();
46+
47+
app.UseEndpoints(endpoints =>
48+
{
49+
endpoints.MapGrpcService<GreeterService>();
50+
51+
endpoints.MapGet("/", async context =>
52+
{
53+
await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
54+
});
55+
});
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)