diff --git a/.docker/docker-compose.yaml b/.docker/docker-compose.yaml index 5e6599f..73c579b 100644 --- a/.docker/docker-compose.yaml +++ b/.docker/docker-compose.yaml @@ -7,8 +7,13 @@ services: CONNECTIONSTRINGS__INTERNSHIPDATABASE: "Host=db.postgres;Port=5432;Database=postgres;Username=postgres;Password=szwoniu" ASPNETCORE_ENVIRONMENT: Development ASPNETCORE_URLS: http://+:80 - SECURITYOPTIONS__SECRET: PDv7DrqznYL6nv7DrqzjnQYO9JxIsWdcjnQYL6nu0f + SECURITYOPTIONS__SECRET: iewaiwie3aig9wi3chieBai9eephai SECURITYOPTIONS__EXPIRATION: 20 + SECURITYOPTIONS__BASEURL: https://logowanie.pg.edu.pl + SECURITYOPTIONS__TOKENPATH: /oauth2.0/accessToken + SECURITYOPTIONS__PROFILEPATH: /oauth2.0/profile + SECURITYOPTIONS__CLIENTID: PraktykiClientId + SECURITYOPTIONS__REDIRECTURL: https://system-praktyk.stg.kadet.net/user/login/check/pg depends_on: - db.postgres ports: diff --git a/src/AspNet.Security.OAuth.MyGut/AspNet.Security.OAuth.MyGut.csproj b/src/AspNet.Security.OAuth.MyGut/AspNet.Security.OAuth.MyGut.csproj deleted file mode 100644 index e5cfdb1..0000000 --- a/src/AspNet.Security.OAuth.MyGut/AspNet.Security.OAuth.MyGut.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - netcoreapp3.1 - - - - - - - diff --git a/src/AspNet.Security.OAuth.MyGut/AuthenticationBuilderExtension.cs b/src/AspNet.Security.OAuth.MyGut/AuthenticationBuilderExtension.cs deleted file mode 100644 index b442239..0000000 --- a/src/AspNet.Security.OAuth.MyGut/AuthenticationBuilderExtension.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Microsoft.AspNetCore.Authentication; -using Microsoft.Extensions.DependencyInjection; - -namespace AspNet.Security.OAuth.MyGut -{ - public static class AuthenticationBuilderExtension - { - public static AuthenticationBuilder AddMyGut(this AuthenticationBuilder builder) => - builder.AddMyGut(MyGutAuthenticationDefaults.AuthenticationScheme, MyGutAuthenticationDefaults.DisplayName, options => { }); - - public static AuthenticationBuilder AddMyGut( - this AuthenticationBuilder builder, - string scheme, - string caption, - Action configuration - ) => - builder.AddOAuth(scheme, caption, configuration); - } -} \ No newline at end of file diff --git a/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationConstants.cs b/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationConstants.cs deleted file mode 100644 index 7edb2e5..0000000 --- a/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationConstants.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace AspNet.Security.OAuth.MyGut -{ - public static class MyGutAuthenticationConstants - { - public static class Urls - { - } - - public static class Claims - { - public const string AlbumNumber = "urn:mygut:albumnumber"; - } - - public static class UrlQueryParameterValues - { - public const string Consent = "consent"; - public const string None = "none"; - } - } -} \ No newline at end of file diff --git a/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationDefaults.cs b/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationDefaults.cs deleted file mode 100644 index 5e07b0d..0000000 --- a/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationDefaults.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace AspNet.Security.OAuth.MyGut -{ - public static class MyGutAuthenticationDefaults - { - public const string AuthenticationScheme = "MyGut"; - - public const string DisplayName = "MyGut"; - - public const string Issuer = "MyGut"; - - public const string CallbackPath = "/signin-mygut"; - - public const string AuthorizationEndpoint = "https://logowanie.pg.edu.pl/login"; - - public const string TokenEndpoint = "https://logowanie.pg.edu.pl/login"; - - public const string UserInformationEndpoint = "https://logowanie.pg.edu.pl/login"; - } -} \ No newline at end of file diff --git a/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationHandler.cs b/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationHandler.cs deleted file mode 100644 index 6782093..0000000 --- a/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationHandler.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Encodings.Web; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.OAuth; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace AspNet.Security.OAuth.MyGut -{ - public class MyGutAuthenticationHandler : OAuthHandler - { - public MyGutAuthenticationHandler( - IOptionsMonitor options, - ILoggerFactory logger, - UrlEncoder encoder, - ISystemClock clock) : base(options, logger, encoder, clock) - { - } - } -} \ No newline at end of file diff --git a/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationOptions.cs b/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationOptions.cs deleted file mode 100644 index c3f027d..0000000 --- a/src/AspNet.Security.OAuth.MyGut/MyGutAuthenticationOptions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.AspNetCore.Authentication.OAuth; - -namespace AspNet.Security.OAuth.MyGut -{ - public class MyGutAuthenticationOptions : OAuthOptions - { - public MyGutAuthenticationOptions() - { - ClaimsIssuer = MyGutAuthenticationDefaults.Issuer; - CallbackPath = MyGutAuthenticationDefaults.CallbackPath; - AuthorizationEndpoint = MyGutAuthenticationDefaults.AuthorizationEndpoint; - TokenEndpoint = MyGutAuthenticationDefaults.TokenEndpoint; - UserInformationEndpoint = MyGutAuthenticationDefaults.UserInformationEndpoint; - } - } -} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/AccessController.cs b/src/InternshipSystem.Api/Controllers/AccessController.cs index ea15e8f..69164e3 100644 --- a/src/InternshipSystem.Api/Controllers/AccessController.cs +++ b/src/InternshipSystem.Api/Controllers/AccessController.cs @@ -1,15 +1,18 @@ using System; +using System.IO; using System.Linq; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; using InternshipSystem.Api.Options; using InternshipSystem.Api.Security; +using InternshipSystem.Core; using InternshipSystem.Repository; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; +using Serilog; namespace InternshipSystem.Api.Controllers { @@ -19,12 +22,18 @@ namespace InternshipSystem.Api.Controllers { private readonly InternshipDbContext _context; private readonly JwtTokenService _tokenService; + private readonly GutCasClient _loginClient; private readonly SecurityOptions _securityOptions; - public AccessController(IOptions options, InternshipDbContext context, JwtTokenService tokenService) + public AccessController( + IOptions options, + InternshipDbContext context, + JwtTokenService tokenService, + GutCasClient loginClient) { _context = context; _tokenService = tokenService; + _loginClient = loginClient; _securityOptions = options.Value; } @@ -32,16 +41,47 @@ namespace InternshipSystem.Api.Controllers [HttpGet("login")] public async Task Authenticate(string code, CancellationToken cancellationToken) { + var token = await _loginClient.GetCasTokenAsync(code, cancellationToken); + + var casData = await _loginClient.GetProfileAsync(token, cancellationToken); + + if (!long.TryParse(casData.PersonNumber, out var id)) + { + return BadRequest(); + } + + var student = await _context.Students.FirstOrDefaultAsync(s => s.Id == id); + + if (student == null) + { + student = CreateStudentWithCasData(casData); + await _context.Students.AddAsync(student, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + } + var identity = new ClaimsIdentity(new[] { - new Claim(ClaimTypes.Name, "Jan"), - new Claim(ClaimTypes.Surname, "Kowalski"), - new Claim(InternshipClaims.PersonNumber, "1") + new Claim(ClaimTypes.Name, student.FirstName), + new Claim(ClaimTypes.Surname, student.LastName), + new Claim(InternshipClaims.PersonNumber, student.Id.ToString()) }); return Ok(_tokenService.generateToken(identity)); } + [HttpGet("/dev/login")] + public async Task Authenticate(CancellationToken cancellationToken) + { + var identity = new ClaimsIdentity(new[] + { + new Claim(ClaimTypes.Name, "firstname"), + new Claim(ClaimTypes.Surname, "lastname"), + new Claim(InternshipClaims.PersonNumber, "1") + }); + + return Ok(_tokenService.generateToken(identity)); + } + [HttpGet("loginEdition")] [Authorize] public async Task LoginIntoEdition(Guid editionId, [FromServices] User user, CancellationToken token) @@ -64,5 +104,16 @@ namespace InternshipSystem.Api.Controllers return Ok(_tokenService.generateToken(newIdentity)); } + + private Student CreateStudentWithCasData(CasUserData casData) + { + var id = long.Parse(casData.PersonNumber); + var firstName = casData.FirstName; + var lastName = casData.LastName; + var email = casData.Mail.First(s => s.EndsWith("@student.pg.edu.pl")); + var albumNumber = int.Parse(casData.AlbumNumber); + + return Student.CreateStudent(id, firstName, lastName, email, albumNumber); + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/GutCasClient.cs b/src/InternshipSystem.Api/Controllers/GutCasClient.cs new file mode 100644 index 0000000..08f0714 --- /dev/null +++ b/src/InternshipSystem.Api/Controllers/GutCasClient.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using InternshipSystem.Api.Options; +using Microsoft.Extensions.Options; + +namespace InternshipSystem.Api.Controllers +{ + public class GutCasClient + { + private readonly HttpClient _client; + private readonly SecurityOptions _securityOptions; + + public GutCasClient(HttpClient client, IOptions options) + { + _securityOptions = options.Value; + + client.BaseAddress = _securityOptions.BaseUrl; + _client = client; + } + + public async Task GetCasTokenAsync(string code, CancellationToken cancellationToken) + { + var request = new HttpRequestMessage + { + Method = HttpMethod.Post, + Content = new FormUrlEncodedContent(new Dictionary + { + { "grant_type", "authorization_code" }, + { "client_id", _securityOptions.ClientId }, + { "client_secret", _securityOptions.Secret }, + { "redirect_uri", _securityOptions.RedirectUrl.ToString() }, + { "code", code } + }), + RequestUri = _securityOptions.TokenPath + }; + + var response = await _client.SendAsync(request, cancellationToken); + await using var stream = await response.Content.ReadAsStreamAsync(); + + var value = await JsonSerializer.DeserializeAsync>(stream); + + return value["access_token"].ToString(); + } + + + public async Task GetProfileAsync(string token, CancellationToken cancellationToken) + { + var request = new HttpRequestMessage + { + Method = HttpMethod.Get, + Content = new StringContent(string.Empty), + RequestUri = _securityOptions.ProfilePath + }; + + request.Headers.Authorization = AuthenticationHeaderValue.Parse($"Bearer {token}"); + request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); + + var response = await _client.SendAsync(request, cancellationToken); + await using var stream = await response.Content.ReadAsStreamAsync(); + + var result = await JsonSerializer.DeserializeAsync( + stream, + new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }); + + return result.Attributes; + } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs b/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs index 6bc7ab8..d6a2bd1 100644 --- a/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs +++ b/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs @@ -2,10 +2,15 @@ using System.Threading.Tasks; using InternshipSystem.Api.Queries; using InternshipSystem.Api.Security; +using InternshipSystem.Core.Commands; +using InternshipSystem.Repository; +using Microsoft.AspNetCore.Authorization; +using InternshipSystem.Api.Security; using InternshipSystem.Api.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; namespace InternshipSystem.Api.Controllers { @@ -22,7 +27,7 @@ namespace InternshipSystem.Api.Controllers /// /// Validate and add filled internship registration form /// - /// Internship registration data + /// Internship registration data /// If registration form was successfully added /// If the provided registration query was malformed /// This action is only available for authorized student registered for current edition diff --git a/src/InternshipSystem.Api/InternshipSystem.Api.csproj b/src/InternshipSystem.Api/InternshipSystem.Api.csproj index 133fa45..d5c17c0 100644 --- a/src/InternshipSystem.Api/InternshipSystem.Api.csproj +++ b/src/InternshipSystem.Api/InternshipSystem.Api.csproj @@ -23,7 +23,6 @@ - diff --git a/src/InternshipSystem.Api/Options/SecurityOptions.cs b/src/InternshipSystem.Api/Options/SecurityOptions.cs index 2fcf5fe..499b604 100644 --- a/src/InternshipSystem.Api/Options/SecurityOptions.cs +++ b/src/InternshipSystem.Api/Options/SecurityOptions.cs @@ -1,8 +1,21 @@ -namespace InternshipSystem.Api.Options +using System; +using System.Security.Policy; + +namespace InternshipSystem.Api.Options { public class SecurityOptions { public string Secret { get; set; } public double Expiration { get; set; } + + public Uri BaseUrl { get; set; } + + public Uri TokenPath { get; set; } + + public Uri ProfilePath { get; set; } + + public Uri RedirectUrl { get; set; } + + public string ClientId { get; set; } } } \ No newline at end of file diff --git a/src/InternshipSystem.Api/Result/CasUserData.cs b/src/InternshipSystem.Api/Result/CasUserData.cs new file mode 100644 index 0000000..560a3ac --- /dev/null +++ b/src/InternshipSystem.Api/Result/CasUserData.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace InternshipSystem.Api.Controllers +{ + public class CasUserData + { + public string AlbumNumber { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public List Mail { get; set; } + public string PersonNumber { get; set; } + public List Pg_Cui_Portalroles { get; set; } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Result/CasUserProfile.cs b/src/InternshipSystem.Api/Result/CasUserProfile.cs new file mode 100644 index 0000000..f051b2d --- /dev/null +++ b/src/InternshipSystem.Api/Result/CasUserProfile.cs @@ -0,0 +1,10 @@ +namespace InternshipSystem.Api.Controllers +{ + public class CasUserProfile + { + public string Service { get; set; } + public CasUserData Attributes { get; set; } + public string Id { get; set; } + public string Client_Id { get; set; } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Startup.cs b/src/InternshipSystem.Api/Startup.cs index ab34720..ccdc27d 100644 --- a/src/InternshipSystem.Api/Startup.cs +++ b/src/InternshipSystem.Api/Startup.cs @@ -2,6 +2,7 @@ using System; using System.IO; using System.Reflection; using AutoMapper; +using InternshipSystem.Api.Controllers; using InternshipSystem.Api.Extensions; using InternshipSystem.Api.ModelBinders; using InternshipSystem.Api.Options; @@ -26,32 +27,38 @@ namespace InternshipSystem.Api public Startup(IConfiguration configuration) => Configuration = configuration; - public void ConfigureServices(IServiceCollection services) => + public void ConfigureServices(IServiceCollection services) + { services - .Configure(Configuration.GetSection("SecurityOptions")) - .AddDbContext(o => o.UseNpgsql(Configuration.GetConnectionString("InternshipDatabase"))) - .AddSwaggerGen(options => + .Configure(Configuration.GetSection("SecurityOptions")); + + services + .AddStudentAuthentication() + .AddAuthorization(o => + { + o.AddPolicy(Policies.RegisteredOnly, policy => policy.RequireClaim("Edition")); + }) + .AddHttpClient(); + + services + .AddDbContext(o => + o.UseNpgsql(Configuration.GetConnectionString("InternshipDatabase"))) + .AddScoped() + .AddScoped() + .AddScoped() + .AddAutoMapper(cfg => cfg.AddProfile()); + + services + .AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo {Title = "InternshipSystem Api - TEST", Version = "v1"}); var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); options.IncludeXmlComments(xmlPath); }) - .AddScoped() - .AddScoped() - .AddScoped() - .AddAutoMapper(cfg => cfg.AddProfile()) - .AddStudentAuthentication() - .AddAuthorization(o => - { - o.AddPolicy(Policies.RegisteredOnly, policy => policy.RequireClaim("Edition")); - }) - .AddControllers(o => - { - o.ModelBinderProviders.Insert(0, new UserBinderProvider()); - }) - ; - + .AddControllers(o => { o.ModelBinderProviders.Insert(0, new UserBinderProvider()); }); + } + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) diff --git a/src/InternshipSystem.Core/Commands/UpdateRegistrationForm.cs b/src/InternshipSystem.Core/Commands/UpdateRegistrationForm.cs new file mode 100644 index 0000000..4ff3a8d --- /dev/null +++ b/src/InternshipSystem.Core/Commands/UpdateRegistrationForm.cs @@ -0,0 +1,33 @@ +using System; +using InternshipSystem.Core.Entity.Internship; + +namespace InternshipSystem.Core.Commands +{ + public class UpdateRegistrationForm + { + public UpdateCompany? Company { get; set; } + public DateTime? Start { get; set; } + public DateTime? End { get; set; } + public InternshipType? Type { get; set; } + } + + public struct UpdateCompany + { + public long? Id { get; set; } + public string Nip { get; set; } + public string Name { get; set; } + public UpdateBranchOffice? BranchOffice { get; set; } + + public bool IsUpdate => Id.HasValue; + } + + public struct UpdateBranchOffice + { + public long? Id { get; set; } + public string Street { get; set; } + public string Building { get; set; } + public string City { get; set; } + public string PostalCode { get; set; } + public string Country { get; set; } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Company.cs b/src/InternshipSystem.Core/Entity/Company.cs index 46904c4..d722dfd 100644 --- a/src/InternshipSystem.Core/Entity/Company.cs +++ b/src/InternshipSystem.Core/Entity/Company.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using InternshipSystem.Core.Commands; namespace InternshipSystem.Core { @@ -24,5 +26,10 @@ namespace InternshipSystem.Core { Branches.Add(createBranch); } + + public static Company CreateCompany(UpdateCompany updateCompany) + { + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Edition.cs b/src/InternshipSystem.Core/Entity/Edition.cs index 16fd29c..b6fa3cd 100644 --- a/src/InternshipSystem.Core/Entity/Edition.cs +++ b/src/InternshipSystem.Core/Entity/Edition.cs @@ -14,6 +14,9 @@ namespace InternshipSystem.Core public DateTime ReportingStart { get; set; } public Course Course { get; set; } public List Internships { get; set; } + + public InternshipType AllowedInternshipTypes { get; set; } + public List AvailableSubjects { get; set; } public List AvailableInternshipTypes { get; set; } @@ -40,5 +43,15 @@ namespace InternshipSystem.Core Internships.Add(internship); } + + public bool IsDateDuringEdition(DateTime start, DateTime end) + { + return start >= EditionStart && end <= EditionFinish; + } + + public bool IsInternshiptypeAllowed(InternshipType internshipType) + { + return AllowedInternshipTypes.HasFlag(internshipType); + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Internship/Internship.cs b/src/InternshipSystem.Core/Entity/Internship/Internship.cs index 9b15e3b..965835b 100644 --- a/src/InternshipSystem.Core/Entity/Internship/Internship.cs +++ b/src/InternshipSystem.Core/Entity/Internship/Internship.cs @@ -1,5 +1,8 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using InternshipSystem.Core.Commands; +using InternshipSystem.Core.ValueObject; namespace InternshipSystem.Core { @@ -12,9 +15,10 @@ namespace InternshipSystem.Core public Report Report { get; set; } public List Approvals { get; set; } public List Documentation { get; set; } - public float? Grade { get; set; } public Edition Edition { get; set; } + + public float? Grade { get; set; } public void UpdateDocument(Document document) { @@ -47,5 +51,38 @@ namespace InternshipSystem.Core return internship; } + + public void UpdateInternshipRegistration(UpdateRegistrationForm updateRegistration) + { + var start = updateRegistration.Start ?? InternshipRegistration.Start; + var end = updateRegistration.End ?? InternshipRegistration.End; + + if (!Edition.IsDateDuringEdition(start, end)) + { + throw new ArgumentOutOfRangeException(nameof(InternshipRegistration.Start) + nameof(InternshipRegistration.End),"Date outside of edition boundaries"); + } + + var internshipType = updateRegistration.Type ?? InternshipRegistration.Type; + + if (!Edition.IsInternshiptypeAllowed(internshipType)) + { + throw new ArgumentException("Internship type not allowed for this edition", nameof(updateRegistration.Type)); + } + + var company = InternshipRegistration.Company; + if (company == null) + { + if (!updateRegistration.Company.HasValue) + { + throw new ArgumentException("Company"); + } + + company = Company.CreateCompany(updateRegistration.Company.Value); + + + } + + InternshipRegistration.Update(start, end, internshipType); + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs b/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs index 590557b..dc4b68a 100644 --- a/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs +++ b/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs @@ -17,6 +17,13 @@ namespace InternshipSystem.Core { return new InternshipRegistration(); } + + public void Update(DateTime start, DateTime end, InternshipType internshipType) + { + Start = start; + End = end; + Type = internshipType; + } public void UpdateCompany(Company newCompany) { diff --git a/src/InternshipSystem.Core/Entity/Student.cs b/src/InternshipSystem.Core/Entity/Student.cs index b3e7fab..04b7f1b 100644 --- a/src/InternshipSystem.Core/Entity/Student.cs +++ b/src/InternshipSystem.Core/Entity/Student.cs @@ -9,6 +9,17 @@ namespace InternshipSystem.Core public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } - public int Semester { get; set; } + + public static Student CreateStudent(long id, string firstName, string lastName, string email, in int albumNumber) + { + return new Student + { + Id = id, + AlbumNumber = albumNumber, + FirstName = firstName, + LastName = lastName, + Email = email + }; + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Repository/DatabaseFiller.cs b/src/InternshipSystem.Repository/DatabaseFiller.cs index f6038a8..ef31643 100644 --- a/src/InternshipSystem.Repository/DatabaseFiller.cs +++ b/src/InternshipSystem.Repository/DatabaseFiller.cs @@ -223,7 +223,6 @@ namespace InternshipSystem.Repository LastName = "Kowalski", AlbumNumber = 123456, Email = "s123456@student.pg.edu.pl", - Semester = 4, }, InternshipRegistration = new InternshipRegistration { @@ -273,7 +272,6 @@ namespace InternshipSystem.Repository LastName = "Kołek", AlbumNumber = 102137, Email = "s102137@student.pg.edu.pl", - Semester = 6, }, InternshipRegistration = new InternshipRegistration { diff --git a/test/InternshipSystem.Api.Test/InternshipSystem.Api.Test.csproj b/test/InternshipSystem.Api.Test/InternshipSystem.Api.Test.csproj index 80e5e31..b18b329 100644 --- a/test/InternshipSystem.Api.Test/InternshipSystem.Api.Test.csproj +++ b/test/InternshipSystem.Api.Test/InternshipSystem.Api.Test.csproj @@ -6,6 +6,10 @@ false + + + + diff --git a/test/InternshipSystem.Api.Test/InternshipSystem.cs b/test/InternshipSystem.Api.Test/InternshipSystem.cs index b490e1d..2033085 100644 --- a/test/InternshipSystem.Api.Test/InternshipSystem.cs +++ b/test/InternshipSystem.Api.Test/InternshipSystem.cs @@ -1,6 +1,59 @@ using System; +using System.Collections.Generic; +using System.Text.Json; +using InternshipSystem.Api.Controllers; using Machine.Specifications; namespace InternshipSystem.Api.Test { + [Subject(typeof(JsonSerializer))] + class When_deserializing_cas + { + private static string json; + + + private Establish context = () => + { + // { + // "service": "https://system-praktyk.stg.kadet.net/user/login/code", + // "attributes": { + // "albumNumber": "165581", + // "firstName": "Kacper", + // "lastName": "Donat", + // "mail": [ + // "kacdonat@pg.edu.pl", + // "kacper.donat@pg.edu.pl", + // "s165581@student.pg.edu.pl" + // ], + // "personNumber": "1101074", + // "PG_CUI_PORTALROLES": [ + // "ROLE_EKONTAKT_PROD", + // "RP_STUDENT", + // "RP_USER", + // "ROLE_TRAC", + // "ROLE_HUDSON", + // "ROLE_WWW_ADMIN", + // "RP_PRACOWNIK" + // ] + // }, + // "id": "1101074", + // "client_id": "PraktykiClientId" + // } + + json = + " {\r\n \"service\": \"https://system-praktyk.stg.kadet.net/user/login/code\",\r\n \"attributes\": {\r\n \"albumNumber\": \"165581\",\r\n \"firstName\": \"Kacper\",\r\n \"lastName\": \"Donat\",\r\n \"mail\": [\r\n \"kacdonat@pg.edu.pl\",\r\n \"kacper.donat@pg.edu.pl\",\r\n \"s165581@student.pg.edu.pl\"\r\n ],\r\n \"personNumber\": \"1101074\",\r\n \"PG_CUI_PORTALROLES\": [\r\n \"ROLE_EKONTAKT_PROD\",\r\n \"RP_STUDENT\",\r\n \"RP_USER\",\r\n \"ROLE_TRAC\",\r\n \"ROLE_HUDSON\",\r\n \"ROLE_WWW_ADMIN\",\r\n \"RP_PRACOWNIK\"\r\n ]\r\n },\r\n \"id\": \"1101074\",\r\n \"client_id\": \"PraktykiClientId\"\r\n }"; + + options = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true, + }; + }; + + private Because of = () => result = JsonSerializer.Deserialize(json, options); + + private It should_nop = () => true.ShouldBeTrue(); + + private static JsonSerializerOptions options; + private static CasUserProfile result; + } }