// This method gets called by the runtime. Use this method to configure the HTTP request pipeline public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { // Add cookie middleware app.UseCookieAuthentication(new CookieAuthenticationOptions { AutomaticAuthenticate = true, AutomaticChallenge = true, LoginPath = new PathString("/login"), LogoutPath = new PathString("/logout") }); // Add the OAuth2 middleware app.UseOAuthAuthentication(new OAuthOptions { AuthenticationScheme = "Coinbase", ClientId = Configuration["coinbase:clientId"], ClientSecret = Configuration["coinbase:clientSecret"], CallbackPath = new PathString("/signin-coinbase"), AuthorizationEndpoint = "https://www.coinbase.com/oauth/authorize", TokenEndpoint = "https://api.coinbase.com/oauth/token", // the URL accessed used after user authenticated, used to store user object UserInformationEndpoint = "https://api.coinbase.com/v2/user", // in the example, this was written like: "https://sandbox.coinbase.com/v2/user/(id,name,username)" to store fields as "claims" // SCOPE // additional scopes needed for live money send { "meta[send_limit_amount]=1", "eta[send_limit_currency]=USD", "meta[send_limit_period]=day" } // Scope = { "user", "addresses", "balance", "contacts", "recurring_payments", "transactions", "wallet:accounts:read", "wallet:transactions:read", "wallet:transactions:send:bypass-2fa", "wallet:transactions:send", "meta[send_limit_amount]=10", "eta[send_limit_currency]=USD", "meta[send_limit_period]=day" }, Scope = { "wallet:accounts:read", "wallet:transactions:read", "wallet:transactions:send" }, // Scope = { "wallet:accounts:read", "wallet:transactions:read" }, Events = new OAuthEvents { // The OnCreatingTicket event is called after the user has been authenticated and the OAuth middleware has // created an auth ticket. We need to manually call the UserInformationEndpoint to retrieve the user's information, // parse the resulting JSON to extract the relevant information, and add the correct claims. OnCreatingTicket = async context => { // Retrieve user info from Coinbase after successful authentication var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); request.Headers.Add("x-li-format", "json"); // Tell Coinbase we want the result in JSON, otherwise it will return XML var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted); response.EnsureSuccessStatusCode(); // Extract the user info object var user = JObject.Parse(await response.Content.ReadAsStringAsync()); // testing JObject/JToken variations string fullName = (string)user["data"]["name"]; string gravatar = (string)user["data"]["avatar_url"]; JToken tData = user["data"]; var fullData = user["data"]; string userId = (string)user["data"]["id"]; // var userId = user["data"]["id"].ToObject(); // import database context var optionsBuilder = new DbContextOptionsBuilder <BCAPContext>(); optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=BCAPDB;Trusted_Connection=True;"); BCAPContext BCAP = new BCAPContext(optionsBuilder.Options); // Query the singular entry in current customer table var currentUser = BCAP.CurrentCustomer.FirstOrDefault(); // add user object into currentUser table if not present, else if present, updates to currently pulled user info if (currentUser == null) { BCAP.CurrentCustomer.Add(new CurrentCustomer { CustomerId = userId, FullName = fullName, ProfilePicUrl = gravatar, Data = fullData.ToString(), AccessToken = context.AccessToken }); } else { // update currentUser from database BCAP.CurrentCustomer.Remove(currentUser); BCAP.SaveChanges(); BCAP.CurrentCustomer.Add(new CurrentCustomer { CustomerId = userId, FullName = fullName, ProfilePicUrl = gravatar, Data = fullData.ToString(), AccessToken = context.AccessToken }); } BCAP.SaveChanges(); // Add the Name Identifier claim if (!string.IsNullOrEmpty(userId)) { context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId, ClaimValueTypes.String, context.Options.ClaimsIssuer)); } // Add the Name claim var formattedName = user["data"]["name"].ToString(); // var formattedName = user.Value<string>("formattedName"); if (!string.IsNullOrEmpty(formattedName)) { context.Identity.AddClaim(new Claim(ClaimTypes.Name, formattedName, ClaimValueTypes.String, context.Options.ClaimsIssuer)); } context.Identity.AddClaim(new Claim("urn:token:coinbase", context.AccessToken)); }, OnRedirectToAuthorizationEndpoint = context => { // metaTags required by coinbase (in tandem with Scope parameter) to allow transactions var metaTags = "&meta%5Bsend_limit_amount%5D=1&meta%5Bsend_limit_currency%5D=USD&meta%5Bsend_limit_period%5D=day"; var newUri = context.RedirectUri + metaTags; context.Response.Redirect(newUri); return(Task.FromResult(0)); } } }); // Listen for requests on the /login path, and issue a challenge to log in with Coinbase middleware app.Map("/login", builder => { builder.Run(async context => { // Return a challenge to invoke the Coinbase authentication scheme // await context.Authentication.ChallengeAsync("Coinbase", properties: new AuthenticationProperties() { RedirectUri = "/" }); await context.Authentication.ChallengeAsync("Coinbase", properties: new AuthenticationProperties() { RedirectUri = "http://*****:*****@"Server=(localdb)\mssqllocaldb;Database=BCAPDB;Trusted_Connection=True;"); BCAPContext BCAP = new BCAPContext(optionsBuilder.Options); // define and clear current customer var currentUser = BCAP.CurrentCustomer.FirstOrDefault(); BCAP.CurrentCustomer.Remove(currentUser); BCAP.SaveChanges(); // Sign the user out of the authentication middleware (i.e. it will clear the Auth cookie) await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); // Redirect the user to the home page after signing out // context.Response.Redirect("/"); context.Response.Redirect("http://localhost:8080/#/register"); }); }); loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseApplicationInsightsRequestTelemetry(); app.UseApplicationInsightsExceptionTelemetry(); app.UseMvc(); }
public CustomerController(BCAPContext context) { _context = context; }