diff --git a/Diuna.sln b/Diuna/Diuna.sln similarity index 65% rename from Diuna.sln rename to Diuna/Diuna.sln index c233824..1aa9a20 100644 --- a/Diuna.sln +++ b/Diuna/Diuna.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.4.33110.190 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebAPI", "WebAPI\WebAPI.csproj", "{EB898292-5370-45C7-85B7-FE24D110A8C6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebAPI", "WebAPI\WebAPI.csproj", "{799D68C2-A4C1-43F8-8C35-1126C0AC32D6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EB898292-5370-45C7-85B7-FE24D110A8C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EB898292-5370-45C7-85B7-FE24D110A8C6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EB898292-5370-45C7-85B7-FE24D110A8C6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EB898292-5370-45C7-85B7-FE24D110A8C6}.Release|Any CPU.Build.0 = Release|Any CPU + {799D68C2-A4C1-43F8-8C35-1126C0AC32D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {799D68C2-A4C1-43F8-8C35-1126C0AC32D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {799D68C2-A4C1-43F8-8C35-1126C0AC32D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {799D68C2-A4C1-43F8-8C35-1126C0AC32D6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {C1F5C21F-B331-4C5D-BDFF-3FAC8116996F} + SolutionGuid = {2CFA03A7-56D9-4ADE-9B6A-1A3383A1C104} EndGlobalSection EndGlobal diff --git a/Diuna/WebAPI/AppDbContext.cs b/Diuna/WebAPI/AppDbContext.cs new file mode 100644 index 0000000..3c297c6 --- /dev/null +++ b/Diuna/WebAPI/AppDbContext.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using WebAPI.Models; + +namespace WebAPI +{ + public class AppDbContext : DbContext + { + public DbSet Users { get; set; } + + public AppDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + } + + public static readonly Microsoft.Extensions.Logging.LoggerFactory _myLoggerFactory = + new LoggerFactory(new[] { + new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() + }); + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseLoggerFactory(_myLoggerFactory); + } + } +} diff --git a/Diuna/WebAPI/Controllers/AuthController.cs b/Diuna/WebAPI/Controllers/AuthController.cs new file mode 100644 index 0000000..6f80498 --- /dev/null +++ b/Diuna/WebAPI/Controllers/AuthController.cs @@ -0,0 +1,72 @@ +using Google.Apis.Auth; +using Google.Apis.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Identity.Client.Platforms.Features.DesktopOs.Kerberos; +using Microsoft.IdentityModel.Tokens; +using System.Configuration; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using WebAPI.Models; + +namespace WebAPI.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class AuthController : Controller + { + private readonly AppDbContext db; + private readonly IConfiguration configuration; + public AuthController( + AppDbContext _db, IConfiguration _configuration) + { db = _db; configuration = _configuration; } + + [HttpPost] + [Route("apiToken")] + public async Task apiToken([FromBody] string credential) + { + var settings = new GoogleJsonWebSignature.ValidationSettings() + { + Audience = new List { configuration.GetValue("GoogleClientId") } + }; + var payload = await GoogleJsonWebSignature.ValidateAsync(credential, settings); + var user = db.Users.Where(x => x.Email == payload.Email).FirstOrDefault(); + if (user != null) + { + return Ok(JWTGenerator(user)); + } + else + { + return BadRequest(); + } + } + + private dynamic JWTGenerator(User user) + { + var tokenHandler = new JwtSecurityTokenHandler(); + var key = Encoding.ASCII.GetBytes(configuration.GetValue("Secret")); + + var tokenDescriptor = new SecurityTokenDescriptor + { + Subject = new ClaimsIdentity(new[] { new Claim("username", user.UserName) }), + Expires = DateTime.UtcNow.AddDays(7), + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature) + }; + var token = tokenHandler.CreateToken(tokenDescriptor); + var encrypterToken = tokenHandler.WriteToken(token); + + HttpContext.Response.Cookies.Append("token", encrypterToken, + new CookieOptions + { + Expires = DateTime.Now.AddDays(7), + HttpOnly = true, + Secure = true, + IsEssential = true, + SameSite = SameSiteMode.None + }); + + return new { token = encrypterToken, username = user.UserName }; + } + } +} \ No newline at end of file diff --git a/Diuna/WebAPI/Controllers/PingController.cs b/Diuna/WebAPI/Controllers/PingController.cs new file mode 100644 index 0000000..fdde72f --- /dev/null +++ b/Diuna/WebAPI/Controllers/PingController.cs @@ -0,0 +1,28 @@ +using Google.Apis.Auth; +using Google.Apis.Http; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Identity.Client.Platforms.Features.DesktopOs.Kerberos; +using Microsoft.IdentityModel.Tokens; +using System.Configuration; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using WebAPI.Models; + +namespace WebAPI.Controllers +{ + [ApiController] + [Route("api/[controller]")] + [Authorize] + public class PingController : Controller + { + [HttpGet] + [Route("Ping")] + public IActionResult Ping() + { + return Ok(new { data = "Pong" }); + } + } +} \ No newline at end of file diff --git a/Diuna/WebAPI/Migrations/20221205190148_Initial.Designer.cs b/Diuna/WebAPI/Migrations/20221205190148_Initial.Designer.cs new file mode 100644 index 0000000..db783cc --- /dev/null +++ b/Diuna/WebAPI/Migrations/20221205190148_Initial.Designer.cs @@ -0,0 +1,51 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using WebAPI; + +#nullable disable + +namespace WebAPI.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20221205190148_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("WebAPI.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Diuna/WebAPI/Migrations/20221205190148_Initial.cs b/Diuna/WebAPI/Migrations/20221205190148_Initial.cs new file mode 100644 index 0000000..ddde03d --- /dev/null +++ b/Diuna/WebAPI/Migrations/20221205190148_Initial.cs @@ -0,0 +1,36 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace WebAPI.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Email = table.Column(type: "nvarchar(max)", nullable: true), + UserName = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: true), + CreatedAt = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/Diuna/WebAPI/Migrations/AppDbContextModelSnapshot.cs b/Diuna/WebAPI/Migrations/AppDbContextModelSnapshot.cs new file mode 100644 index 0000000..c06ff91 --- /dev/null +++ b/Diuna/WebAPI/Migrations/AppDbContextModelSnapshot.cs @@ -0,0 +1,48 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using WebAPI; + +#nullable disable + +namespace WebAPI.Migrations +{ + [DbContext(typeof(AppDbContext))] + partial class AppDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("WebAPI.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Diuna/WebAPI/Models/User.cs b/Diuna/WebAPI/Models/User.cs new file mode 100644 index 0000000..dfc773c --- /dev/null +++ b/Diuna/WebAPI/Models/User.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; + +namespace WebAPI.Models +{ + public class User + { + #region Properties + [Key] + public Guid Id { get; set; } + public string? Email { get; set; } + [StringLength(50)] + public string? UserName { get; set; } + public DateTime CreatedAt { get; set; } + #endregion + } +} diff --git a/Diuna/WebAPI/Program.cs b/Diuna/WebAPI/Program.cs new file mode 100644 index 0000000..523f4a5 --- /dev/null +++ b/Diuna/WebAPI/Program.cs @@ -0,0 +1,81 @@ +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using System.Text; +using WebAPI; + +var builder = WebApplication.CreateBuilder(args); + +var connectionString = builder.Configuration.GetConnectionString("SQLDatabase"); +builder.Services.AddDbContext(x => x.UseSqlServer(connectionString)); + +builder.Services.AddCors(options => +{ + options.AddPolicy("CORSPolicy", builder => + { + builder.WithOrigins("http://localhost:4200") + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials(); + + builder.WithOrigins("https://diuna.bim-it.pl") + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials(); + }); +}); + +builder.Services.AddAuthentication(x => +{ + x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}).AddCookie(x => +{ + x.Cookie.Name = "token"; + +}).AddJwtBearer(x => +{ + x.RequireHttpsMetadata = false; + x.SaveToken = true; + x.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetValue("Secret"))), + ValidateIssuer = false, + ValidateAudience = false + }; + x.Events = new JwtBearerEvents + { + OnMessageReceived = context => + { + //context.Token = context.Request.Cookies["token"]; + context.Token = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Ik1pY2hhbCBaaWVsaW5za2kiLCJuYmYiOjE2NzAyODk3NTAsImV4cCI6MTY3MDg5NDU1MCwiaWF0IjoxNjcwMjg5NzUwfQ.XZ1lE_Jio9N5aetvY8qX8rS2xoIcPw3GJWGSatPh1VokQkrILOowvvibdGViQOOi39qGBOFKa8JC61XcaL-1qw"; + return Task.CompletedTask; + } + }; + +}); + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +// app.UseHttpsRedirection(); +app.UseCors("CORSPolicy"); + +app.UseAuthorization(); +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/WebAPI/Properties/launchSettings.json b/Diuna/WebAPI/Properties/launchSettings.json similarity index 73% rename from WebAPI/Properties/launchSettings.json rename to Diuna/WebAPI/Properties/launchSettings.json index 612c11f..fee1250 100644 --- a/WebAPI/Properties/launchSettings.json +++ b/Diuna/WebAPI/Properties/launchSettings.json @@ -4,8 +4,8 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:1860", - "sslPort": 44315 + "applicationUrl": "http://localhost:12241", + "sslPort": 44358 } }, "profiles": { @@ -13,8 +13,8 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "launchUrl": "weatherforecast", - "applicationUrl": "https://localhost:7170;http://localhost:5008", + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7009;http://localhost:5183", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -22,7 +22,7 @@ "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, - "launchUrl": "weatherforecast", + "launchUrl": "swagger", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/Diuna/WebAPI/WebAPI.csproj b/Diuna/WebAPI/WebAPI.csproj new file mode 100644 index 0000000..d644760 --- /dev/null +++ b/Diuna/WebAPI/WebAPI.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + enable + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + diff --git a/WebAPI/appsettings.Development.json b/Diuna/WebAPI/appsettings.Development.json similarity index 100% rename from WebAPI/appsettings.Development.json rename to Diuna/WebAPI/appsettings.Development.json diff --git a/Diuna/WebAPI/appsettings.json b/Diuna/WebAPI/appsettings.json new file mode 100644 index 0000000..25cec86 --- /dev/null +++ b/Diuna/WebAPI/appsettings.json @@ -0,0 +1,14 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "SQLDatabase": "Server=tcp:localhost,1433;Initial Catalog=diuna;Persist Security Info=False;User ID=SA;Password=v](8Lc|RfG;MultipleActiveResultSets=False;Encrypt=False;TrustServerCertificate=False;Connection Timeout=30;" + }, + "GoogleCLientId": "107631825312-bkfe438ehr9k9ecb2h76g802tj6advma.apps.googleusercontent.com", + "Secret": "8393AF8EAEF8478CB738D44858690F9C7E2D19F65896DD9FBAA3EB2A6F493E80" +} diff --git a/Frontend/src/app/app.module.ts b/Frontend/src/app/app.module.ts index 85d6acc..83d810d 100644 --- a/Frontend/src/app/app.module.ts +++ b/Frontend/src/app/app.module.ts @@ -7,6 +7,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MainViewComponent } from './main-view/main-view.component'; import { MaterialModule } from './material.module'; import { LoginPageComponent } from './components/login-page/login-page.component'; +import { HttpClientModule } from '@angular/common/http'; @NgModule({ @@ -20,6 +21,7 @@ import { LoginPageComponent } from './components/login-page/login-page.component AppRoutingModule, BrowserAnimationsModule, MaterialModule, + HttpClientModule ], providers: [], bootstrap: [AppComponent] diff --git a/Frontend/src/app/auth/auth.service.ts b/Frontend/src/app/auth/auth.service.ts index 6c3724a..6379cd2 100644 --- a/Frontend/src/app/auth/auth.service.ts +++ b/Frontend/src/app/auth/auth.service.ts @@ -1,9 +1,60 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { environment } from 'src/environments/environment'; +import { User } from '../models/user'; @Injectable({ providedIn: 'root' }) -export class AuthServiceService { +export class AuthService { - constructor() { } + apiToken: string | null = null; + user: User | null = null; + + constructor( + private http$: HttpClient + ) { } + + loadDbUser() { + return new Promise((resolve, reject) => { + const headers = new HttpHeaders({ + // 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiToken}` + }) + this.http$.get(`${environment.api.url}/ping/ping`, { + headers, + withCredentials: true + }).subscribe({ + next: (data) => { + console.log('Ping', data); + resolve(data); + }, + error: (e) => { + console.error('Ping error', e); + reject(e); + } + } + ); + }); + } + + getAPIToken(credentials: string): Promise { + return new Promise((resolve, reject) => { + const header = new HttpHeaders().set('Content-type', 'application/json'); + this.http$.post(`${environment.api.url}/auth/apiToken`, JSON.stringify(credentials), { headers: header }).subscribe({ + next: (data) => { + console.log('apiToken', data); + this.apiToken = data.token; + resolve(data); + }, + error: (e) => { + console.error('apiToken error', e); + reject(e); + } + } + ); + }); + //const header = new HttpHeaders().set('Content-type', 'application/json'); + //return this.httpClient.post(this.path + "LoginWithGoogle", JSON.stringify(credentials), { headers: header }); + } } diff --git a/Frontend/src/app/components/login-page/login-page.component.ts b/Frontend/src/app/components/login-page/login-page.component.ts index bd1b341..caba2d7 100644 --- a/Frontend/src/app/components/login-page/login-page.component.ts +++ b/Frontend/src/app/components/login-page/login-page.component.ts @@ -1,8 +1,10 @@ import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import jwt_decode from "jwt-decode"; +import { AuthService } from 'src/app/auth/auth.service'; import { User } from 'src/app/models/user'; import { DataService } from 'src/app/services/data.service'; +import { environment } from 'src/environments/environment'; @Component({ selector: 'app-login-page', @@ -13,38 +15,46 @@ import { DataService } from 'src/app/services/data.service'; export class LoginPageComponent implements OnInit { constructor( private data$: DataService, - private router$: Router + private router$: Router, + private auth$: AuthService ) {} ngOnInit(): void { - // @ts-ignore - google.accounts.id.initialize({ - client_id: "107631825312-bkfe438ehr9k9ecb2h76g802tj6advma.apps.googleusercontent.com", - callback: this.handleCredentialResponse.bind(this), - auto_select: true, - cancel_on_tap_outside: true, - }); - // @ts-ignore - google.accounts.id.renderButton( // @ts-ignore - document.getElementById("google-button"), - { theme: "outline", size: "large", width: "100%" } - ); - // @ts-ignore - google.accounts.id.prompt(); + window.onGoogleLibraryLoad = () => { + // @ts-ignore + google.accounts.id.initialize({ + client_id: environment.google.clientId, + callback: this.handleCredentialResponse.bind(this), + auto_select: true, + cancel_on_tap_outside: true + }); + // @ts-ignore + google.accounts.id.renderButton( + // @ts-ignore + document.getElementById("google-button"), + { theme: "outline", size: "large", width: "100%" } + ); + // @ts-ignore + google.accounts.id.prompt((notification: PromptMomentNotification) => {}); + }; } async handleCredentialResponse(response: any) { try { + console.log("Google Response", response); const responsePayload: any = jwt_decode(response.credential); this.data$.currentUser = new User({ - id: 1, - googledId: responsePayload.aud, + googleCredentials: response.credential, userName: `${responsePayload.given_name} ${responsePayload.family_name}`, email: responsePayload.email, avatar: responsePayload.picture }); + // this.auth$.loadDbUser(); this.router$.navigate(['/app']); + console.log("USer", this.data$.currentUser); + await this.auth$.getAPIToken(response.credential); + this.auth$.loadDbUser(); } catch (e) { console.error('Get user error', e); } diff --git a/Frontend/src/app/models/user.ts b/Frontend/src/app/models/user.ts index 2f2ce5f..05154b6 100644 --- a/Frontend/src/app/models/user.ts +++ b/Frontend/src/app/models/user.ts @@ -2,8 +2,8 @@ export class User { id!: string; email!: string; userName!: string; - googleId!: string; - avatar?: string | ArrayBuffer; + googleCredentials!: string; + avatar?: string; constructor(input: any) { Object.assign(this, input) } diff --git a/Frontend/src/environments/environment.ts b/Frontend/src/environments/environment.ts index f56ff47..91eaee1 100644 --- a/Frontend/src/environments/environment.ts +++ b/Frontend/src/environments/environment.ts @@ -3,7 +3,13 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, + api: { + url: "http://localhost:5183/api" + }, + google: { + clientId: "107631825312-bkfe438ehr9k9ecb2h76g802tj6advma.apps.googleusercontent.com" + } }; /* diff --git a/WebAPI/Controllers/WeatherForecastController.cs b/WebAPI/Controllers/WeatherForecastController.cs deleted file mode 100644 index 09f1727..0000000 --- a/WebAPI/Controllers/WeatherForecastController.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WebAPI.Controllers -{ - [ApiController] - [Route("[controller]")] - public class WeatherForecastController : ControllerBase - { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" - }; - - private readonly ILogger _logger; - - public WeatherForecastController(ILogger logger) - { - _logger = logger; - } - - [HttpGet] - public IEnumerable Get() - { - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateTime.Now.AddDays(index), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = Summaries[Random.Shared.Next(Summaries.Length)] - }) - .ToArray(); - } - } -} \ No newline at end of file diff --git a/WebAPI/Program.cs b/WebAPI/Program.cs deleted file mode 100644 index ac7c10a..0000000 --- a/WebAPI/Program.cs +++ /dev/null @@ -1,17 +0,0 @@ -var builder = WebApplication.CreateBuilder(args); - -// Add services to the container. - -builder.Services.AddControllers(); - -var app = builder.Build(); - -// Configure the HTTP request pipeline. - -app.UseHttpsRedirection(); - -app.UseAuthorization(); - -app.MapControllers(); - -app.Run(); diff --git a/WebAPI/WeatherForecast.cs b/WebAPI/WeatherForecast.cs deleted file mode 100644 index f154876..0000000 --- a/WebAPI/WeatherForecast.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace WebAPI -{ - public class WeatherForecast - { - public DateTime Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - - public string? Summary { get; set; } - } -} \ No newline at end of file diff --git a/WebAPI/WebAPI.csproj b/WebAPI/WebAPI.csproj deleted file mode 100644 index c78c9c7..0000000 --- a/WebAPI/WebAPI.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net6.0 - enable - enable - - - diff --git a/WebAPI/appsettings.json b/WebAPI/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/WebAPI/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -}