major updates login system

This commit is contained in:
henrydays 2018-08-29 18:24:13 +01:00
parent 227ff8cf93
commit efef0ade4d
25 changed files with 919 additions and 274 deletions

View File

@ -5,23 +5,31 @@ using System.Text;
using System.Threading.Tasks;
using api.Dtos;
using api.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
namespace api.Controllers
{
{
[AllowAnonymous]
[Route("api/")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly Data.IAuthRepository repo;
private readonly IConfiguration config;
public AuthController(Data.IAuthRepository repo, IConfiguration config)
public UserManager<User> _userManager { get; }
public SignInManager<User> _signInManager { get; }
public AuthController(IConfiguration config,UserManager<User> UserManager, SignInManager<User> SignInManager)
{
this.config = config;
this.repo = repo;
_userManager = UserManager;
_signInManager = SignInManager;
}
[HttpPost("register")]
@ -30,38 +38,43 @@ namespace api.Controllers
UserForRegisterDto.username = UserForRegisterDto.username.ToLower();
//validar a request
if (await repo.UserExists(UserForRegisterDto.username))
return BadRequest("username already exists");
var userToCreate = new User
{
username = UserForRegisterDto.username,
fullname = UserForRegisterDto.fullname,
gender= UserForRegisterDto.gender,
age= UserForRegisterDto.age,
phone= UserForRegisterDto.phone,
email=UserForRegisterDto.email,
adress=UserForRegisterDto.adress,
country=UserForRegisterDto.country,
city=UserForRegisterDto.city,
linkedin=UserForRegisterDto.linkedin,
lastlogin=UserForRegisterDto.lastlogin,
registed=UserForRegisterDto.registed,
qrcode=UserForRegisterDto.qrcode,
role=UserForRegisterDto.role,
degree=UserForRegisterDto.degree,
schoolyear=UserForRegisterDto.schoolyear,
profileicon=UserForRegisterDto.profileicon,
company=UserForRegisterDto.company,
position=UserForRegisterDto.position,
about=UserForRegisterDto.about
UserName = UserForRegisterDto.username,
FullName = UserForRegisterDto.fullname,
Gender= UserForRegisterDto.gender,
Age= UserForRegisterDto.age,
Phone= UserForRegisterDto.phone,
Email=UserForRegisterDto.email,
Adress=UserForRegisterDto.adress,
Country=UserForRegisterDto.country,
City=UserForRegisterDto.city,
linkedIn=UserForRegisterDto.linkedin,
LastLogin=UserForRegisterDto.lastlogin,
Registed=UserForRegisterDto.registed,
QRcode=UserForRegisterDto.qrcode,
Role=UserForRegisterDto.role,
Degree=UserForRegisterDto.degree,
SchoolYear=UserForRegisterDto.schoolyear,
ProfileIcon=UserForRegisterDto.profileicon,
Company=UserForRegisterDto.company,
Position=UserForRegisterDto.position,
About=UserForRegisterDto.about
};
var createUser = await repo.Register(userToCreate, UserForRegisterDto.password);
return StatusCode(201);
var result = await _userManager.CreateAsync(userToCreate, UserForRegisterDto.password);
if(result.Succeeded)
{
return StatusCode(201);
}
return BadRequest(result.Errors);
}
[HttpPost("login")]
@ -69,20 +82,29 @@ namespace api.Controllers
{
//verifica se o utilizador existe na base de dados e se consegue fazer login
var userFromRepo = await repo.Login(UserForLoginDto.Username.ToLower(), UserForLoginDto.Password);
//Se não conseguir
if (userFromRepo == null)
{
return Unauthorized();
}
var user = await _userManager.FindByNameAsync(UserForLoginDto.Username);
//o token vai ter 2 claims, uma vai ser o id e outra vai ser o nome
var claims = new[]
var result = await _signInManager.CheckPasswordSignInAsync(user,UserForLoginDto.Password, false);
if(result.Succeeded)
{
new Claim(ClaimTypes.NameIdentifier, userFromRepo.id.ToString()),
new Claim(ClaimTypes.Name, userFromRepo.username)
var appUser= await _userManager.Users.FirstOrDefaultAsync(u => u.NormalizedUserName == UserForLoginDto.Username.ToUpper());
return Ok(new {
token = GenerateJwtToken(appUser)
});
}
return Unauthorized();
}
private string GenerateJwtToken(User user){
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.UserName)
};
//obtem a key na app settings
@ -108,10 +130,7 @@ namespace api.Controllers
//em seguida criamos o token
var token = tokenHandler.CreateToken(tokenDescriptor);
//devolvemos ao cliente
return Ok(new {
token= tokenHandler.WriteToken(token)
});
return tokenHandler.WriteToken(token);
}

