SKE-58 add participant class to register

This commit is contained in:
Przemysław Stawujak 2018-12-29 19:24:31 +01:00
parent 2fc97f469c
commit 79e797edeb
12 changed files with 170 additions and 8 deletions

View File

@ -38,6 +38,32 @@
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<select class="form-control"
[(ngModel)]="model.role"
name="Role"
required>
<option *ngFor="let possibleRole of possibleRoles" [value]="possibleRole.value">
{{possibleRole.viewValue}}
</option>
</select>
</div>
</div>
<div *ngIf="model.role === 'Participant'" class="form-group form-float">
<div class="form-line">
<select class="form-control"
[(ngModel)]="model.participantClass"
name="ParticipantClass"
required>
<option *ngFor="let possibleClass of possibleClasses" [value]="possibleClass.value">
{{possibleClass.viewValue}}
</option>
</select>
</div>
</div>
<div class="form-actions">
<button [disabled]="saving" [routerLink]="['../login']" type="button" class="btn btn-default">{{l("Powrót")}}</button>
<button type="submit" class="btn btn-success" [disabled]="!registerForm.form.valid">{{l("Zarejestruj")}}</button>

View File

@ -1,4 +1,4 @@
import { Component, Injector, ElementRef, AfterViewInit, ViewChild } from '@angular/core';
import { Component, Injector, ElementRef, OnInit, AfterViewInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { AccountServiceProxy, RegisterInput, RegisterOutput } from '@shared/service-proxies/service-proxies'
import { AppComponentBase } from '@shared/app-component-base';
@ -10,7 +10,7 @@ import { finalize } from 'rxjs/operators';
templateUrl: './register.component.html',
animations: [accountModuleAnimation()]
})
export class RegisterComponent extends AppComponentBase implements AfterViewInit {
export class RegisterComponent extends AppComponentBase implements OnInit, AfterViewInit {
@ViewChild('cardBody') cardBody: ElementRef;
@ -18,6 +18,22 @@ export class RegisterComponent extends AppComponentBase implements AfterViewInit
saving: boolean = false;
public possibleClasses = [
{value: 1, viewValue: 'Klasa 1'},
{value: 2, viewValue: 'Klasa 2'},
{value: 3, viewValue: 'Klasa 3'},
{value: 4, viewValue: 'Klasa 4'},
{value: 5, viewValue: 'Klasa 5'},
{value: 6, viewValue: 'Klasa 6'},
{value: 7, viewValue: 'Klasa 7'},
{value: 8, viewValue: 'Klasa 8'}
];
public possibleRoles = [
{value: 'Participant', viewValue: 'Uczestnik'},
{value: 'Organizer', viewValue: 'Organizator'}
];
constructor(
injector: Injector,
private _accountService: AccountServiceProxy,
@ -31,11 +47,21 @@ export class RegisterComponent extends AppComponentBase implements AfterViewInit
$(this.cardBody.nativeElement).find('input:first').focus();
}
ngOnInit(): void {
this.model.role = 'Participant';
this.model.participantClass = 1;
}
back(): void {
this._router.navigate(['/login']);
}
save(): void {
if (this.model.role === 'Organizer') {
this.model.participantClass = 0;
}
this.model.participantClass = +this.model.participantClass;
this.saving = true;
this._accountService.register(this.model)
.pipe(finalize(() => { this.saving = false; }))

View File

@ -1880,6 +1880,8 @@ export class RegisterInput implements IRegisterInput {
userName: string;
emailAddress: string;
password: string;
role: string;
participantClass: number;
captchaResponse: string | undefined;
constructor(data?: IRegisterInput) {
@ -1898,6 +1900,8 @@ export class RegisterInput implements IRegisterInput {
this.userName = data["userName"];
this.emailAddress = data["emailAddress"];
this.password = data["password"];
this.role = data["role"];
this.participantClass = data["participantClass"];
this.captchaResponse = data["captchaResponse"];
}
}
@ -1916,6 +1920,8 @@ export class RegisterInput implements IRegisterInput {
data["userName"] = this.userName;
data["emailAddress"] = this.emailAddress;
data["password"] = this.password;
data["role"] = this.role;
data["participantClass"] = this.participantClass;
data["captchaResponse"] = this.captchaResponse;
return data;
}
@ -1934,6 +1940,8 @@ export interface IRegisterInput {
userName: string;
emailAddress: string;
password: string;
role: string;
participantClass: number;
captchaResponse: string | undefined;
}

View File

@ -66,6 +66,8 @@ namespace SystemKonkursow.Authorization.Accounts
input.EmailAddress,
input.UserName,
input.Password,
input.Role,
input.ParticipantClass,
true // Assumed email address is always confirmed. Change this if you want to implement email confirmation.
);

View File

@ -31,6 +31,12 @@ namespace SystemKonkursow.Authorization.Accounts.Dto
[DisableAuditing]
public string Password { get; set; }
[Required]
public string Role { get; set; }
[Required]
public int ParticipantClass { get; set; }
[DisableAuditing]
public string CaptchaResponse { get; set; }

View File

@ -11,6 +11,8 @@ using Abp.Runtime.Session;
using Abp.UI;
using SystemKonkursow.Authorization.Roles;
using SystemKonkursow.MultiTenancy;
using SystemKonkursow.Domain;
using Abp.Domain.Repositories;
namespace SystemKonkursow.Authorization.Users
{
@ -22,22 +24,25 @@ namespace SystemKonkursow.Authorization.Users
private readonly UserManager _userManager;
private readonly RoleManager _roleManager;
private readonly IPasswordHasher<User> _passwordHasher;
private readonly IRepository<Domain.Participant, int> _participantRepository;
public UserRegistrationManager(
TenantManager tenantManager,
UserManager userManager,
RoleManager roleManager,
IPasswordHasher<User> passwordHasher)
IPasswordHasher<User> passwordHasher,
IRepository<Domain.Participant, int> participantRepository)
{
_tenantManager = tenantManager;
_userManager = userManager;
_roleManager = roleManager;
_passwordHasher = passwordHasher;
_participantRepository = participantRepository;
AbpSession = NullAbpSession.Instance;
}
public async Task<User> RegisterAsync(string name, string surname, string emailAddress, string userName, string plainPassword, bool isEmailConfirmed)
public async Task<User> RegisterAsync(string name, string surname, string emailAddress, string userName, string plainPassword, string role, int participantClass, bool isEmailConfirmed)
{
CheckForTenant();
@ -57,6 +62,18 @@ namespace SystemKonkursow.Authorization.Users
user.SetNormalizedNames();
if (role == "Participant")
{
var participantRole = _roleManager.Roles.IgnoreQueryFilters().FirstOrDefault(r => r.TenantId == tenant.Id && r.Name == StaticRoleNames.Host.Participant);
user.Roles.Add(new UserRole(tenant.Id, user.Id, participantRole.Id));
}
if (role == "Organizer")
{
var organizerRole = _roleManager.Roles.IgnoreQueryFilters().FirstOrDefault(r => r.TenantId == tenant.Id && r.Name == StaticRoleNames.Host.Organizer);
user.Roles.Add(new UserRole(tenant.Id, user.Id, organizerRole.Id));
}
foreach (var defaultRole in await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync())
{
user.Roles.Add(new UserRole(tenant.Id, user.Id, defaultRole.Id));
@ -65,6 +82,18 @@ namespace SystemKonkursow.Authorization.Users
await _userManager.InitializeOptionsAsync(tenant.Id);
CheckErrors(await _userManager.CreateAsync(user, plainPassword));
if (participantClass != 0)
{
var participant = new Participant
{
UserId = user.Id,
ParticipantClass = participantClass
};
_participantRepository.Insert(participant);
}
await CurrentUnitOfWork.SaveChangesAsync();
return user;

View File

@ -0,0 +1,17 @@
using Abp.Domain.Entities;
using System.ComponentModel.DataAnnotations.Schema;
using SystemKonkursow.Authorization.Users;
namespace SystemKonkursow.Domain
{
[Table("Participants")]
public class Participant : Entity<int>
{
public long UserId { get; set; }
public int ParticipantClass { get; set; }
[ForeignKey(nameof(UserId))]
public virtual User User { get; set; }
}
}

View File

@ -3,11 +3,13 @@ using Abp.Authorization.Users;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using SystemKonkursow.Authorization;
using SystemKonkursow.Authorization.Roles;
using SystemKonkursow.Authorization.Users;
using SystemKonkursow.Domain;
namespace SystemKonkursow.EntityFrameworkCore.Seed
{
@ -30,14 +32,14 @@ namespace SystemKonkursow.EntityFrameworkCore.Seed
//list permissions
});
CreateUser(new List<Role> { organizerRole }, "Jan", "Kowalski", "organizator", "organizator@example.com");
CreateUser(new List<Role> { organizerRole }, "Jan", "Kowalski", "organizator", "organizator@example.com", false);
Role participantRole = CreateRole(StaticRoleNames.Host.Participant, new List<string> {
PermissionNames.Pages_Solve_Competition
//list permissions
});
CreateUser(new List<Role> { participantRole }, "Jerzy", "Nowak", "uczestnik", "uczestnik@example.com");
CreateUser(new List<Role> { participantRole }, "Jerzy", "Nowak", "uczestnik", "uczestnik@example.com", true);
}
private Role CreateRole(string roleName, IList<string> permissionList)
@ -63,8 +65,10 @@ namespace SystemKonkursow.EntityFrameworkCore.Seed
return role;
}
private void CreateUser(IEnumerable<Role> roles, string name, string surname, string userName, string emailAddress)
private void CreateUser(IEnumerable<Role> roles, string name, string surname, string userName, string emailAddress, bool isParticipant)
{
Random rnd = new Random();
var user = _context.Users.IgnoreQueryFilters()
.FirstOrDefault(u => u.TenantId == 1 && u.UserName == userName);
if (null == user)
@ -86,6 +90,18 @@ namespace SystemKonkursow.EntityFrameworkCore.Seed
_context.Users.Add(user);
_context.SaveChanges();
if (isParticipant)
{
var participant = new Participant()
{
UserId = user.Id,
ParticipantClass = rnd.Next(1, 9)
};
_context.Participants.Add(participant);
_context.SaveChanges();
}
// Assign role to user
foreach (var role in roles)
{

View File

@ -16,6 +16,8 @@ namespace SystemKonkursow.EntityFrameworkCore
}
public DbSet<Domain.Participant> Participants { get; set; }
public DbSet<Domain.CompetitionCategory> CompetitionCategories { get; set; }
public DbSet<Domain.Category> Categories { get; set; }

View File

@ -1081,6 +1081,23 @@ namespace SystemKonkursow.Migrations
b.ToTable("CompetitionCategories");
});
modelBuilder.Entity("SystemKonkursow.Domain.Participant", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("ParticipantClass");
b.Property<long>("UserId");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Participants");
});
modelBuilder.Entity("SystemKonkursow.MultiTenancy.Tenant", b =>
{
b.Property<int>("Id")
@ -1302,6 +1319,14 @@ namespace SystemKonkursow.Migrations
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("SystemKonkursow.Domain.Participant", b =>
{
b.HasOne("SystemKonkursow.Authorization.Users.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("SystemKonkursow.MultiTenancy.Tenant", b =>
{
b.HasOne("SystemKonkursow.Authorization.Users.User", "CreatorUser")

View File

@ -25,4 +25,7 @@
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
</Project>

View File

@ -141,6 +141,8 @@ namespace SystemKonkursow.Controllers
externalUser.EmailAddress,
externalUser.EmailAddress,
Authorization.Users.User.CreateRandomPassword(),
"Organizer",
0,
true
);