提交 f5127aca 编写于 作者: 麦壳饼's avatar 麦壳饼

user ,data table,roadmap

上级 b8d1d567
.dockerignore
.env
.git
.gitignore
.vs
.vscode
*/bin
*/obj
**/.toolstarget
\ No newline at end of file
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
assembly-versioning-scheme: MajorMinorPatchTag
assembly-file-versioning-scheme: MajorMinorPatchTag
mode: ContinuousDeployment
next-version: 1.0
patch-version-bump-message: '\+semver:\s?(fix|patch)'
branches: {}
ignore:
sha: []
using IoTSharp.Hub.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class AccountController : ControllerBase
{
private ApplicationDbContext _context;
private ILogger _logger;
private readonly UserManager<IdentityUser> _userManager;
private readonly IConfiguration _configuration;
private readonly SignInManager<IdentityUser> _signInManager;
public AccountController(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
IConfiguration configuration, ILogger<AccountController> logger, ApplicationDbContext context
)
{
_userManager = userManager;
_signInManager = signInManager;
_configuration = configuration;
_logger = logger;
_context = context;
}
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Login([FromBody] LoginDto model)
{
IActionResult actionResult = NoContent();
try
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false);
if (result.Succeeded)
{
var appUser = _userManager.Users.SingleOrDefault(r => r.Email == model.Email);
actionResult = Ok(new { code = 0, msg = "OK", data = GenerateJwtToken(model.Email, appUser) });
}
else
{
actionResult = BadRequest(new { code = -3, msg = "Login Error", data = result });
}
}
catch (Exception ex)
{
actionResult = BadRequest(new { code = -1, msg = ex.Message, data = ex });
}
return actionResult;
}
/// <summary>
/// Register a user
/// </summary>
/// <param name="model"></param>
/// <returns ></returns>
/// <seealso cref="BrokerController.InstallCertificate(CertificateDot)"/>
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Register([FromBody] RegisterDto model)
{
IActionResult actionResult = NoContent();
try
{
var user = new IdentityUser
{
Email = model.Email
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, false);
await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, model.Email));
var cust = _context.Customer.FirstOrDefault(c => c.Name == model.CustomerName);
if (cust != null)
{
await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.GroupSid,cust.Id.ToString()));
actionResult = Ok(new { code = 0, msg = "OK", data = GenerateJwtToken(model.Email, user) });
}
}
else
{
var msg = from e in result.Errors select $"{e.Code}:{e.Description}\r\n";
actionResult = BadRequest(new { code = -3, msg = string.Join(';', msg.ToArray()) });
}
}
catch (Exception ex)
{
actionResult = BadRequest(new { code = -2, msg = ex.Message, data = ex });
_logger.LogError(ex, ex.Message);
}
return actionResult;
}
private object GenerateJwtToken(string email, IdentityUser user)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JwtExpireDays"]));
var token = new JwtSecurityToken(
_configuration["JwtIssuer"],
_configuration["JwtIssuer"],
claims,
expires: expires,
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
public class LoginDto
{
[Required]
public string Password { get; set; }
[Required]
public string Email { get; set; }
}
public class RegisterDto
{
[Required]
public string Email { get; set; }
[Required]
public string CustomerName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "PASSWORD_MIN_LENGTH", MinimumLength = 6)]
public string Password { get; set; }
}
}
}
\ No newline at end of file
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Linq;
namespace IoTSharp.Hub.Data
{
public class ApplicationDbContext : IdentityDbContext
{
IConfiguration _configuration;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IConfiguration configuration)
: base(options)
{
_configuration = configuration;
var _DataBase = configuration["DataBase"] ?? "sqlite";
if (Enum.TryParse(_DataBase, out DatabaseType databaseType))
{
DatabaseType = databaseType;
}
if (this.Database.EnsureCreated())
{
if (Database.GetPendingMigrations().Count() > 0)
{
Database.Migrate();
}
}
}
public DatabaseType DatabaseType { get; private set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>()
.HasOne(p => p.Tenant)
.WithMany(b => b.Customers);
modelBuilder.Entity<Device>()
.HasOne(p => p.Customer)
.WithMany(b => b.Devices);
modelBuilder.Entity<Device>()
.HasOne(p => p.Tenant)
.WithMany(b => b.Devices);
switch (DatabaseType)
{
case DatabaseType.mssql:
ForSqlServer(modelBuilder);
break;
case DatabaseType.npgsql:
ForNpgsql(modelBuilder);
break;
case DatabaseType.sqlite:
break;
default:
break;
}
}
private void ForNpgsql(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ClientSideAttribute>()
.Property(b => b.Value_Json)
.HasColumnType("jsonb");
modelBuilder.Entity<ClientSideAttribute>()
.Property(b => b.Value_XML)
.HasColumnType("xml");
modelBuilder.Entity<ServerSideAttribute>()
.Property(b => b.Value_Json)
.HasColumnType("jsonb");
modelBuilder.Entity<ServerSideAttribute>()
.Property(b => b.Value_XML)
.HasColumnType("xml");
modelBuilder.Entity<SharedSideAttribute>()
.Property(b => b.Value_Json)
.HasColumnType("jsonb");
modelBuilder.Entity<SharedSideAttribute>()
.Property(b => b.Value_XML)
.HasColumnType("xml");
}
private void ForSqlServer(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ClientSideAttribute>()
.Property(b => b.Value_XML)
.HasColumnType("xml");
modelBuilder.Entity<ServerSideAttribute>()
.Property(b => b.Value_XML)
.HasColumnType("xml");
modelBuilder.Entity<SharedSideAttribute>()
.Property(b => b.Value_XML)
.HasColumnType("xml");
}
public DbSet<Tenant> Tenant { get; set; }
public DbSet<Customer> Customer { get; set; }
public DbSet<Relationship> Relationship { get; set; }
public DbSet<Device> Device { get; set; }
public DbSet<ClientSideAttribute> ClientSideAttribute { get; set; }
public DbSet<ServerSideAttribute> ServerSideAttribute { get; set; }
public DbSet<SharedSideAttribute> SharedSideAttribute { get; set; }
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Data
{
public class ClientSideAttribute
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; }
[EnumDataType(typeof(AttributeType))]
public AttributeType Type { get; set; }
public bool Value_Boolean { get; set; }
public string Value_String { get; set; }
public long Value_Long { get; set; }
public double Value_Double { get; set; }
public string Value_Json { get; set; }
public string Value_XML { get; set; }
public byte[] Value_Binary { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Data
{
public class Customer
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Country { get; set; }
public string Province { get; set; }
public string City { get; set; }
public string Street { get; set; }
public string Address { get; set; }
public int ZipCode { get; set; }
public Tenant Tenant { get; set; }
public List<Device> Devices { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Data
{
public class Device
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; }
public string Type { get; set; }
public Tenant Tenant { get; set; }
public Customer Customer { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Data
{
public enum AttributeType
{
Boolean,
String,
Long,
Double,
Json,
XML,
Binary
}
public enum DatabaseType
{
mssql,
npgsql,
sqlite
}
}
// <auto-generated />
using System;
using IoTSharp.Hub.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace IoTSharp.Hub.Data.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("00000000000000_CreateIdentitySchema")]
partial class CreateIdentitySchema
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("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")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("RoleId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed");
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<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasMaxLength(128);
b.Property<string>("ProviderDisplayName");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("Name")
.HasMaxLength(128);
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using System;
namespace IoTSharp.Hub.Data.Migrations
{
public partial class CreateIdentitySchema : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(nullable: false),
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
{
Id = table.Column<string>(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),
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
RoleId = table.Column<string>(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("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
UserId = table.Column<string>(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>(maxLength: 128, nullable: false),
ProviderKey = table.Column<string>(maxLength: 128, nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true),
UserId = table.Column<string>(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
{
UserId = table.Column<string>(nullable: false),
RoleId = table.Column<string>(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<string>(nullable: false),
LoginProvider = table.Column<string>(maxLength: 128, nullable: false),
Name = table.Column<string>(maxLength: 128, 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,
filter: "[NormalizedName] IS NOT NULL");
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,
filter: "[NormalizedUserName] IS NOT NULL");
}
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: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
}
}
}
\ No newline at end of file
// <auto-generated />
using System;
using IoTSharp.Hub.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace IoTSharp.Hub.Data.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.4-rtm-31024")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("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")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("RoleId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed");
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<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasMaxLength(128);
b.Property<string>("ProviderDisplayName");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("Name")
.HasMaxLength(128);
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Data
{
public class Relationship
{
[Key]
public Guid UseId { get; set; }
public Guid CustomerId { get; set; }
public Guid TenantId { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Data
{
public class ServerSideAttribute
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; }
[EnumDataType(typeof(AttributeType))]
public AttributeType Type { get; set; }
public bool Value_Boolean { get; set; }
public string Value_String { get; set; }
public long Value_Long { get; set; }
public double Value_Double { get; set; }
public string Value_Json { get; set; }
public string Value_XML { get; set; }
public byte[] Value_Binary { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Data
{
public class SharedSideAttribute
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; }
[EnumDataType(typeof(AttributeType))]
public AttributeType Type { get; set; }
public bool Value_Boolean { get; set; }
public string Value_String { get; set; }
public long Value_Long { get; set; }
public double Value_Double { get; set; }
public string Value_Json { get; set; }
public string Value_XML { get; set; }
public byte[] Value_Binary { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Data
{
public class Tenant
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; }
public string EMail { get; set; }
public string Phone { get; set; }
public string Country { get; set; }
public string Province { get; set; }
public string City { get; set; }
public string Street { get; set; }
public string Address { get; set; }
public int ZipCode { get; set; }
public List<Customer> Customers { get; set; }
public List<Device> Devices { get; set; }
}
}
using HealthChecks.UI.Client;
using IoTSharp.Hub.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MQTTnet.Diagnostics;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace IoTSharp.Hub
{
public static class IoTSharpExtension
{
public static void AddIoTSharpHub(this IServiceCollection services, IConfiguration configuration)
{
var _DataBase = configuration["DataBase"] ?? "sqlite";
var _ConnectionString = Environment.ExpandEnvironmentVariables(configuration.GetConnectionString(_DataBase) ?? "Data Source=%APPDATA%\\IoTSharp.Hub\\MQTTChat.db;Pooling=true;");
switch (_DataBase)
{
case "mssql":
services.AddEntityFrameworkSqlServer();
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(_ConnectionString), ServiceLifetime.Transient);
services.AddHealthChecks().AddSqlServer(_ConnectionString, name: "database").AddMQTTChatHealthChecks();
break;
case "npgsql":
services.AddEntityFrameworkNpgsql();
services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(_ConnectionString), ServiceLifetime.Transient);
services.AddHealthChecks().AddNpgSql(_ConnectionString, name: "database").AddMQTTChatHealthChecks();
break;
case "memory":
services.AddEntityFrameworkInMemoryDatabase();
services.AddDbContext<ApplicationDbContext>(options => options.UseInMemoryDatabase(nameof(ApplicationDbContext)), ServiceLifetime.Transient);
services.AddHealthChecks().AddMQTTChatHealthChecks();
break;
case "sqlite":
default:
services.AddEntityFrameworkSqlite();
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlite(_ConnectionString), ServiceLifetime.Transient);
services.AddHealthChecks().AddSqlite(_ConnectionString, name: "database").AddMQTTChatHealthChecks();
break;
}
services.AddHealthChecksUI();
}
internal static void UseIotSharpHealthChecks(this IApplicationBuilder app)
{
app.UseHealthChecksUI();
app.UseHealthChecks("/health", new HealthCheckOptions()
{
Predicate = _ => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
}
private static void AddMQTTChatHealthChecks(this IHealthChecksBuilder builder)
{
builder.AddPrivateMemoryHealthCheck(1024 * 1024 * 1024, "privatememory")
.AddDiskStorageHealthCheck(setup =>
{
DriveInfo.GetDrives().ToList().ForEach(di =>
{
setup.AddDrive(di.Name, 1024);
});
});
}
private static string GetFullPathName(string filename)
{
FileInfo fi = new FileInfo(System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.Create)
, MethodBase.GetCurrentMethod().DeclaringType.Assembly.GetName().Name, filename));
if (!fi.Directory.Exists) fi.Directory.Create();
return fi.FullName;
}
public static void UseMqttLogger(this IApplicationBuilder app)
{
var mqttNetLogger = app.ApplicationServices.GetService<IMqttNetLogger>();
var _loggerFactory = app.ApplicationServices.GetService<ILoggerFactory>();
var logger = _loggerFactory.CreateLogger<IMqttNetLogger>();
mqttNetLogger.LogMessagePublished += (object sender, MqttNetLogMessagePublishedEventArgs e) =>
{
var message = $"ID:{e.TraceMessage.LogId},ThreadId:{e.TraceMessage.ThreadId},Source:{e.TraceMessage.Source},Timestamp:{e.TraceMessage.Timestamp},Message:{e.TraceMessage.Message}";
switch (e.TraceMessage.Level)
{
case MqttNetLogLevel.Verbose:
logger.LogTrace(e.TraceMessage.Exception, message);
break;
case MqttNetLogLevel.Info:
logger.LogInformation(e.TraceMessage.Exception, message);
break;
case MqttNetLogLevel.Warning:
logger.LogWarning(e.TraceMessage.Exception, message);
break;
case MqttNetLogLevel.Error:
logger.LogError(e.TraceMessage.Exception, message);
break;
default:
break;
}
};
}
}
}
\ No newline at end of file
using System.Threading.Tasks;
namespace IoTSharp.Hub.Extensions
{
public static class MiscExtension
{
public static Task Forget(this Task task)
{
return Task.CompletedTask;
}
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<Company>IoT#</Company>
<Product>IoTSharp</Product>
<Authors>IoT#</Authors>
<PackageProjectUrl>https://github.com/IoTSharp/IoTSharp</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/IoTSharp/IoTSharp/blob/master/LICENSE</PackageLicenseUrl>
<RepositoryUrl>https://github.com/IoTSharp/IoTSharp</RepositoryUrl>
<PackageReleaseNotes>
Open-source IoT Platform - Device management, data collection, processing and visualization. https://www.iotsharp.net
</PackageReleaseNotes>
<Description>
Open-source IoT Platform - Device management, data collection, processing and visualization.
</Description>
<PackageId>IoTSharp</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Network" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Sqlite" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.System" Version="2.2.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="2.2.4" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="IoTSharp.X509Extensions" Version="1.3.3" />
<PackageReference Include="LiteDB" Version="4.1.4" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.6" />
<PackageReference Include="MQTTnet" Version="2.8.5" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" />
<PackageReference Include="NSwag.AspNetCore" Version="12.0.7" />
<PackageReference Include="QuartzHostedService" Version="0.0.3" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
</ItemGroup>
</Project>
\ No newline at end of file
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using System.Text;
namespace IoTSharp.Hub
{
public class Program
{
public static void Main(string[] args)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
\ No newline at end of file
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace IoTSharp.Hub.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("IoTSharp.Hub.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性
/// 重写当前线程的 CurrentUICulture 属性。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// 查找类似 显示帮助 的本地化字符串。
/// </summary>
public static string ShowHelp {
get {
return ResourceManager.GetString("ShowHelp", resourceCulture);
}
}
/// <summary>
/// 查找类似 The certificate is installed 的本地化字符串。
/// </summary>
public static string TheCertificateIsInstalled {
get {
return ResourceManager.GetString("TheCertificateIsInstalled", resourceCulture);
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ShowHelp" xml:space="preserve">
<value>显示帮助</value>
</data>
<data name="TheCertificateIsInstalled" xml:space="preserve">
<value>The certificate is installed</value>
</data>
</root>
\ No newline at end of file
using IoTSharp.Hub.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NSwag.AspNetCore;
using System;
using System.Linq;
using System.Reflection;
namespace IoTSharp.Hub
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddLogging(loggingBuilder => loggingBuilder.AddConsole());
services.AddIoTSharpHub(Configuration);
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication().AddJwtBearer();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
services.AddSwaggerDocument(configure =>
{
Assembly assembly = typeof(Startup).GetTypeInfo().Assembly;
var description = (AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyDescriptionAttribute));
configure.Title = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
configure.Version = typeof(Startup).GetTypeInfo().Assembly.GetName().Version.ToString();
configure.Description = description?.Description;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseAuthentication();
app.UseMvc();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseSwaggerUi3();
app.UseSwagger(config => config.PostProcess = (document, request) =>
{
if (request.Headers.ContainsKey("X-External-Host"))
{
// Change document server settings to public
document.Host = request.Headers["X-External-Host"].First();
document.BasePath = request.Headers["X-External-Path"].First();
}
});
app.UseSwaggerUi3(config => config.TransformToExternalPath = (internalUiRoute, request) =>
{
// The header X-External-Path is set in the nginx.conf file
var externalPath = request.Headers.ContainsKey("X-External-Path") ? request.Headers["X-External-Path"].First() : "";
return externalPath + internalUiRoute;
});
app.UseIotSharpHealthChecks();
}
}
}
\ No newline at end of file
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"DataBase": "sqlite",
"ConnectionStrings": {
"mssql": "Server=localhost;Database=MQTTChat;Trusted_Connection=True;MultipleActiveResultSets=true",
"npgsql": "Server=localhost;Database=MQTTChat;Username=postgres;Password=future;",
"sqlite": "Data Source=:memory:"
},
"JwtKey": "kissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissme",
"JwtExpireDays": 1,
"JwtIssuer": "IoTSharp.Hub",
"AllowedHosts": "*",
"HealthChecks-UI": {
"HealthChecks": [
{
"Name": "HTTP-Api-Basic",
"Uri": "http://localhost:5000/health"
}
],
"Webhooks": [
{
"Name": "",
"Uri": "",
"Payload": "",
"RestoredPayload": ""
}
],
"EvaluationTimeOnSeconds": 10,
"MinimumSecondsBetweenFailureNotifications": 60
}
}
\ No newline at end of file
{
"DataBase": "npgsql",
"ConnectionStrings": {
"npgsql": "Server=localhost;Database=IoTSharp;Username=postgres;Password=future;",
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"JwtKey": "kissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissme",
"JwtExpireDays": 1,
"JwtIssuer": "IoTSharp.Hub",
"AllowedHosts": "*"
}
\ No newline at end of file
<head>
<title>IoTSharp.Hub</title>
<meta http-equiv="refresh" content="2;url=/swagger/">
</head>
<body>
<a href="https://api.iotsharp.net/swagger/"> Click here to browse swagger, currently only it </a>
</body>
\ No newline at end of file

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2048
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTSharp.Hub", "IoTSharp.Hub\IoTSharp.Hub.csproj", "{260081B3-E2EA-4BA0-8322-E3894907585E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D5C97089-F896-436D-8E99-27B2E43BC65F}"
ProjectSection(SolutionItems) = preProject
GitVersion.yml = GitVersion.yml
LICENSE = LICENSE
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApplication1", "WebApplication1\WebApplication1.csproj", "{4B89CAE2-66F7-4C95-B701-AE48810F2051}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{260081B3-E2EA-4BA0-8322-E3894907585E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{260081B3-E2EA-4BA0-8322-E3894907585E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{260081B3-E2EA-4BA0-8322-E3894907585E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{260081B3-E2EA-4BA0-8322-E3894907585E}.Release|Any CPU.Build.0 = Release|Any CPU
{4B89CAE2-66F7-4C95-B701-AE48810F2051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B89CAE2-66F7-4C95-B701-AE48810F2051}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B89CAE2-66F7-4C95-B701-AE48810F2051}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B89CAE2-66F7-4C95-B701-AE48810F2051}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CD7ADD62-E3BD-453A-B653-BC70DB9FF817}
EndGlobalSection
EndGlobal
# IoT# Roadmap
This roadmap communicates priorities for evolving and extending IoTSharp.
At present, our primary focus is enabling the following for IoTSharp:
* Multi-tenant devices and assets Management
* Collect and visualize data
* Process and React
As we complete those goals, we'll update our roadmap to include additional feature/capability areas we will focus on next.
For general information regarding IoTSharp.Gateway plans, [IoTShap GateWay
roadmap](https://github.com/IoTSharp/IotSharp.Gateway/blob/master/roadmap.md).
## Timelines
| Milestone | Date |
|---|---|
|Initial launch of IoTSharp and MQTT.Chat |Q4 2018|
|Multi-tenant devices and assets Management |Q1 2019|
|Collect and visualize data |Q1 2019|
|Process and React|Q2 2019|
If you'd like to contribute to WinForms, please take a look at our [Contributing
Guide](contributing.md).
## Shorter-Term Feature Backlog
* Account, user, device, asset management
* Properties, telemetry data display, and editing
## Longer-Term Feature Backlog
* Collect and visualize data
* RPC capabilities
* Process and React
* Rule Engine
* Scheduler
* Reporting
* Widgets desinger
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册