View File

@ -9,7 +9,7 @@ using Microsoft.EntityFrameworkCore;
namespace api.Controllers
{
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

View File

@ -18,16 +18,16 @@ namespace api.Data
public async Task<User> Login(string username, string password)
{
var user =await Context.Users.FirstOrDefaultAsync(x=> x.username== username);
var user =await Context.Users.FirstOrDefaultAsync(x=> x.UserName== username);
if(user==null)
{
return null;
}
if(!VerifyPasswordHash(password,user.passwordhash,user.passwordsalt))
// if(!VerifyPasswordHash(password,user.passwordhash,user.passwordsalt))
return null;
// return null;
return user;
@ -63,9 +63,8 @@ namespace api.Data
CreatePasswordHash(Password,out passwordHash, out passwordSalt);
user.passwordhash=passwordHash;
user.passwordsalt=passwordSalt;
//user.PasswordHash=passwordHash;
// user.PasswordSalt=passwordSalt;
await Context.Users.AddAsync(user);
@ -78,7 +77,7 @@ namespace api.Data
public async Task<bool> UserExists(string username)
{
if(await Context.Users.AnyAsync(x=>x.username== username))
if(await Context.Users.AnyAsync(x=>x.UserName== username))
{
return true;
}

View File

@ -1,15 +1,40 @@
using api.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace api.Data
{
public class DataContext : DbContext
public class DataContext : IdentityDbContext<User,Role,int,IdentityUserClaim<int>,
UserRole,IdentityUserLogin<int>,IdentityRoleClaim<int>,IdentityUserToken<int>>
{
public DataContext(DbContextOptions<DataContext> options):base(options) { }
public DbSet<Value> Values{get;set;}
public DbSet<User> Users { get; set;}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
//para o ef saber as relações
builder.Entity<UserRole>(userRole =>
{
userRole.HasKey(ur=> new {ur.UserId, ur.RoleId});
userRole.HasOne( ur=>ur.Role)
.WithMany(r=>r.UserRoles)
.HasForeignKey(ur=> ur.RoleId)
.IsRequired();
userRole.HasOne( ur=>ur.User)
.WithMany(r=>r.UserRoles)
.HasForeignKey(ur=> ur.UserId)
.IsRequired();
});
}
}
}

View File

@ -9,7 +9,7 @@ namespace api.Dtos
public string username {get;set;}
[Required]
[StringLength(8,MinimumLength=4,ErrorMessage="You must specify password between 4 and 8 cars")]
[StringLength(15,MinimumLength=4,ErrorMessage="You must specify password between 4 and 15 cars")]
public string password{get;set;}
public string fullname {get;set;}
public string gender {get;set;}

View File

@ -1,91 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using api.Data;
namespace api.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20180828004500_userUpdate")]
partial class userUpdate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846");
modelBuilder.Entity("api.Models.User", b =>
{
b.Property<int>("id")
.ValueGeneratedOnAdd();
b.Property<string>("about");
b.Property<string>("adress");
b.Property<int>("age");
b.Property<string>("city");
b.Property<string>("company");
b.Property<string>("country");
b.Property<string>("degree");
b.Property<string>("email");
b.Property<string>("fullname");
b.Property<string>("gender");
b.Property<DateTime>("lastlogin");
b.Property<string>("linkedin");
b.Property<byte[]>("passwordhash");
b.Property<byte[]>("passwordsalt");
b.Property<int>("phone");
b.Property<string>("position");
b.Property<string>("profileicon");
b.Property<string>("qrcode");
b.Property<DateTime>("registed");
b.Property<string>("role");
b.Property<int>("schoolyear");
b.Property<string>("university");
b.Property<string>("username");
b.HasKey("id");
b.ToTable("Users");
});
modelBuilder.Entity("api.Models.Value", b =>
{
b.Property<int>("id")
.ValueGeneratedOnAdd();
b.Property<string>("Name");
b.HasKey("id");
b.ToTable("Values");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,68 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace api.Migrations
{
public partial class userUpdate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
username = table.Column<string>(nullable: true),
fullname = table.Column<string>(nullable: true),
gender = table.Column<string>(nullable: true),
age = table.Column<int>(nullable: false),
phone = table.Column<int>(nullable: false),
email = table.Column<string>(nullable: true),
passwordhash = table.Column<byte[]>(nullable: true),
passwordsalt = table.Column<byte[]>(nullable: true),
university = table.Column<string>(nullable: true),
adress = table.Column<string>(nullable: true),
country = table.Column<string>(nullable: true),
city = table.Column<string>(nullable: true),
linkedin = table.Column<string>(nullable: true),
lastlogin = table.Column<DateTime>(nullable: false),
registed = table.Column<DateTime>(nullable: false),
qrcode = table.Column<string>(nullable: true),
role = table.Column<string>(nullable: true),
degree = table.Column<string>(nullable: true),
schoolyear = table.Column<int>(nullable: false),
profileicon = table.Column<string>(nullable: true),
company = table.Column<string>(nullable: true),
position = table.Column<string>(nullable: true),
about = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.id);
});
migrationBuilder.CreateTable(
name: "Values",
columns: table => new
{
id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Values", x => x.id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "Values");
}
}
}

View File

@ -0,0 +1,272 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using api.Data;
namespace api.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20180829010046_update")]
partial class update
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846");
modelBuilder.Entity("api.Models.Role", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Name")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("api.Models.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("About");
b.Property<int>("AccessFailedCount");
b.Property<string>("Adress");
b.Property<int>("Age");
b.Property<string>("City");
b.Property<string>("Company");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Country");
b.Property<string>("Degree");
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed");
b.Property<string>("FullName");
b.Property<string>("Gender");
b.Property<DateTime>("LastLogin");
b.Property<bool>("LockoutEnabled");
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash");
b.Property<int>("Phone");
b.Property<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("Position");
b.Property<string>("ProfileIcon");
b.Property<string>("QRcode");
b.Property<DateTime>("Registed");
b.Property<string>("Role");
b.Property<int>("SchoolYear");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("University");
b.Property<string>("UserName")
.HasMaxLength(256);
b.Property<string>("linkedIn");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("api.Models.UserRole", b =>
{
b.Property<int>("UserId");
b.Property<int>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("api.Models.Value", b =>
{
b.Property<int>("id")
.ValueGeneratedOnAdd();
b.Property<string>("Name");
b.HasKey("id");
b.ToTable("Values");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<int>("RoleId");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<int>("UserId");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
{
b.Property<string>("LoginProvider");
b.Property<string>("ProviderKey");
b.Property<string>("ProviderDisplayName");
b.Property<int>("UserId");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
{
b.Property<int>("UserId");
b.Property<string>("LoginProvider");
b.Property<string>("Name");
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("api.Models.UserRole", b =>
{
b.HasOne("api.Models.Role", "Role")
.WithMany("UserRoles")
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("api.Models.User", "User")
.WithMany("UserRoles")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
{
b.HasOne("api.Models.Role")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
{
b.HasOne("api.Models.User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
{
b.HasOne("api.Models.User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
{
b.HasOne("api.Models.User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,254 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace api.Migrations
{
public partial class update : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
AccessFailedCount = table.Column<int>(nullable: false),
EmailConfirmed = table.Column<bool>(nullable: false),
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
LockoutEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
FullName = table.Column<string>(nullable: true),
Gender = table.Column<string>(nullable: true),
Age = table.Column<int>(nullable: false),
Phone = table.Column<int>(nullable: false),
University = table.Column<string>(nullable: true),
Adress = table.Column<string>(nullable: true),
Country = table.Column<string>(nullable: true),
City = table.Column<string>(nullable: true),
linkedIn = table.Column<string>(nullable: true),
LastLogin = table.Column<DateTime>(nullable: false),
Registed = table.Column<DateTime>(nullable: false),
QRcode = table.Column<string>(nullable: true),
Role = table.Column<string>(nullable: true),
Degree = table.Column<string>(nullable: true),
SchoolYear = table.Column<int>(nullable: false),
ProfileIcon = table.Column<string>(nullable: true),
Company = table.Column<string>(nullable: true),
Position = table.Column<string>(nullable: true),
About = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Values",
columns: table => new
{
id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Values", x => x.id);
});
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
RoleId = table.Column<int>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<int>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(nullable: false),
ProviderKey = table.Column<string>(nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
RoleId = table.Column<int>(nullable: false),
UserId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<int>(nullable: false),
LoginProvider = table.Column<string>(nullable: false),
Name = table.Column<string>(nullable: false),
Value = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "Values");
migrationBuilder.DropTable(
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
}
}
}

View File

@ -16,60 +16,128 @@ namespace api.Migrations
modelBuilder
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846");
modelBuilder.Entity("api.Models.User", b =>
modelBuilder.Entity("api.Models.Role", b =>
{
b.Property<int>("id")
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("about");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("adress");
b.Property<string>("Name")
.HasMaxLength(256);
b.Property<int>("age");
b.Property<string>("NormalizedName")
.HasMaxLength(256);
b.Property<string>("city");
b.HasKey("Id");
b.Property<string>("company");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex");
b.Property<string>("country");
b.ToTable("AspNetRoles");
});
b.Property<string>("degree");
modelBuilder.Entity("api.Models.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("email");
b.Property<string>("About");
b.Property<string>("fullname");
b.Property<int>("AccessFailedCount");
b.Property<string>("gender");
b.Property<string>("Adress");
b.Property<DateTime>("lastlogin");
b.Property<int>("Age");
b.Property<string>("linkedin");
b.Property<string>("City");
b.Property<byte[]>("passwordhash");
b.Property<string>("Company");
b.Property<byte[]>("passwordsalt");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<int>("phone");
b.Property<string>("Country");
b.Property<string>("position");
b.Property<string>("Degree");
b.Property<string>("profileicon");
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<string>("qrcode");
b.Property<bool>("EmailConfirmed");
b.Property<DateTime>("registed");
b.Property<string>("FullName");
b.Property<string>("role");
b.Property<string>("Gender");
b.Property<int>("schoolyear");
b.Property<DateTime>("LastLogin");
b.Property<string>("university");
b.Property<bool>("LockoutEnabled");
b.Property<string>("username");
b.Property<DateTimeOffset?>("LockoutEnd");
b.HasKey("id");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256);
b.ToTable("Users");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash");
b.Property<int>("Phone");
b.Property<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("Position");
b.Property<string>("ProfileIcon");
b.Property<string>("QRcode");
b.Property<DateTime>("Registed");
b.Property<string>("Role");
b.Property<int>("SchoolYear");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("University");
b.Property<string>("UserName")
.HasMaxLength(256);
b.Property<string>("linkedIn");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("api.Models.UserRole", b =>
{
b.Property<int>("UserId");
b.Property<int>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("api.Models.Value", b =>
@ -83,6 +151,119 @@ namespace api.Migrations
b.ToTable("Values");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<int>("RoleId");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<int>("UserId");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
{
b.Property<string>("LoginProvider");
b.Property<string>("ProviderKey");
b.Property<string>("ProviderDisplayName");
b.Property<int>("UserId");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
{
b.Property<int>("UserId");
b.Property<string>("LoginProvider");
b.Property<string>("Name");
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("api.Models.UserRole", b =>
{
b.HasOne("api.Models.Role", "Role")
.WithMany("UserRoles")
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("api.Models.User", "User")
.WithMany("UserRoles")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
{
b.HasOne("api.Models.Role")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
{
b.HasOne("api.Models.User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
{
b.HasOne("api.Models.User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
{
b.HasOne("api.Models.User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}

11
api/Models/Role.cs Normal file
View File

@ -0,0 +1,11 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Identity;
namespace api.Models
{
public class Role : IdentityRole <int>
{
public ICollection<UserRole> UserRoles{get;set;}
}
}

View File

@ -1,34 +1,34 @@
using System;
using Microsoft.AspNetCore.Identity;
using System.Collections.Generic;
namespace api.Models
{
public class User
public class User: IdentityUser<int>
{
public int id{get;set;}
public string username {get;set;}
public string fullname {get;set;}
public string gender {get;set;}
public int age{get;set;}
public int phone{get;set;}
public string email{get;set;}
public byte[] passwordhash{get;set;}
public byte[] passwordsalt{get;set;}
public string university{get;set;}
public string adress{get;set;}
public string country{get;set;}
public string city{get;set;}
public string linkedin{get;set;}
public DateTime lastlogin {get;set;}
public DateTime registed{get;set;}
public string qrcode{get;set;}
public string role{get;set;}
public string degree{get;set;}
public int schoolyear{get;set;}
public string profileicon {get;set;}
public string company{get;set;}
public string position{get;set;}
public string about{get;set;}
public string FullName {get;set;}
public string Gender {get;set;}
public int Age{get;set;}
public int Phone{get;set;}
public string University{get;set;}
public string Adress{get;set;}
public string Country{get;set;}
public string City{get;set;}
public string linkedIn{get;set;}
public DateTime LastLogin {get;set;}
public DateTime Registed{get;set;}
public string QRcode{get;set;}
public string Role{get;set;}
public string Degree{get;set;}
public int SchoolYear{get;set;}
public string ProfileIcon {get;set;}
public string Company{get;set;}
public string Position{get;set;}
public string About{get;set;}
public ICollection<UserRole> UserRoles{get;set;}
}
}

11
api/Models/UserRole.cs Normal file
View File

@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Identity;
namespace api.Models
{
public class UserRole: IdentityUserRole<int>
{
public User User{get;set;}
public Role Role{get;set;}
}
}

View File

@ -6,13 +6,17 @@ using System.Text;
using System.Threading.Tasks;
using api.Data;
using api.Helpers;
using api.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@ -39,15 +43,27 @@ namespace api
//define a connection string indicada em appsettings.json
services.AddDbContext<DataContext>(x=>x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
IdentityBuilder builder = services.AddIdentityCore<User>(Options=>
{
//mudar isto no fim por questoes de segurança
Options.Password.RequireDigit = false;
Options.Password.RequiredLength=4;
Options.Password.RequireNonAlphanumeric= false;
Options.Password.RequireUppercase= false;
}
);
//cors support
services.AddCors();
builder= new IdentityBuilder(builder.UserType,typeof(Role),builder.Services);
//cria uma instancia para cada request do cliente (mantem instancia entre CORS)
services.AddScoped<IAuthRepository, AuthRepository>();
builder.AddEntityFrameworkStores<DataContext>();
//autenticação para o token
builder.AddRoleValidator<RoleValidator<Role>>();
builder.AddRoleManager<RoleManager<Role>>();
builder.AddSignInManager<SignInManager<User>>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options=> {
options.TokenValidationParameters = new TokenValidationParameters
{
@ -58,6 +74,22 @@ namespace api
};
});
services.AddMvc(Options=>
{
var policy= new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
Options.Filters.Add(new AuthorizeFilter(policy));
}
).
SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//cors support
services.AddCors();
//autenticação para o token
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
3a97798254b18657d56a44988ab129233ae944cd
30e9dae95a6e59aac28ec7765f632b5b766c0005

Binary file not shown.

Binary file not shown.

BIN
artefacts/api.pages Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
landing.pages Normal file

Binary file not shown.