18 | Swapping to Development environment will display more detailed information about the error that occurred.
19 |
20 |
21 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application.
22 |
23 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.IdentityServer/User/IdentityServerBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using Nyw.IdentityServer.User;
2 | using System.Collections.Generic;
3 |
4 | namespace Microsoft.Extensions.DependencyInjection {
5 | ///
6 | /// Extension methods for the IdentityServer builder
7 | ///
8 | public static class IdentityServerBuilderExtensions {
9 | ///
10 | /// Adds test users.
11 | ///
12 | /// The builder.
13 | /// The users.
14 | ///
15 | public static IIdentityServerBuilder AddUserModel(this IIdentityServerBuilder builder) {
16 | builder.Services.AddSingleton(new UserStore());
17 | builder.AddProfileService();
18 | builder.AddResourceOwnerValidator();
19 | return builder;
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/Controllers/RedisController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using StackExchange.Redis;
7 |
8 |
9 | namespace Nyw.Portal.Controllers {
10 | public class RedisController : Controller {
11 | public IActionResult Index() {
12 | var cfg = ConfigurationOptions.Parse("localhost:6379");
13 | //cfg.Password = "P2ssw0rd";
14 |
15 | ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(cfg);
16 | IDatabase db = redis.GetDatabase();
17 |
18 | string cVal = "abcdefg";
19 | var cKey = "mykey";
20 | db.StringSet(cKey, cVal);
21 | System.Diagnostics.Trace.WriteLine($"Set {nameof(cKey)}'s value : {cVal} to Redis");
22 |
23 | cVal = db.StringGet(cKey);
24 | System.Diagnostics.Trace.WriteLine($"Get {nameof(cKey)}'s value : {cVal} from Redis");
25 | return View();
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/lib/jquery-validation/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-validation",
3 | "homepage": "http://jqueryvalidation.org/",
4 | "repository": {
5 | "type": "git",
6 | "url": "git://github.com/jzaefferer/jquery-validation.git"
7 | },
8 | "authors": [
9 | "Jörn Zaefferer "
10 | ],
11 | "description": "Form validation made easy",
12 | "main": "dist/jquery.validate.js",
13 | "keywords": [
14 | "forms",
15 | "validation",
16 | "validate"
17 | ],
18 | "license": "MIT",
19 | "ignore": [
20 | "**/.*",
21 | "node_modules",
22 | "bower_components",
23 | "test",
24 | "demo",
25 | "lib"
26 | ],
27 | "dependencies": {
28 | "jquery": ">= 1.7.2"
29 | },
30 | "version": "1.14.0",
31 | "_release": "1.14.0",
32 | "_resolution": {
33 | "type": "version",
34 | "tag": "1.14.0",
35 | "commit": "c1343fb9823392aa9acbe1c3ffd337b8c92fed48"
36 | },
37 | "_source": "git://github.com/jzaefferer/jquery-validation.git",
38 | "_target": ">=1.8",
39 | "_originalSource": "jquery-validation"
40 | }
--------------------------------------------------------------------------------
/DevOps/Sonarqube/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "2"
2 |
3 | services:
4 | sonarqube:
5 | image: sonarqube
6 | ports:
7 | - "9000:9000"
8 | networks:
9 | - sonarnet
10 | environment:
11 | - SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar
12 | volumes:
13 | - sonarqube_conf:/opt/sonarqube/conf
14 | - sonarqube_data:/opt/sonarqube/data
15 | - sonarqube_extensions:/opt/sonarqube/extensions
16 | - sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins
17 |
18 | db:
19 | image: postgres
20 | networks:
21 | - sonarnet
22 | environment:
23 | - POSTGRES_USER=sonar
24 | - POSTGRES_PASSWORD=sonar
25 | volumes:
26 | - postgresql:/var/lib/postgresql
27 | # This needs explicit mapping due to https://github.com/docker-library/postgres/blob/4e48e3228a30763913ece952c611e5e9b95c8759/Dockerfile.template#L52
28 | - postgresql_data:/var/lib/postgresql/data
29 |
30 | networks:
31 | sonarnet:
32 | driver: bridge
33 |
34 | volumes:
35 | sonarqube_conf:
36 | sonarqube_data:
37 | sonarqube_extensions:
38 | sonarqube_bundled-plugins:
39 | postgresql:
40 | postgresql_data:
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/lib/bootstrap/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap",
3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
4 | "keywords": [
5 | "css",
6 | "js",
7 | "less",
8 | "mobile-first",
9 | "responsive",
10 | "front-end",
11 | "framework",
12 | "web"
13 | ],
14 | "homepage": "http://getbootstrap.com",
15 | "license": "MIT",
16 | "moduleType": "globals",
17 | "main": [
18 | "less/bootstrap.less",
19 | "dist/js/bootstrap.js"
20 | ],
21 | "ignore": [
22 | "/.*",
23 | "_config.yml",
24 | "CNAME",
25 | "composer.json",
26 | "CONTRIBUTING.md",
27 | "docs",
28 | "js/tests",
29 | "test-infra"
30 | ],
31 | "dependencies": {
32 | "jquery": "1.9.1 - 3"
33 | },
34 | "version": "3.3.7",
35 | "_release": "3.3.7",
36 | "_resolution": {
37 | "type": "version",
38 | "tag": "v3.3.7",
39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
40 | },
41 | "_source": "https://github.com/twbs/bootstrap.git",
42 | "_target": "v3.3.7",
43 | "_originalSource": "bootstrap",
44 | "_direct": true
45 | }
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/lib/bootstrap/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2011-2016 Twitter, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Vendor/Nyw.Vendor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 | Nyw.VendorService
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/lib/jquery-validation/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | =====================
3 |
4 | Copyright Jörn Zaefferer
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/Views/Shared/_ValidationScriptsPartial.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
18 |
19 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ApiGateway/Nyw.ApiGateway.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | PreserveNewest
24 |
25 |
26 | PreserveNewest
27 |
28 |
29 | PreserveNewest
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ApiGateway/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Configuration;
4 | using Microsoft.Extensions.DependencyInjection;
5 |
6 | using Ocelot.Middleware;
7 | using Ocelot.DependencyInjection;
8 | using Ocelot.Administration;
9 |
10 | namespace Ocelot.POC {
11 | public class Startup {
12 | public Startup(IConfiguration configuration) {
13 | Configuration = configuration;
14 | }
15 |
16 | public IConfiguration Configuration { get; }
17 |
18 | // This method gets called by the runtime. Use this method to add services to the container.
19 | public void ConfigureServices(IServiceCollection services) {
20 | services.AddMvc();
21 | services.AddOcelot()
22 | .AddAdministration();
23 | }
24 |
25 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
26 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
27 | if (env.IsDevelopment()) {
28 | app.UseDeveloperExceptionPage();
29 | }
30 | app.UseAuthentication();
31 | app.UseMvc();
32 | app.UseOcelot().Wait();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/lib/jquery-validation-unobtrusive/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-validation-unobtrusive",
3 | "version": "3.2.6",
4 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive",
5 | "description": "Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.",
6 | "main": [
7 | "jquery.validate.unobtrusive.js"
8 | ],
9 | "ignore": [
10 | "**/.*",
11 | "*.json",
12 | "*.md",
13 | "*.txt",
14 | "gulpfile.js"
15 | ],
16 | "keywords": [
17 | "jquery",
18 | "asp.net",
19 | "mvc",
20 | "validation",
21 | "unobtrusive"
22 | ],
23 | "authors": [
24 | "Microsoft"
25 | ],
26 | "license": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm",
27 | "repository": {
28 | "type": "git",
29 | "url": "git://github.com/aspnet/jquery-validation-unobtrusive.git"
30 | },
31 | "dependencies": {
32 | "jquery-validation": ">=1.8",
33 | "jquery": ">=1.8"
34 | },
35 | "_release": "3.2.6",
36 | "_resolution": {
37 | "type": "version",
38 | "tag": "v3.2.6",
39 | "commit": "13386cd1b5947d8a5d23a12b531ce3960be1eba7"
40 | },
41 | "_source": "git://github.com/aspnet/jquery-validation-unobtrusive.git",
42 | "_target": "3.2.6",
43 | "_originalSource": "jquery-validation-unobtrusive"
44 | }
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ApiGateway/Administration/OcelotBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Ocelot.Administration {
2 | using System;
3 | using DependencyInjection;
4 | using IdentityServer4.AccessTokenValidation;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.Extensions.Configuration;
7 | using Microsoft.Extensions.DependencyInjection;
8 |
9 | public static class OcelotBuilderExtensions {
10 | public static IOcelotBuilder AddAdministration(this IOcelotBuilder builder) {
11 |
12 | IConfiguration configuration = builder.Configuration;
13 |
14 | Action idpOptions = o => {
15 | o.Authority = configuration.GetValue("Idp:Authority");// @"http://localhost:8500";
16 | o.ApiName = configuration.GetValue("Idp:ApiName", "apigw.admin"); //"apigw.admin";
17 | o.RequireHttpsMetadata = configuration.GetValue("Idp:RequireHttpsMetadata", false); //false;
18 | o.SupportedTokens = SupportedTokens.Both;
19 | };
20 |
21 | builder.Services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
22 | .AddIdentityServerAuthentication(idpOptions);
23 | //return new OcelotAdministrationBuilder(builder.Services, builder.Configuration);
24 | return builder;
25 | }
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ApiGateway/Controllers/GlobalController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using Microsoft.AspNetCore.Authorization;
4 | using Microsoft.AspNetCore.Mvc;
5 | using Microsoft.Extensions.Logging;
6 | using Ocelot.Configuration.File;
7 | using Ocelot.Configuration.Repository;
8 | using Ocelot.Configuration.Setter;
9 |
10 | namespace NSB.ApiManagement.ApiMgtService.Controllers {
11 | //此Controller操作FileConfiguration.GlobalConfiguration,包括查询/更新
12 | [Route("admin/[controller]")]
13 | [ApiController]
14 | [Authorize]
15 | public class GlobalController : ControllerBase
16 | {
17 | private readonly IFileConfigurationRepository _repo;
18 | private readonly IFileConfigurationSetter _setter;
19 | private readonly IServiceProvider _provider;
20 | private readonly ILogger _logger;
21 |
22 | public GlobalController(IFileConfigurationRepository repo, IFileConfigurationSetter setter, IServiceProvider provider, ILogger logger) {
23 | _repo = repo;
24 | _setter = setter;
25 | _provider = provider;
26 | _logger = logger;
27 | }
28 | [HttpGet]
29 | public async Task Get() {
30 | _logger.LogInformation("get demo log");
31 | var response = await _repo.Get();
32 | if (response.IsError) {
33 | return new BadRequestObjectResult(response.Errors);
34 | }
35 | return new OkObjectResult(response.Data.GlobalConfiguration);
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ApiGateway/nlog.config:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.IdentityServer/nlog.config:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/DevOps/Sonarqube/README.md:
--------------------------------------------------------------------------------
1 | ## 环境说明
2 | - Windows 10 v1803
3 | - Docker Version 18.03.1-ce-win65
4 | - [JDK1.8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
5 | - .NET Core 2.x
6 |
7 | ## 准备条件
8 | - 使用docker-compose准备Sonarqube环境
9 | - 本地安装dotnet-sonarscaner工具
10 | ```cmd
11 | dotnet tool install --global dotnet-sonarscanner --version 4.3.1
12 | ```
13 |
14 | ## 启动Sonarqube:
15 | - 打开命令行,切换到此目录
16 | - 运行命令:
17 | ```cmd
18 | docker-compose up
19 | ```
20 | - 打开浏览器,访问http://localhost:9000
21 | - 完成
22 | - 重启
23 | ```cmd
24 | docker-compose restart sonarqube
25 | ```
26 |
27 | ## 扫描代码
28 | - 打开浏览器,访问http://localhost:9000,使用管理员账号密码登录(默认都是admin),进入Sonar项目管理界面
29 | 
30 | - 输入项目名称,生成token
31 | - 点击继续,选择项目类型,输入项目唯一key(任意字符,唯一即可)
32 | - 点击完后会生执行步骤,可复制,稍后使用
33 | - 打开命令行(cmd或powershell)窗口,切换目录到项目目录下
34 | - 依次执行刚才复制的命令
35 | ```cmd
36 | dotnet sonarscanner begin /k:"TestProject" /d:sonar.host.url="http://localhost:9000" /d:sonar.login="cfe594fd605f2e4821835e43c69da82e489c2f23"
37 | dotnet build
38 | dotnet sonarscanner end /d:sonar.login="cfe594fd605f2e4821835e43c69da82e489c2f23"
39 | ```
40 | - 等待命令执行完毕后即可重新访问http://localhost:9000查看扫描报告
41 | 
42 |
43 | ## 注意事项
44 | - 本地需安装配置JDK,否则执行dotnet sonarscanner end会失败
45 | - 如果是对整个解决方案进行扫描,或目录下有多个项目时,需在dotnet build命令后添加要扫描的解决方案或项目,如
46 | ``` cmd
47 | dotnet build ./test.sln
48 | ```
49 |
50 | ## 参考
51 | - 原始文件[docker-compose](https://github.com/SonarSource/docker-sonarqube/blob/master/recipes.md)
52 | - [使用说明](https://www.cnblogs.com/myzony/p/9233667.html)
53 | - [dotnet build](https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-build?tabs=netcore2x)
54 | - [dotnte tool install](https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-tool-install)
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Hosting;
7 | using Microsoft.Extensions.Configuration;
8 | using Microsoft.Extensions.DependencyInjection;
9 | using SkyWalking.AspNetCore;
10 |
11 | namespace Nyw.Portal {
12 | public class Startup {
13 | public Startup(IConfiguration configuration) {
14 | Configuration = configuration;
15 | }
16 |
17 | public IConfiguration Configuration { get; }
18 |
19 | // This method gets called by the runtime. Use this method to add services to the container.
20 | public void ConfigureServices(IServiceCollection services) {
21 | services.AddMvc();
22 | //services.AddSkyWalking(option => {
23 | // option.ApplicationCode = "Nyw.Portal";
24 | // option.DirectServers = "10.0.1.202:11800";
25 | //});
26 | }
27 |
28 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
29 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
30 | if (env.IsDevelopment()) {
31 | app.UseDeveloperExceptionPage();
32 | }
33 | else {
34 | app.UseExceptionHandler("/Home/Error");
35 | }
36 |
37 | app.UseStaticFiles();
38 |
39 | app.UseMvc(routes => {
40 | routes.MapRoute(
41 | name: "default",
42 | template: "{controller=Home}/{action=Index}/{id?}");
43 | });
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Vendor/Controllers/ValuesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Microsoft.Extensions.Logging;
7 | using Nyw.VendorService.Models;
8 |
9 | namespace Nyw.VendorService.Controllers {
10 | [Route("api/[controller]")]
11 | public class ValuesController : Controller {
12 | private static List vendors = new List {
13 | new VendorModel{ Id=1 },
14 | new VendorModel{ Id=2, Name="京东" },
15 | new VendorModel{ Id=3, Name="腾讯"}
16 | };
17 | private ILogger log = null;
18 | public ValuesController(ILogger logger) {
19 | this.log = logger;
20 | }
21 | // GET api/values
22 | [HttpGet]
23 | public IEnumerable Get() {
24 |
25 | return vendors;
26 | }
27 |
28 | // GET api/values/5
29 | [HttpGet("{id}")]
30 | public VendorModel Get(int id) {
31 | var vendor = vendors.Where(v => v.Id == id).FirstOrDefault();
32 | log.LogInformation("Read {@Vendor}",vendor);
33 | return vendor;
34 | }
35 |
36 | // POST api/values
37 | [HttpPost]
38 | public void Post([FromBody]string value) {
39 | }
40 |
41 | // PUT api/values/5
42 | [HttpPut("{id}")]
43 | public void Put(int id, [FromBody]string value) {
44 | }
45 |
46 | // DELETE api/values/5
47 | [HttpDelete("{id}")]
48 | public string Delete(int id) {
49 | return $"delete vendor:{id} success";
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Employee/Controllers/ValuesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Nyw.EmployeeServices.Models;
7 |
8 | namespace Nyw.EmployeeServices.Controllers {
9 | [Route("api/[controller]")]
10 | public class ValuesController : Controller {
11 | private static List employees = new List {
12 | new EmployeeModel{Id=1, Alias="zhangsan", NameCN="张三", NameEN="san zhang", Mail="zhangsan@nyw.com" },
13 | new EmployeeModel{Id=2, Alias="lisi", NameCN="李四", NameEN="si li", Mail="lisi@nyw.com" },
14 | new EmployeeModel{Id=3, Alias="wangwu", NameCN="王五", NameEN="wu wang", Mail="wangwu@nyw.com" },
15 | new EmployeeModel{Id=4, Alias="zhaoliu", NameCN="赵六", NameEN="liu zhao", Mail="zhaoliu@nyw.com" }
16 | };
17 | // GET api/values
18 | [HttpGet]
19 | public IEnumerable Get() {
20 | return employees;
21 | }
22 |
23 | // GET api/values/5
24 | [HttpGet("{id}")]
25 | public EmployeeModel Get(int id) {
26 | return employees.Where(e => e.Id == id).FirstOrDefault();
27 | }
28 |
29 | // POST api/values
30 | [HttpPost]
31 | public void Post([FromBody]string value) {
32 | }
33 |
34 | // PUT api/values/5
35 | [HttpPut("{id}")]
36 | public void Put(int id, [FromBody]string value) {
37 | }
38 |
39 | // DELETE api/values/5
40 | [HttpDelete("{id}")]
41 | public string Delete(int id) {
42 | return $"delete employee:{id} success";
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.IdentityServer/User/UserResourceOwnerPasswordValidator.cs:
--------------------------------------------------------------------------------
1 | using IdentityModel;
2 | using IdentityServer4.Validation;
3 | using System.Threading.Tasks;
4 | using System;
5 | using Microsoft.AspNetCore.Authentication;
6 |
7 | namespace Nyw.IdentityServer.User {
8 | public class UserResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator {
9 | private readonly UserStore _users;
10 | private readonly ISystemClock _clock;
11 |
12 | ///
13 | /// Initializes a new instance of the class.
14 | ///
15 | /// The users.
16 | /// The clock.
17 | public UserResourceOwnerPasswordValidator(UserStore users, ISystemClock clock) {
18 | _users = users;
19 | _clock = clock;
20 | }
21 |
22 | ///
23 | /// Validates the resource owner password credential
24 | ///
25 | /// The context.
26 | ///
27 | public Task ValidateAsync(ResourceOwnerPasswordValidationContext context) {
28 | if (_users.ValidateCredentials(context.UserName, context.Password)) {
29 | var user = _users.FindByUsername(context.UserName);
30 | context.Result = new GrantValidationResult(
31 | user.SubjectId ?? throw new ArgumentException("Subject ID not set", nameof(user.SubjectId)),
32 | OidcConstants.AuthenticationMethods.Password, _clock.UtcNow.UtcDateTime,
33 | user.Claims);
34 | }
35 |
36 | return Task.CompletedTask;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/lib/jquery/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright jQuery Foundation and other contributors, https://jquery.org/
2 |
3 | This software consists of voluntary contributions made by many
4 | individuals. For exact contribution history, see the revision history
5 | available at https://github.com/jquery/jquery
6 |
7 | The following license applies to all parts of this software except as
8 | documented below:
9 |
10 | ====
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining
13 | a copy of this software and associated documentation files (the
14 | "Software"), to deal in the Software without restriction, including
15 | without limitation the rights to use, copy, modify, merge, publish,
16 | distribute, sublicense, and/or sell copies of the Software, and to
17 | permit persons to whom the Software is furnished to do so, subject to
18 | the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be
21 | included in all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 |
31 | ====
32 |
33 | All files located in the node_modules and external directories are
34 | externally maintained libraries used by this software which have their
35 | own licenses; we recommend you read them, as their terms may differ from
36 | the terms above.
37 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.IdentityServer/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Configuration;
4 | using Microsoft.Extensions.Logging;
5 | using NLog.Web;
6 | using System;
7 | using System.IO;
8 |
9 | namespace Nyw.IdentityServer {
10 | public class Program {
11 | public static void Main(string[] args) {
12 | var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
13 | try {
14 | logger.Debug("init main");
15 | CreateWebHostBuilder(args).Build().Run();
16 | }
17 | catch (Exception ex) {
18 | logger.Error(ex, "Stopped program because of exception");
19 | throw;
20 | }
21 | finally {
22 | NLog.LogManager.Shutdown();
23 | }
24 | }
25 |
26 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
27 | WebHost.CreateDefaultBuilder(args)
28 | .UseContentRoot(Directory.GetCurrentDirectory())
29 | .ConfigureAppConfiguration((hostingContext, config) => {
30 | config
31 | .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
32 | .AddJsonFile("appsettings.json", true, true)
33 | .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
34 | .AddEnvironmentVariables();
35 | })
36 | .ConfigureLogging(logging => {
37 | logging.ClearProviders();
38 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
39 | })
40 | .UseNLog()
41 | .UseStartup();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.AppExtensions/ConsulExtensions.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using Microsoft.AspNetCore.Builder;
3 | using Microsoft.AspNetCore.Hosting;
4 | using System;
5 |
6 | namespace Nyw.AppExtensions {
7 | public static class ConsulExtensions {
8 | public static IApplicationBuilder RegisterConsulService(this IApplicationBuilder app, IApplicationLifetime lifetime, ConsulServiceOptions options) {
9 | //Action tt = null;
10 |
11 | var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{options.ConsulAddress}:{options.ConsulPort}"));//请求注册的 Consul 地址
12 | // Register service with consul
13 | var registration = new AgentServiceRegistration() {
14 | Checks = new[] {
15 | new AgentServiceCheck() {
16 | DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
17 | Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔,或者称为心跳间隔
18 | HTTP = $"http://{options.Address}:{options.Port}/api/health",//健康检查地址
19 | Timeout = TimeSpan.FromSeconds(5)
20 | } },
21 | ID = Guid.NewGuid().ToString(),
22 | Name = options.Service,
23 | Address = options.Address,
24 | Port = options.Port,
25 | Tags = new[] { $"urlprefix-/{options.Service}" }//添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别
26 | };
27 |
28 | consulClient.Agent.ServiceRegister(registration).Wait();//服务启动时注册,内部实现其实就是使用 Consul API 进行注册(HttpClient发起)
29 | lifetime.ApplicationStopping.Register(() => {
30 | consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服务停止时取消注册
31 | });
32 |
33 | return app;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ApiGateway/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using Microsoft.AspNetCore;
4 | using Microsoft.AspNetCore.Hosting;
5 | using Microsoft.Extensions.Configuration;
6 | using Microsoft.Extensions.Logging;
7 | using NLog.Web;
8 | using Ocelot.DependencyInjection;
9 |
10 | namespace Ocelot.POC {
11 | public class Program {
12 | public static void Main(string[] args) {
13 | var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
14 | try {
15 | logger.Debug("init main");
16 | CreateWebHostBuilder(args).Build().Run();
17 | }
18 | catch (Exception ex) {
19 | logger.Error(ex, "Stopped program because of exception");
20 | throw;
21 | }
22 | finally {
23 | // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
24 | NLog.LogManager.Shutdown();
25 | }
26 | }
27 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
28 | WebHost.CreateDefaultBuilder(args)
29 | .UseContentRoot(Directory.GetCurrentDirectory())
30 | .ConfigureAppConfiguration((hostingContext, config) => {
31 | config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
32 | .AddJsonFile("appsettings.json", true, true)
33 | .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
34 | //.AddJsonFile("ocelot.json")
35 | .AddOcelot(hostingContext.HostingEnvironment)
36 | .AddEnvironmentVariables();
37 | })
38 | .ConfigureLogging(logging => {
39 | logging.ClearProviders();
40 | logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
41 | })
42 | .UseNLog()
43 | .UseStartup();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ApiGateway/ocelot.route.json:
--------------------------------------------------------------------------------
1 | {
2 | "ReRoutes": [
3 | {
4 | "DownstreamPathTemplate": "/api/values/{id}",
5 | "DownstreamScheme": "http",
6 | "ServiceName": "vendor",
7 | "UseServiceDiscovery": true,
8 | "LoadBalancerOptions": {
9 | "Type": "LeastConnection",
10 | "Key": null,
11 | "Expiry": 0
12 | },
13 | "UpstreamPathTemplate": "/vendor/{id}",
14 | "UpstreamHttpMethod": [ "Get", "Delete" ],
15 | /*Quality of Service*/
16 | "QoSOptions": {
17 | "ExceptionsAllowedBeforeBreaking": 3,
18 | "DurationOfBreak": 10,
19 | "TimeoutValue": 5000 /*毫秒*/
20 | },
21 | "RateLimitOptions": {
22 | "ClientWhitelist": [], /*the client in this array will not be affected by the rate limiting*/
23 | "EnableRateLimiting": false,
24 | "Period": "1s", /*This value specifies the period, such as 1s, 5m, 1h,1d and so on. */
25 | "PeriodTimespan": 1.0, /* This value specifies that we can retry after a certain number of seconds*/
26 | "Limit": 10 /*This value specifies the maximum number of requests that a client can make in a defined period*/
27 | },
28 | "HttpHandlerOptions": {
29 | "AllowAutoRedirect": false,
30 | "UseCookieContainer": false,
31 | "UseTracing": false,
32 | "UseProxy": true
33 | }
34 | },
35 | {
36 | "DownstreamPathTemplate": "/api/values/{id}",
37 | "DownstreamScheme": "http",
38 | "ServiceName": "employee",
39 | "UseServiceDiscovery": true,
40 | "LoadBalancerOptions": {
41 | "Type": "LeastConnection",
42 | "Key": null,
43 | "Expiry": 0
44 | },
45 | "UpstreamPathTemplate": "/employee/{id}",
46 | "UpstreamHttpMethod": [ "Get", "Delete" ],
47 | "QoSOptions": {
48 | "ExceptionsAllowedBeforeBreaking": 3,
49 | "DurationOfBreak": 10,
50 | "TimeoutValue": 5000
51 | },
52 | "HttpHandlerOptions": {
53 | "AllowAutoRedirect": false,
54 | "UseCookieContainer": false,
55 | "UseTracing": false,
56 | "UseProxy": true
57 | }
58 | }
59 | ]
60 | }
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Vendor/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Logging;
10 | using Serilog;
11 | using Serilog.Events;
12 | using Serilog.Sinks.Elasticsearch;
13 |
14 | namespace Nyw.VendorService {
15 | public class Program {
16 | public static void Main(string[] args) {
17 | Log.Logger = new LoggerConfiguration()
18 | .MinimumLevel.Debug()
19 | .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
20 | .Enrich.FromLogContext()
21 | .WriteTo.Console()
22 | .WriteTo.File("logs\\log.txt", rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true)
23 | .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200")) {
24 | AutoRegisterTemplate = true,
25 | AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv6,
26 | FailureCallback = e => Console.WriteLine("Unable to submit event " + e.MessageTemplate),
27 | EmitEventFailure = EmitEventFailureHandling.WriteToSelfLog |
28 | EmitEventFailureHandling.WriteToFailureSink |
29 | EmitEventFailureHandling.RaiseCallback
30 | })
31 | .CreateLogger();
32 |
33 | try {
34 | Log.Information("Starting web host");
35 | CreateWebHostBuilder(args).Build().Run();
36 | }
37 | catch (Exception ex) {
38 | Log.Fatal(ex, "Host terminated unexpectedly");
39 | }
40 | finally {
41 | Log.CloseAndFlush();
42 | }
43 | }
44 |
45 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
46 | WebHost.CreateDefaultBuilder(args)
47 | .ConfigureAppConfiguration(Startup.ConfigureAppConfiguration)
48 | .UseStartup()
49 | .UseSerilog();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ApiGateway/Controllers/RerouteController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using Microsoft.AspNetCore.Authorization;
4 | using Microsoft.AspNetCore.Mvc;
5 | using Microsoft.Extensions.Logging;
6 | using Ocelot.Configuration.File;
7 | using Ocelot.Configuration.Repository;
8 | using Ocelot.Configuration.Setter;
9 |
10 | namespace NSB.ApiManagement.ApiMgtService.Controllers {
11 | [Route("admin/[controller]")]
12 | [ApiController]
13 | [Authorize]
14 | public class RerouteController : ControllerBase {
15 | private readonly IFileConfigurationRepository _repo;
16 | private readonly IFileConfigurationSetter _setter;
17 | private readonly IServiceProvider _provider;
18 | private readonly ILogger _logger;
19 | public RerouteController(IFileConfigurationRepository repo, IFileConfigurationSetter setter, IServiceProvider provider, ILogger logger) {
20 | _repo = repo;
21 | _setter = setter;
22 | _provider = provider;
23 | _logger = logger;
24 | }
25 | //读取所有ReRoutes
26 | [HttpGet]
27 | public async Task Get() {
28 | _logger.LogInformation("get demo log");
29 | //对ReRoute对象操作是对FileConfiguration.ReRoutes属性的操作
30 | var response = await _repo.Get();
31 | if (response.IsError) {
32 | return new BadRequestObjectResult(response.Errors);
33 | }
34 | return new OkObjectResult(response.Data.ReRoutes);
35 | }
36 | //更新某一个ReRoute
37 | [HttpPost]
38 | public async Task Post([FromBody]FileReRoute fileReRoute) {
39 | try {
40 | var fileConfiguration= _repo.Get().Result.Data;
41 | //根据FileReRoute.Key找到要更新的FileReRoute
42 | //更新FileReRoute
43 |
44 | var response = await _setter.Set(fileConfiguration);
45 |
46 | if (response.IsError) {
47 | return new BadRequestObjectResult(response.Errors);
48 | }
49 |
50 | return new OkObjectResult(fileReRoute);
51 | }
52 | catch (Exception e) {
53 | return new BadRequestObjectResult($"{e.Message}:{e.StackTrace}");
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ExchangeRateTask/Program.cs:
--------------------------------------------------------------------------------
1 | using Quartz;
2 | using Quartz.Impl;
3 | using Serilog;
4 | using System;
5 | using System.Collections.Specialized;
6 | using System.Threading.Tasks;
7 |
8 | namespace Nyw.ExchangeRateTask {
9 | class Program {
10 | static void Main(string[] args) {
11 |
12 | Log.Logger = new LoggerConfiguration()
13 | .MinimumLevel.Debug()
14 | .WriteTo.Console()
15 | .WriteTo.File("logs\\log.txt", rollingInterval: RollingInterval.Day)
16 | .CreateLogger();
17 |
18 | Log.Information("Hello, world!");
19 |
20 | RunTask().GetAwaiter().GetResult();
21 |
22 | Console.WriteLine("Press any key to close the application");
23 | Console.ReadKey();
24 | }
25 | private static async Task RunTask() {
26 | try {
27 | //NameValueCollection props = new NameValueCollection {
28 | // { "quartz.serializer.type", "binary" }
29 | //};
30 | //StdSchedulerFactory factory = new StdSchedulerFactory(props);
31 | //IScheduler scheduler = await factory.GetScheduler();
32 |
33 | IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler();
34 | await scheduler.Start();
35 |
36 | IJobDetail jobDetail = JobBuilder.Create()
37 | .WithIdentity("helloJob1","group1")
38 | .Build();
39 | ITrigger trigger = TriggerBuilder.Create()
40 | .WithIdentity("trigger1", "group1")
41 | .StartNow()
42 | .WithSimpleSchedule(x => x
43 | .WithIntervalInSeconds(10)
44 | .WithRepeatCount(5)
45 | //.RepeatForever()
46 | )
47 | .Build();
48 |
49 | await scheduler.ScheduleJob(jobDetail,trigger);
50 |
51 | await Task.Delay(TimeSpan.FromSeconds(60));
52 | await scheduler.Shutdown();
53 | }
54 | catch (SchedulerException sex) {
55 | await Console.Error.WriteLineAsync(sex.ToString());
56 | }
57 | catch (Exception ex) {
58 | await Console.Error.WriteLineAsync(ex.ToString());
59 | }
60 | }
61 | }
62 | public class HelloJob : IJob {
63 | public async Task Execute(IJobExecutionContext context) {
64 | await Console.Out.WriteLineAsync("Greetings from Hello Job.");
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.IdentityServer/User/UserProfileService.cs:
--------------------------------------------------------------------------------
1 | using IdentityServer4.Extensions;
2 | using IdentityServer4.Models;
3 | using IdentityServer4.Services;
4 | using Microsoft.Extensions.Logging;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 |
9 | namespace Nyw.IdentityServer.User {
10 | public class UserProfileService : IProfileService {
11 | ///
12 | /// The logger
13 | ///
14 | protected readonly ILogger Logger;
15 |
16 | ///
17 | /// The users
18 | ///
19 | protected readonly UserStore Users;
20 |
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | /// The users.
25 | /// The logger.
26 | public UserProfileService(UserStore users, ILogger logger) {
27 | Users = users;
28 | Logger = logger;
29 | }
30 |
31 | ///
32 | /// This method is called whenever claims about the user are requested (e.g. during token creation or via the userinfo endpoint)
33 | ///
34 | /// The context.
35 | ///
36 | public virtual Task GetProfileDataAsync(ProfileDataRequestContext context) {
37 | context.LogProfileRequest(Logger);
38 |
39 | if (context.RequestedClaimTypes.Any()) {
40 | var user = Users.FindBySubjectId(context.Subject.GetSubjectId());
41 | if (user != null) {
42 | context.AddRequestedClaims(user.Claims);
43 | }
44 | }
45 |
46 | context.LogIssuedClaims(Logger);
47 |
48 | return Task.CompletedTask;
49 | }
50 |
51 | ///
52 | /// This method gets called whenever identity server needs to determine if the user is valid or active (e.g. if the user's account has been deactivated since they logged in).
53 | /// (e.g. during token issuance or validation).
54 | ///
55 | /// The context.
56 | ///
57 | public virtual Task IsActiveAsync(IsActiveContext context) {
58 | Logger.LogDebug("IsActive called from: {caller}", context.Caller);
59 |
60 | var user = Users.FindBySubjectId(context.Subject.GetSubjectId());
61 | context.IsActive = user?.IsActive == true;
62 |
63 | return Task.CompletedTask;
64 | }
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.ApiGateway/ocelot.json:
--------------------------------------------------------------------------------
1 | {"ReRoutes":[{"DownstreamPathTemplate":"/api/values/{id}","UpstreamPathTemplate":"/vendor/{id}","UpstreamHttpMethod":["Get","Delete"],"AddHeadersToRequest":{},"UpstreamHeaderTransform":{},"DownstreamHeaderTransform":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0,"Region":null},"ReRouteIsCaseSensitive":false,"ServiceName":"vendor","DownstreamScheme":"http","QoSOptions":{"ExceptionsAllowedBeforeBreaking":3,"DurationOfBreak":10,"TimeoutValue":5000},"LoadBalancerOptions":{"Type":"LeastConnection","Key":null,"Expiry":0},"RateLimitOptions":{"ClientWhitelist":[],"EnableRateLimiting":false,"Period":"1s","PeriodTimespan":1.0,"Limit":10},"AuthenticationOptions":{"AuthenticationProviderKey":null,"AllowedScopes":[]},"HttpHandlerOptions":{"AllowAutoRedirect":false,"UseCookieContainer":false,"UseTracing":false,"UseProxy":true},"UseServiceDiscovery":true,"DownstreamHostAndPorts":[],"UpstreamHost":null,"Key":null,"DelegatingHandlers":[],"Priority":1,"Timeout":0,"DangerousAcceptAnyServerCertificateValidator":false},{"DownstreamPathTemplate":"/api/values/{id}","UpstreamPathTemplate":"/employee/{id}","UpstreamHttpMethod":["Get","Delete"],"AddHeadersToRequest":{},"UpstreamHeaderTransform":{},"DownstreamHeaderTransform":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0,"Region":null},"ReRouteIsCaseSensitive":false,"ServiceName":"employee","DownstreamScheme":"http","QoSOptions":{"ExceptionsAllowedBeforeBreaking":3,"DurationOfBreak":10,"TimeoutValue":5000},"LoadBalancerOptions":{"Type":"LeastConnection","Key":null,"Expiry":0},"RateLimitOptions":{"ClientWhitelist":[],"EnableRateLimiting":false,"Period":null,"PeriodTimespan":0.0,"Limit":0},"AuthenticationOptions":{"AuthenticationProviderKey":null,"AllowedScopes":[]},"HttpHandlerOptions":{"AllowAutoRedirect":false,"UseCookieContainer":false,"UseTracing":false,"UseProxy":true},"UseServiceDiscovery":true,"DownstreamHostAndPorts":[],"UpstreamHost":null,"Key":null,"DelegatingHandlers":[],"Priority":1,"Timeout":0,"DangerousAcceptAnyServerCertificateValidator":false}],"Aggregates":[],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Host":"localhost","Port":8500,"Type":null,"Token":null,"ConfigurationKey":"Nyw.Oceolot","PollingInterval":0},"RateLimitOptions":{"ClientIdHeader":"ClientId","QuotaExceededMessage":"Exceeded access quota limit","RateLimitCounterPrefix":"ocelot","DisableRateLimitHeaders":false,"HttpStatusCode":429},"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"BaseUrl":null,"LoadBalancerOptions":{"Type":null,"Key":null,"Expiry":0},"DownstreamScheme":null,"HttpHandlerOptions":{"AllowAutoRedirect":false,"UseCookieContainer":false,"UseTracing":false,"UseProxy":true}}}
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Vendor/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Logging;
11 | using Microsoft.Extensions.Options;
12 | using Winton.Extensions.Configuration.Consul;
13 | using Nyw.AppExtensions;
14 |
15 | namespace Nyw.VendorService {
16 | public class Startup {
17 | public Startup(IConfiguration configuration, IHostingEnvironment env) {
18 | HostingEnvironment = env;
19 | Configuration = configuration;
20 | }
21 |
22 | public IConfiguration Configuration { get; }
23 | public IHostingEnvironment HostingEnvironment { get; }
24 |
25 | // This method gets called by the runtime. Use this method to add services to the container.
26 | public void ConfigureServices(IServiceCollection services) {
27 | services.AddMvc();
28 | }
29 |
30 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
31 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime) {
32 | if (env.IsDevelopment()) {
33 | app.UseDeveloperExceptionPage();
34 | }
35 |
36 | app.RegisterConsulService(appLifetime, new ConsulServiceOptions {
37 | Address = "localhost",
38 | ConsulAddress = "localhost",
39 | ConsulPort = 8500,
40 | Port = Convert.ToInt32(Configuration["ServicePort"]),
41 | Service = "vendor"
42 | });
43 |
44 | appLifetime.ApplicationStopping.Register(cancellationTokenSource.Cancel);
45 | app.UseMvc();
46 | }
47 | private static CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
48 | public static void ConfigureAppConfiguration(WebHostBuilderContext hostingContext, IConfigurationBuilder builder) {
49 | var env = hostingContext.HostingEnvironment;
50 | builder
51 | .AddConsul($"{env.ApplicationName}.{env.EnvironmentName}",
52 | cancellationTokenSource.Token,
53 | options => {
54 | options.ConsulConfigurationOptions =
55 | cco => {
56 | cco.Address = new Uri("http://localhost:8500");
57 | cco.Datacenter = "dc1";
58 | };
59 | options.Optional = true;
60 | options.ReloadOnChange = true;
61 | options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; };
62 | })
63 | .AddEnvironmentVariables();
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Employee/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Logging;
11 | using Microsoft.Extensions.Options;
12 | using Nyw.AppExtensions;
13 | using Winton.Extensions.Configuration.Consul;
14 |
15 | namespace Nyw.EmployeeServices {
16 | public class Startup {
17 | public Startup(IConfiguration configuration, IHostingEnvironment env) {
18 | HostingEnvironment = env;
19 | Configuration = configuration;
20 | }
21 |
22 | public IConfiguration Configuration { get; }
23 | public IHostingEnvironment HostingEnvironment { get; }
24 |
25 | // This method gets called by the runtime. Use this method to add services to the container.
26 | public void ConfigureServices(IServiceCollection services) {
27 | services.AddMvc();
28 | }
29 |
30 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
31 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime) {
32 | if (env.IsDevelopment()) {
33 | app.UseDeveloperExceptionPage();
34 | }
35 |
36 | app.RegisterConsulService(appLifetime, new ConsulServiceOptions {
37 | Address = "localhost",
38 | ConsulAddress = "localhost",
39 | ConsulPort = 8500,
40 | Port = Convert.ToInt32(Configuration["ServicePort"]),
41 | Service = "employee"
42 | });
43 |
44 | appLifetime.ApplicationStopping.Register(cancellationTokenSource.Cancel);
45 | app.UseMvc();
46 | }
47 | private static CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
48 | public static void ConfigureAppConfiguration(WebHostBuilderContext hostingContext, IConfigurationBuilder builder) {
49 | var env = hostingContext.HostingEnvironment;
50 | builder
51 | .AddConsul($"{env.ApplicationName}.{env.EnvironmentName}",
52 | cancellationTokenSource.Token,
53 | options => {
54 | options.ConsulConfigurationOptions =
55 | cco => {
56 | cco.Address = new Uri("http://localhost:8500");
57 | cco.Datacenter = "dc1";
58 | };
59 | options.Optional = true;
60 | options.ReloadOnChange = true;
61 | options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; };
62 | })
63 | .AddEnvironmentVariables();
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/README.zh-CN.md:
--------------------------------------------------------------------------------
1 | [英文](README.md) | 中文
2 | # 蜂巢
3 |
4 | ## 环境说明
5 | - Visual Studio 2017
6 | - .NET Core 2.0
7 | - Windows 10 v1803
8 | - Docker Version 18.03.1-ce-win65
9 |
10 | ## 相关开源项目
11 | - [Ocelot](https://github.com/ThreeMammals/Ocelot)
12 | - [Consul](https://github.com/hashicorp/consul)
13 | - [Winton.Extensions.Configuration.Consul](https://github.com/wintoncode/Winton.Extensions.Configuration.Consul)
14 | - [安装](/Env/Consul/README.md)
15 | - [IdentityServer4](https://github.com/IdentityServer/IdentityServer4)
16 | - [IdentityServer4.EntityFramework](https://github.com/IdentityServer/IdentityServer4.EntityFramework)
17 | - [Serilog](https://github.com/serilog)
18 | - [Serilog.Serilog](https://github.com/serilog/serilog)
19 | - [Serilog-aspnetcore](https://github.com/serilog/serilog-aspnetcore)
20 | - [serilog-sinks-file](https://github.com/serilog/serilog-sinks-file)
21 | - [serilog-sinks-console](https://github.com/serilog/serilog-sinks-console)
22 | - [serilog-sinks-elasticsearch](https://github.com/serilog/serilog-sinks-elasticsearch)
23 | - [ELK](https://github.com/elastic/)
24 | - [elasticsearch](https://github.com/elastic/elasticsearch)
25 | - [logstash](https://github.com/elastic/logstash)
26 | - [kibana](https://github.com/elastic/kibana)
27 | - [安装](/Env/ELK/README.md)
28 | - [Quartz.NET](https://github.com/quartznet/quartznet)
29 | - [Documents](https://www.quartz-scheduler.net/documentation/index.html)
30 | - [skywalking](https://github.com/apache/incubator-skywalking)
31 | - [Client:dotnetcore](https://github.com/OpenSkywalking/skywalking-netcore)
32 | - [Redis](https://github.com/antirez/redis)
33 | - [StackExchange.Redis](https://github.com/StackExchange/StackExchange.Redis/)
34 | - [安装](/Env/Redis/README.md)
35 | - [Sonarqube](/DevOps/Sonarqube/README.md)
36 | - [Jenkins](/DevOps/Jenkins/README.md)
37 |
38 | ## 项目说明
39 | - Nyw.ApiGateway:基于Ocelot构建的ApiGateway,配置从Consul获取
40 | - Nyw.Employee:测试项目
41 | - Consul作为配置源
42 | - 启动时向Consul注册自己
43 | - Nyw.Vendor:测试项目
44 | - Consul作为配置源
45 | - 启动时向Consul注册自己
46 | - 使用serilog,日志输出到Console, File, Elasticsearch
47 | - Nyw.AppExtensions:扩展项目
48 | - Consul扩展,实现项目启动时自动向Consul注册服务
49 | - Nyw.IdentityServer:认证服务项目
50 | - 使用IdentityServer4.EntityFramework保存数据到数据库中
51 | - 使用自定义用户模型
52 | - Nyw.ExchangeRateTask:定期查询汇率任务(计划任务)
53 | - 控制台程序使用Serilog记录日志
54 | - 使用Quartz.NET构建计划任务
55 | - Quartz.NET和Serilog协同工作
56 | - Nyw.Portal:定义门户,计划用于调用API
57 | - 添加skywalking netcore
58 | - 添加Redis缓存
59 | - Nyw.Configuration.SqlServer: 数据库配置提供程序中间件
60 | - 将SQL Server作为IConfiguration的配置提供程序,能够从数据库读取配置
61 |
62 | ## 已验证功能
63 | - Ocelot:
64 | 1. 路由
65 | 1. 服务质量
66 | 1. 使用限制
67 | 1. 服务发现,使用consul
68 | 1. 添加网关管理API框架
69 | 1. 添加Nlog支持
70 | - Consul
71 | 1. K/V存储
72 | 1. Dotnetcore 配置提供程序
73 | 1. 服务注册
74 | 1. 健康检查
75 | - IdentityServer:
76 | 1. 使用IdentityServer4.EntityFramework存储数据到数据库
77 | 1. 自定义用户模型
78 | - Serilog:
79 | 1. ASP.NET Core 2.x使用Serilog记录日志
80 | 1. 输出日志到控制台
81 | 1. 输出日志到文件
82 | 1. 输出日志到Elasticsearch
83 | - ELK:
84 | 1. 使用ELK Docker Compose快速构建环境
85 | 1. 输出日志到Elk
86 | 1. 创建基本索引和查询
87 | - Quartz.NET:
88 | 1. 构建简单的计划任务,重复有限次数和无限次重复
89 | 1. 和Serilog协同工作
90 | 1. 使用控制台运行
91 | - Skywalking
92 | 1. ASP.NET Core 的APM和应用程序拓扑图
93 | - Redis
94 | 1. 基本操作:连接,添加字符串,读取字符串
95 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/Views/Shared/_Layout.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @ViewData["Title"] - Nyw.Portal
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
41 |
42 | @RenderBody()
43 |
44 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
61 |
67 |
68 |
69 |
70 | @RenderSection("Scripts", required: false)
71 |
72 |
73 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 英文 | [中文](README.zh-CN.md)
2 | # honeycomb
3 |
4 | ## Requirements
5 | - Visual Studio 2017
6 | - .NET Core 2.0/2.1
7 | - Windows 10 v1803
8 | - Docker Version 18.03.1-ce-win65
9 |
10 | ## Open Source Projects
11 | - [Ocelot](https://github.com/ThreeMammals/Ocelot)
12 | - [Consul](https://github.com/hashicorp/consul)
13 | - [Winton.Extensions.Configuration.Consul](https://github.com/wintoncode/Winton.Extensions.Configuration.Consul)
14 | - [Setup](/Env/Consul/README.md)
15 | - [IdentityServer4](https://github.com/IdentityServer/IdentityServer4)
16 | - [IdentityServer4.EntityFramework](https://github.com/IdentityServer/IdentityServer4.EntityFramework)
17 | - [Serilog](https://github.com/serilog)
18 | - [Serilog.Serilog](https://github.com/serilog/serilog)
19 | - [Serilog-aspnetcore](https://github.com/serilog/serilog-aspnetcore)
20 | - [serilog-sinks-file](https://github.com/serilog/serilog-sinks-file)
21 | - [serilog-sinks-console](https://github.com/serilog/serilog-sinks-console)
22 | - [serilog-sinks-elasticsearch](https://github.com/serilog/serilog-sinks-elasticsearch)
23 | - [ELK](https://github.com/elastic/)
24 | - [elasticsearch](https://github.com/elastic/elasticsearch)
25 | - [logstash](https://github.com/elastic/logstash)
26 | - [kibana](https://github.com/elastic/kibana)
27 | - [Setup](/Env/ELK/README.md)
28 | - [Quartz.NET](https://github.com/quartznet/quartznet)
29 | - [Documents](https://www.quartz-scheduler.net/documentation/index.html)
30 | - [skywalking](https://github.com/apache/incubator-skywalking)
31 | - [Client:dotnetcore](https://github.com/OpenSkywalking/skywalking-netcore)
32 | - [Redis](https://github.com/antirez/redis)
33 | - [StackExchange.Redis](https://github.com/StackExchange/StackExchange.Redis/)
34 | - [Setup](/Env/Redis/README.md)
35 | - [Sonarqube](/DevOps/Sonarqube/README.md)
36 | - [Jenkins](/DevOps/Jenkins/README.md)
37 |
38 | ## Projects Illustrate
39 | - Nyw.ApiGateway:
40 | - ApiGatewat service, base **Ocelot** and load configuration from **Consul**
41 | - Nyw.Employee:Web API Test Project
42 | - Consul as configuration source provider
43 | - Register itself to consul as a service when lunch
44 | - Nyw.Vendor:Web API Test Project
45 | - Consul as configuration source provider
46 | - Register itself to consul as a service when lunch
47 | - Using serilog,write log to Console, File, Elasticsearch
48 | - Nyw.AppExtensions:Class Library
49 | - .et core middlerware, Consul extension,the app could registry itself to Consul when lunch
50 | - Nyw.IdentityServer:Web API Project for IdentityServer
51 | - Persisent data to sqlserver using IdentityServer4.EntityFramework
52 | - Using customize user model
53 | - Nyw.ExchangeRateTask:Console app as Schedule Task, mock to query Exchange Rage Schdulely
54 | - Use serilog to output log
55 | - Build simple schedule task using Quartz.NET
56 | - Quartz.NET work with Serilog
57 | - Nyw.Portal:Customzie USer Protal, plan to consum API
58 | - add skywalking netcore
59 | - add redis cache
60 | - Nyw.Configuration.SqlServer: IConfiguration SQL Server Provider Middlerware
61 | - Use SQL Server as IConfigguration Provider, it can load appsettings from sqlserver now
62 |
63 | ## Proofed Functions
64 | - Ocelot:
65 | 1. Rounting
66 | 1. Quality of Service
67 | 1. Rate Limiting
68 | 1. Service Discovery, work with consul
69 | 1. Add ApiGateway Admin API craft
70 | 1. Add nlog support;
71 | - Consul
72 | 1. Key/Value
73 | 1. Dotnetcore Configuration Provider
74 | 1. Service Registry
75 | 1. Health Check
76 | - IdentityServer:
77 | 1. IdentityServer4.EntityFramework
78 | 1. Customize User Model
79 | - Serilog:
80 | 1. ASP.NET Core 2.x log using Serilog
81 | 1. Output log to console
82 | 1. Output log to file
83 | 1. Output log to Elasticsearch
84 | - ELK:
85 | 1. ELK Docker Compose build quickly
86 | 1. Write log to Elk
87 | 1. Basicly create index and search
88 | - Quartz.NET:
89 | 1. Simple Schedule with Repeat Count or Forever
90 | 1. Work with Serilog
91 | 1. Console host
92 | - Skywalking
93 | 1. Basicly .net core apm and application topology map
94 | - Redis
95 | 1. Basic Usage:connect, add string, read string
96 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.IdentityServer/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.AspNetCore.Http;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.EntityFrameworkCore;
6 | using System.Reflection;
7 | using Microsoft.Extensions.Configuration;
8 | using IdentityServer4.EntityFramework.DbContexts;
9 | using IdentityServer4.Models;
10 | using IdentityServer4.EntityFramework.Mappers;
11 | using System.Linq;
12 |
13 | namespace Nyw.IdentityServer {
14 | public class Startup {
15 | public Startup(IConfiguration configuration) {
16 | Configuration = configuration;
17 | }
18 |
19 | public IConfiguration Configuration { get; }
20 | // This method gets called by the runtime. Use this method to add services to the container.
21 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
22 | public void ConfigureServices(IServiceCollection services) {
23 | ConfigureIdentityServerServices(services);
24 | services.AddMvc();
25 | }
26 |
27 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
28 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
29 | if (env.IsDevelopment()) {
30 | app.UseDeveloperExceptionPage();
31 | InitializeIdentityServerDatabase(app);
32 | }
33 | app.UseMvc();
34 | }
35 | private void ConfigureIdentityServerServices(IServiceCollection services) {
36 | var idpDbConnStr = Configuration.GetConnectionString("IdpDbConnStr");
37 | var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
38 | services.AddIdentityServer()
39 | .AddDeveloperSigningCredential()
40 | .AddUserModel()
41 | .AddConfigurationStore(options => {
42 | options.ConfigureDbContext = builder =>
43 | builder.UseSqlServer(idpDbConnStr,
44 | sql => sql.MigrationsAssembly(migrationsAssembly));
45 | })
46 | .AddOperationalStore(options => {
47 | options.ConfigureDbContext = builder =>
48 | builder.UseSqlServer(idpDbConnStr,
49 | sql => sql.MigrationsAssembly(migrationsAssembly));
50 | options.EnableTokenCleanup = true;
51 | options.TokenCleanupInterval = 30;
52 | });
53 |
54 | }
55 | private void InitializeIdentityServerDatabase(IApplicationBuilder app) {
56 | using (var serviceScope = app.ApplicationServices.GetService().CreateScope()) {
57 | serviceScope.ServiceProvider.GetRequiredService().Database.Migrate();
58 | var context = serviceScope.ServiceProvider.GetRequiredService();
59 | context.Database.Migrate();
60 | if (!context.Clients.Any()) {
61 | var client1 = new IdentityServer4.Models.Client {
62 | ClientId = "demo.client1",
63 | AllowedGrantTypes = GrantTypes.ClientCredentials,
64 | ClientSecrets = {
65 | new IdentityServer4.Models.Secret("secret".Sha256())
66 | },
67 | AllowedScopes = { "demo.api1" },
68 | ClientName = "Demo Client1"
69 | };
70 | context.Clients.Add(client1.ToEntity());
71 | context.SaveChanges();
72 | }
73 |
74 | if (!context.ApiResources.Any()) {
75 | var api1 = new IdentityServer4.Models.ApiResource {
76 | Name = "demo.api1",
77 | DisplayName = "demo api",
78 | Description = "this is just for demo"
79 | };
80 | context.ApiResources.Add(api1.ToEntity());
81 | context.SaveChanges();
82 | }
83 | }
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | ** Unobtrusive validation support library for jQuery and jQuery Validate
3 | ** Copyright (C) Microsoft Corporation. All rights reserved.
4 | */
5 | !function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function m(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=p.unobtrusive.options||{},m=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),m("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),m("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),m("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var u,p=a.validator,v="unobtrusiveValidation";p.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=m(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){p.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=m(this);a&&a.attachValidation()})}},u=p.unobtrusive.adapters,u.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},u.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},u.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},u.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},p.addMethod("__dummy__",function(a,e,n){return!0}),p.addMethod("regex",function(a,e,n){var t;return this.optional(e)?!0:(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),p.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),p.methods.extension?(u.addSingleVal("accept","mimtype"),u.addSingleVal("extension","extension")):u.addSingleVal("extension","extension","accept"),u.addSingleVal("regex","pattern"),u.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),u.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),u.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),u.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),u.add("required",function(a){("INPUT"!==a.element.tagName.toUpperCase()||"CHECKBOX"!==a.element.type.toUpperCase())&&e(a,"required",!0)}),u.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),u.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),a(function(){p.unobtrusive.parse(document)})}(jQuery);
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Microservice.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27703.2000
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nyw.ApiGateway", "Nyw.ApiGateway\Nyw.ApiGateway.csproj", "{3DF9D910-5A2D-4038-91E8-E136C56E6918}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nyw.Vendor", "Nyw.Vendor\Nyw.Vendor.csproj", "{4E0CBE39-3A13-421D-A605-56C46610883B}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nyw.Employee", "Nyw.Employee\Nyw.Employee.csproj", "{CC65BB47-20FD-4B4F-8B2E-39438381084B}"
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02.Apps", "02.Apps", "{320A36EE-8052-433D-B007-9DE3A2C439BF}"
13 | EndProject
14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01.Common", "01.Common", "{90E9C700-3C64-4F15-9406-F31BAC440D8B}"
15 | EndProject
16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nyw.AppExtensions", "Nyw.AppExtensions\Nyw.AppExtensions.csproj", "{F07B5EB9-5FC0-4969-8F69-3B19186EC9D0}"
17 | EndProject
18 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00.Services", "00.Services", "{F1422284-13A6-4C40-89B3-3558D7AD042C}"
19 | EndProject
20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nyw.IdentityServer", "Nyw.IdentityServer\Nyw.IdentityServer.csproj", "{41D909B7-8319-4261-85B9-78DC79376C9E}"
21 | EndProject
22 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "03.Tasks", "03.Tasks", "{6823DB3A-7A63-48CF-91C4-5B42DEAE19F8}"
23 | EndProject
24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nyw.ExchangeRateTask", "Nyw.ExchangeRateTask\Nyw.ExchangeRateTask.csproj", "{ABF99209-048D-417F-A6C0-AD7F1E4BA46A}"
25 | EndProject
26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nyw.Portal", "Nyw.Portal\Nyw.Portal.csproj", "{CAB44AD9-7A47-4AFC-BBB2-84085AC27BEE}"
27 | EndProject
28 | Global
29 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
30 | Debug|Any CPU = Debug|Any CPU
31 | Release|Any CPU = Release|Any CPU
32 | EndGlobalSection
33 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
34 | {3DF9D910-5A2D-4038-91E8-E136C56E6918}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 | {3DF9D910-5A2D-4038-91E8-E136C56E6918}.Debug|Any CPU.Build.0 = Debug|Any CPU
36 | {3DF9D910-5A2D-4038-91E8-E136C56E6918}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {3DF9D910-5A2D-4038-91E8-E136C56E6918}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {4E0CBE39-3A13-421D-A605-56C46610883B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {4E0CBE39-3A13-421D-A605-56C46610883B}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {4E0CBE39-3A13-421D-A605-56C46610883B}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {4E0CBE39-3A13-421D-A605-56C46610883B}.Release|Any CPU.Build.0 = Release|Any CPU
42 | {CC65BB47-20FD-4B4F-8B2E-39438381084B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43 | {CC65BB47-20FD-4B4F-8B2E-39438381084B}.Debug|Any CPU.Build.0 = Debug|Any CPU
44 | {CC65BB47-20FD-4B4F-8B2E-39438381084B}.Release|Any CPU.ActiveCfg = Release|Any CPU
45 | {CC65BB47-20FD-4B4F-8B2E-39438381084B}.Release|Any CPU.Build.0 = Release|Any CPU
46 | {F07B5EB9-5FC0-4969-8F69-3B19186EC9D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47 | {F07B5EB9-5FC0-4969-8F69-3B19186EC9D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
48 | {F07B5EB9-5FC0-4969-8F69-3B19186EC9D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
49 | {F07B5EB9-5FC0-4969-8F69-3B19186EC9D0}.Release|Any CPU.Build.0 = Release|Any CPU
50 | {41D909B7-8319-4261-85B9-78DC79376C9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51 | {41D909B7-8319-4261-85B9-78DC79376C9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
52 | {41D909B7-8319-4261-85B9-78DC79376C9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
53 | {41D909B7-8319-4261-85B9-78DC79376C9E}.Release|Any CPU.Build.0 = Release|Any CPU
54 | {ABF99209-048D-417F-A6C0-AD7F1E4BA46A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
55 | {ABF99209-048D-417F-A6C0-AD7F1E4BA46A}.Debug|Any CPU.Build.0 = Debug|Any CPU
56 | {ABF99209-048D-417F-A6C0-AD7F1E4BA46A}.Release|Any CPU.ActiveCfg = Release|Any CPU
57 | {ABF99209-048D-417F-A6C0-AD7F1E4BA46A}.Release|Any CPU.Build.0 = Release|Any CPU
58 | {CAB44AD9-7A47-4AFC-BBB2-84085AC27BEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
59 | {CAB44AD9-7A47-4AFC-BBB2-84085AC27BEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
60 | {CAB44AD9-7A47-4AFC-BBB2-84085AC27BEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
61 | {CAB44AD9-7A47-4AFC-BBB2-84085AC27BEE}.Release|Any CPU.Build.0 = Release|Any CPU
62 | EndGlobalSection
63 | GlobalSection(SolutionProperties) = preSolution
64 | HideSolutionNode = FALSE
65 | EndGlobalSection
66 | GlobalSection(NestedProjects) = preSolution
67 | {3DF9D910-5A2D-4038-91E8-E136C56E6918} = {F1422284-13A6-4C40-89B3-3558D7AD042C}
68 | {4E0CBE39-3A13-421D-A605-56C46610883B} = {320A36EE-8052-433D-B007-9DE3A2C439BF}
69 | {CC65BB47-20FD-4B4F-8B2E-39438381084B} = {320A36EE-8052-433D-B007-9DE3A2C439BF}
70 | {F07B5EB9-5FC0-4969-8F69-3B19186EC9D0} = {90E9C700-3C64-4F15-9406-F31BAC440D8B}
71 | {41D909B7-8319-4261-85B9-78DC79376C9E} = {F1422284-13A6-4C40-89B3-3558D7AD042C}
72 | {ABF99209-048D-417F-A6C0-AD7F1E4BA46A} = {6823DB3A-7A63-48CF-91C4-5B42DEAE19F8}
73 | {CAB44AD9-7A47-4AFC-BBB2-84085AC27BEE} = {320A36EE-8052-433D-B007-9DE3A2C439BF}
74 | EndGlobalSection
75 | GlobalSection(ExtensibilityGlobals) = postSolution
76 | SolutionGuid = {D3749782-165A-47C9-A8BA-C007F17F3AD9}
77 | EndGlobalSection
78 | EndGlobal
79 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Home Page";
3 | }
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Learn how to build ASP.NET apps that can run anywhere.
18 |
19 | Learn More
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | There are powerful new features in Visual Studio for building modern web apps.
29 |
30 | Learn More
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | Bring in libraries from NuGet and npm, and automate tasks using Grunt or Gulp.
40 |
41 | Learn More
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
51 |
52 | Learn More
53 |
54 |
107 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.IdentityServer/User/UserStore.cs:
--------------------------------------------------------------------------------
1 | using IdentityModel;
2 | using System.Collections.Generic;
3 | using System.IdentityModel.Tokens.Jwt;
4 | using System.Linq;
5 | using System.Security.Claims;
6 | using System;
7 |
8 |
9 | namespace Nyw.IdentityServer.User {
10 | public class UserStore {
11 | private readonly List _users = null;
12 |
13 | ///
14 | /// Initializes a new instance of the class.
15 | ///
16 | /// The users.
17 | public UserStore(/*List users*/) {
18 | //_users = users;
19 | if (_users == null) {
20 | _users = new List {
21 | new UserModel{ SubjectId="1", Username="test1", Usermail="test1@qq.com", MobilePhone="13900000001", Password="P2ssw0rd", Claims=new List{ new Claim("name", "test1"),new Claim("website", "https://test1.com") } },
22 | new UserModel{ SubjectId="2", Username="test2", Usermail="test2@qq.com", MobilePhone="13900000002", Password="P2ssw0rd", Claims=new List{ new Claim("name", "test2"),new Claim("website", "https://test2.com") } },
23 | new UserModel{ SubjectId="3", Username="test3", Usermail="test3@qq.com", MobilePhone="13900000003", Password="P2ssw0rd", Claims=new List{ new Claim("name", "test3"),new Claim("website", "https://test3.com") } },
24 | new UserModel{ SubjectId="4", Username="test4", Usermail="test4@qq.com", MobilePhone="13900000004", Password="P2ssw0rd", Claims=new List{ new Claim("name", "test4"),new Claim("website", "https://test4.com") } },
25 | new UserModel{ SubjectId="5", Username="test5", Usermail="test5@qq.com", MobilePhone="13900000005", Password="P2ssw0rd", Claims=new List{ new Claim("name", "test5"),new Claim("website", "https://test5.com") } }
26 | };
27 | }
28 | }
29 |
30 | ///
31 | /// Validates the credentials.
32 | ///
33 | /// The username.
34 | /// The password.
35 | ///
36 | public bool ValidateCredentials(string username, string password) {
37 | var user = FindByUsername(username);
38 | if (user != null) {
39 | return user.Password.Equals(password);
40 | }
41 |
42 | return false;
43 | }
44 |
45 | ///
46 | /// Finds the user by subject identifier.
47 | ///
48 | /// The subject identifier.
49 | ///
50 | public UserModel FindBySubjectId(string subjectId) {
51 | return _users.FirstOrDefault(x => x.SubjectId == subjectId);
52 | }
53 |
54 | ///
55 | /// Finds the user by username.
56 | ///
57 | /// The username.
58 | ///
59 | public UserModel FindByUsername(string username) {
60 | return _users.FirstOrDefault(x => x.Username.Equals(username, StringComparison.OrdinalIgnoreCase));
61 | }
62 |
63 | ///
64 | /// Finds the user by external provider.
65 | ///
66 | /// The provider.
67 | /// The user identifier.
68 | ///
69 | public UserModel FindByExternalProvider(string provider, string userId) {
70 | /*return _users.FirstOrDefault(x =>
71 | x.ProviderName == provider &&
72 | x.ProviderSubjectId == userId);*/
73 | return null;
74 | }
75 |
76 | ///
77 | /// Automatically provisions a user.
78 | ///
79 | /// The provider.
80 | /// The user identifier.
81 | /// The claims.
82 | ///
83 | public UserModel AutoProvisionUser(string provider, string userId, List claims) {
84 | // create a list of claims that we want to transfer into our store
85 | var filtered = new List();
86 |
87 | foreach (var claim in claims) {
88 | // if the external system sends a display name - translate that to the standard OIDC name claim
89 | if (claim.Type == ClaimTypes.Name) {
90 | filtered.Add(new Claim(JwtClaimTypes.Name, claim.Value));
91 | }
92 | // if the JWT handler has an outbound mapping to an OIDC claim use that
93 | else if (JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.ContainsKey(claim.Type)) {
94 | filtered.Add(new Claim(JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap[claim.Type], claim.Value));
95 | }
96 | // copy the claim as-is
97 | else {
98 | filtered.Add(claim);
99 | }
100 | }
101 |
102 | // if no display name was provided, try to construct by first and/or last name
103 | if (!filtered.Any(x => x.Type == JwtClaimTypes.Name)) {
104 | var first = filtered.FirstOrDefault(x => x.Type == JwtClaimTypes.GivenName)?.Value;
105 | var last = filtered.FirstOrDefault(x => x.Type == JwtClaimTypes.FamilyName)?.Value;
106 | if (first != null && last != null) {
107 | filtered.Add(new Claim(JwtClaimTypes.Name, first + " " + last));
108 | }
109 | else if (first != null) {
110 | filtered.Add(new Claim(JwtClaimTypes.Name, first));
111 | }
112 | else if (last != null) {
113 | filtered.Add(new Claim(JwtClaimTypes.Name, last));
114 | }
115 | }
116 |
117 | // create a new unique subject id
118 | var sub = CryptoRandom.CreateUniqueId();
119 |
120 | // check if a display name is available, otherwise fallback to subject id
121 | var name = filtered.FirstOrDefault(c => c.Type == JwtClaimTypes.Name)?.Value ?? sub;
122 |
123 | // create new user
124 | var user = new UserModel {
125 | SubjectId = sub,
126 | Username = name,
127 | /*ProviderName = provider,
128 | ProviderSubjectId = userId,*/
129 | Claims = filtered
130 | };
131 |
132 | // add user to in-memory store
133 | _users.Add(user);
134 |
135 | return user;
136 | }
137 |
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015/2017 cache/options directory
28 | .vs/
29 | .vscode/
30 | # Uncomment if you have tasks that create the project's static files in wwwroot
31 | #wwwroot/
32 |
33 | # Visual Studio 2017 auto generated files
34 | Generated\ Files/
35 |
36 | # MSTest test Results
37 | [Tt]est[Rr]esult*/
38 | [Bb]uild[Ll]og.*
39 |
40 | # NUNIT
41 | *.VisualState.xml
42 | TestResult.xml
43 |
44 | # Build Results of an ATL Project
45 | [Dd]ebugPS/
46 | [Rr]eleasePS/
47 | dlldata.c
48 |
49 | # Benchmark Results
50 | BenchmarkDotNet.Artifacts/
51 |
52 | # .NET Core
53 | project.lock.json
54 | project.fragment.lock.json
55 | artifacts/
56 | **/Properties/launchSettings.json
57 |
58 | # StyleCop
59 | StyleCopReport.xml
60 |
61 | # Files built by Visual Studio
62 | *_i.c
63 | *_p.c
64 | *_i.h
65 | *.ilk
66 | *.meta
67 | *.obj
68 | *.iobj
69 | *.pch
70 | *.pdb
71 | *.ipdb
72 | *.pgc
73 | *.pgd
74 | *.rsp
75 | *.sbr
76 | *.tlb
77 | *.tli
78 | *.tlh
79 | *.tmp
80 | *.tmp_proj
81 | *.log
82 | *.vspscc
83 | *.vssscc
84 | .builds
85 | *.pidb
86 | *.svclog
87 | *.scc
88 |
89 | # Chutzpah Test files
90 | _Chutzpah*
91 |
92 | # Visual C++ cache files
93 | ipch/
94 | *.aps
95 | *.ncb
96 | *.opendb
97 | *.opensdf
98 | *.sdf
99 | *.cachefile
100 | *.VC.db
101 | *.VC.VC.opendb
102 |
103 | # Visual Studio profiler
104 | *.psess
105 | *.vsp
106 | *.vspx
107 | *.sap
108 |
109 | # Visual Studio Trace Files
110 | *.e2e
111 |
112 | # TFS 2012 Local Workspace
113 | $tf/
114 |
115 | # Guidance Automation Toolkit
116 | *.gpState
117 |
118 | # ReSharper is a .NET coding add-in
119 | _ReSharper*/
120 | *.[Rr]e[Ss]harper
121 | *.DotSettings.user
122 |
123 | # JustCode is a .NET coding add-in
124 | .JustCode
125 |
126 | # TeamCity is a build add-in
127 | _TeamCity*
128 |
129 | # DotCover is a Code Coverage Tool
130 | *.dotCover
131 |
132 | # AxoCover is a Code Coverage Tool
133 | .axoCover/*
134 | !.axoCover/settings.json
135 |
136 | # Visual Studio code coverage results
137 | *.coverage
138 | *.coveragexml
139 |
140 | # NCrunch
141 | _NCrunch_*
142 | .*crunch*.local.xml
143 | nCrunchTemp_*
144 |
145 | # MightyMoose
146 | *.mm.*
147 | AutoTest.Net/
148 |
149 | # Web workbench (sass)
150 | .sass-cache/
151 |
152 | # Installshield output folder
153 | [Ee]xpress/
154 |
155 | # DocProject is a documentation generator add-in
156 | DocProject/buildhelp/
157 | DocProject/Help/*.HxT
158 | DocProject/Help/*.HxC
159 | DocProject/Help/*.hhc
160 | DocProject/Help/*.hhk
161 | DocProject/Help/*.hhp
162 | DocProject/Help/Html2
163 | DocProject/Help/html
164 |
165 | # Click-Once directory
166 | publish/
167 |
168 | # Publish Web Output
169 | *.[Pp]ublish.xml
170 | *.azurePubxml
171 | # Note: Comment the next line if you want to checkin your web deploy settings,
172 | # but database connection strings (with potential passwords) will be unencrypted
173 | *.pubxml
174 | *.publishproj
175 |
176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
177 | # checkin your Azure Web App publish settings, but sensitive information contained
178 | # in these scripts will be unencrypted
179 | PublishScripts/
180 |
181 | # NuGet Packages
182 | *.nupkg
183 | # The packages folder can be ignored because of Package Restore
184 | **/[Pp]ackages/*
185 | # except build/, which is used as an MSBuild target.
186 | !**/[Pp]ackages/build/
187 | # Uncomment if necessary however generally it will be regenerated when needed
188 | #!**/[Pp]ackages/repositories.config
189 | # NuGet v3's project.json files produces more ignorable files
190 | *.nuget.props
191 | *.nuget.targets
192 |
193 | # Microsoft Azure Build Output
194 | csx/
195 | *.build.csdef
196 |
197 | # Microsoft Azure Emulator
198 | ecf/
199 | rcf/
200 |
201 | # Windows Store app package directories and files
202 | AppPackages/
203 | BundleArtifacts/
204 | Package.StoreAssociation.xml
205 | _pkginfo.txt
206 | *.appx
207 |
208 | # Visual Studio cache files
209 | # files ending in .cache can be ignored
210 | *.[Cc]ache
211 | # but keep track of directories ending in .cache
212 | !*.[Cc]ache/
213 |
214 | # Others
215 | ClientBin/
216 | ~$*
217 | *~
218 | *.dbmdl
219 | *.dbproj.schemaview
220 | *.jfm
221 | *.pfx
222 | *.publishsettings
223 | orleans.codegen.cs
224 |
225 | # Including strong name files can present a security risk
226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
227 | #*.snk
228 |
229 | # Since there are multiple workflows, uncomment next line to ignore bower_components
230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
231 | #bower_components/
232 |
233 | # RIA/Silverlight projects
234 | Generated_Code/
235 |
236 | # Backup & report files from converting an old project file
237 | # to a newer Visual Studio version. Backup files are not needed,
238 | # because we have git ;-)
239 | _UpgradeReport_Files/
240 | Backup*/
241 | UpgradeLog*.XML
242 | UpgradeLog*.htm
243 | ServiceFabricBackup/
244 | *.rptproj.bak
245 |
246 | # SQL Server files
247 | *.mdf
248 | *.ldf
249 | *.ndf
250 |
251 | # Business Intelligence projects
252 | *.rdl.data
253 | *.bim.layout
254 | *.bim_*.settings
255 | *.rptproj.rsuser
256 |
257 | # Microsoft Fakes
258 | FakesAssemblies/
259 |
260 | # GhostDoc plugin setting file
261 | *.GhostDoc.xml
262 |
263 | # Node.js Tools for Visual Studio
264 | .ntvs_analysis.dat
265 | node_modules/
266 |
267 | # Visual Studio 6 build log
268 | *.plg
269 |
270 | # Visual Studio 6 workspace options file
271 | *.opt
272 |
273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
274 | *.vbw
275 |
276 | # Visual Studio LightSwitch build output
277 | **/*.HTMLClient/GeneratedArtifacts
278 | **/*.DesktopClient/GeneratedArtifacts
279 | **/*.DesktopClient/ModelManifest.xml
280 | **/*.Server/GeneratedArtifacts
281 | **/*.Server/ModelManifest.xml
282 | _Pvt_Extensions
283 |
284 | # Paket dependency manager
285 | .paket/paket.exe
286 | paket-files/
287 |
288 | # FAKE - F# Make
289 | .fake/
290 |
291 | # JetBrains Rider
292 | .idea/
293 | *.sln.iml
294 |
295 | # CodeRush
296 | .cr/
297 |
298 | # Python Tools for Visual Studio (PTVS)
299 | __pycache__/
300 | *.pyc
301 |
302 | # Cake - Uncomment if you are using it
303 | # tools/**
304 | # !tools/packages.config
305 |
306 | # Tabs Studio
307 | *.tss
308 |
309 | # Telerik's JustMock configuration file
310 | *.jmconfig
311 |
312 | # BizTalk build output
313 | *.btp.cs
314 | *.btm.cs
315 | *.odx.cs
316 | *.xsd.cs
317 |
318 | # OpenCover UI analysis results
319 | OpenCover/
320 |
321 | # Azure Stream Analytics local run output
322 | ASALocalRun/
323 |
324 | # MSBuild Binary and Structured Log
325 | *.binlog
326 |
327 | # NVidia Nsight GPU debugger configuration file
328 | *.nvuser
329 |
330 | # MFractors (Xamarin productivity tool) working folder
331 | .mfractor/
332 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/images/banner2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/images/banner1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/images/banner3.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/images/banner4.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/POC/nyw.microservice/Nyw.Portal/wwwroot/lib/jquery-validation/dist/additional-methods.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery Validation Plugin - v1.14.0 - 6/30/2015
2 | * http://jqueryvalidation.org/
3 | * Copyright (c) 2015 Jörn Zaefferer; Licensed MIT */
4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):a(jQuery)}(function(a){!function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("accept",function(b,c,d){var e,f,g="string"==typeof d?d.replace(/\s/g,"").replace(/,/g,"|"):"image/*",h=this.optional(c);if(h)return h;if("file"===a(c).attr("type")&&(g=g.replace(/\*/g,".*"),c.files&&c.files.length))for(e=0;ec;c++)d=h-c,e=f.substring(c,c+1),g+=d*e;return g%11===0},"Please specify a valid bank account number"),a.validator.addMethod("bankorgiroaccountNL",function(b,c){return this.optional(c)||a.validator.methods.bankaccountNL.call(this,b,c)||a.validator.methods.giroaccountNL.call(this,b,c)},"Please specify a valid bank or giro account number"),a.validator.addMethod("bic",function(a,b){return this.optional(b)||/^([A-Z]{6}[A-Z2-9][A-NP-Z1-2])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test(a)},"Please specify a valid BIC code"),a.validator.addMethod("cifES",function(a){"use strict";var b,c,d,e,f,g,h=[];if(a=a.toUpperCase(),!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)"))return!1;for(d=0;9>d;d++)h[d]=parseInt(a.charAt(d),10);for(c=h[2]+h[4]+h[6],e=1;8>e;e+=2)f=(2*h[e]).toString(),g=f.charAt(1),c+=parseInt(f.charAt(0),10)+(""===g?0:parseInt(g,10));return/^[ABCDEFGHJNPQRSUVW]{1}/.test(a)?(c+="",b=10-parseInt(c.charAt(c.length-1),10),a+=b,h[8].toString()===String.fromCharCode(64+b)||h[8].toString()===a.charAt(a.length-1)):!1},"Please specify a valid CIF number."),a.validator.addMethod("cpfBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f=0;if(b=parseInt(a.substring(9,10),10),c=parseInt(a.substring(10,11),10),d=function(a,b){var c=10*a%11;return(10===c||11===c)&&(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(e=1;9>=e;e++)f+=parseInt(a.substring(e-1,e),10)*(11-e);if(d(f,b)){for(f=0,e=1;10>=e;e++)f+=parseInt(a.substring(e-1,e),10)*(12-e);return d(f,c)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&/^(5[12345])/.test(a)?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:128&d?!0:!1},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=e?!0:c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d?!0:!1):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="";if(c=l.substring(0,2),h={AL:"\\d{8}[\\dA-Z]{16}",AD:"\\d{8}[\\dA-Z]{12}",AT:"\\d{16}",AZ:"[\\dA-Z]{4}\\d{20}",BE:"\\d{12}",BH:"[A-Z]{4}[\\dA-Z]{14}",BA:"\\d{16}",BR:"\\d{23}[A-Z][\\dA-Z]",BG:"[A-Z]{4}\\d{6}[\\dA-Z]{8}",CR:"\\d{17}",HR:"\\d{17}",CY:"\\d{8}[\\dA-Z]{16}",CZ:"\\d{20}",DK:"\\d{14}",DO:"[A-Z]{4}\\d{20}",EE:"\\d{16}",FO:"\\d{14}",FI:"\\d{14}",FR:"\\d{10}[\\dA-Z]{11}\\d{2}",GE:"[\\dA-Z]{2}\\d{16}",DE:"\\d{18}",GI:"[A-Z]{4}[\\dA-Z]{15}",GR:"\\d{7}[\\dA-Z]{16}",GL:"\\d{14}",GT:"[\\dA-Z]{4}[\\dA-Z]{20}",HU:"\\d{24}",IS:"\\d{22}",IE:"[\\dA-Z]{4}\\d{14}",IL:"\\d{19}",IT:"[A-Z]\\d{10}[\\dA-Z]{12}",KZ:"\\d{3}[\\dA-Z]{13}",KW:"[A-Z]{4}[\\dA-Z]{22}",LV:"[A-Z]{4}[\\dA-Z]{13}",LB:"\\d{4}[\\dA-Z]{20}",LI:"\\d{5}[\\dA-Z]{12}",LT:"\\d{16}",LU:"\\d{3}[\\dA-Z]{13}",MK:"\\d{3}[\\dA-Z]{10}\\d{2}",MT:"[A-Z]{4}\\d{5}[\\dA-Z]{18}",MR:"\\d{23}",MU:"[A-Z]{4}\\d{19}[A-Z]{3}",MC:"\\d{10}[\\dA-Z]{11}\\d{2}",MD:"[\\dA-Z]{2}\\d{18}",ME:"\\d{18}",NL:"[A-Z]{4}\\d{10}",NO:"\\d{11}",PK:"[\\dA-Z]{4}\\d{16}",PS:"[\\dA-Z]{4}\\d{21}",PL:"\\d{24}",PT:"\\d{21}",RO:"[A-Z]{4}[\\dA-Z]{16}",SM:"[A-Z]\\d{10}[\\dA-Z]{12}",SA:"\\d{2}[\\dA-Z]{18}",RS:"\\d{18}",SK:"\\d{20}",SI:"\\d{15}",ES:"\\d{20}",SE:"\\d{20}",CH:"\\d{5}[\\dA-Z]{12}",TN:"\\d{20}",TR:"\\d{5}[\\dA-Z]{17}",AE:"\\d{3}\\d{16}",GB:"[A-Z]{4}\\d{14}",VG:"[\\dA-Z]{4}\\d{16}"},g=h[c],"undefined"!=typeof g&&(i=new RegExp("^[A-Z]{2}\\d{2}"+g+"$",""),!i.test(l)))return!1;for(d=l.substring(4,l.length)+l.substring(0,4),j=0;j9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("nieES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[T]{1}/.test(a)?a[8]===/^[T]{1}[A-Z0-9]{8}$/.test(a):/^[XYZ]{1}/.test(a)?a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.replace("X","0").replace("Y","1").replace("Z","2").substring(0,8)%23):!1:!1},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):/^[KLM]{1}/.test(a)?a[8]===String.fromCharCode(64):!1:!1},"Please specify a valid NIF number."),jQuery.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return this.optional(b)?!0:("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=e||"undefined"==typeof c.caseSensitive?!1:c.caseSensitive,g=e||"undefined"==typeof c.includeTerritories?!1:c.includeTerritories,h=e||"undefined"==typeof c.includeMilitary?!1:c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;17>b;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e?e:!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,d=d.concat(c.errorList)}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){return!!a.trim(""+a(b).val())},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||-1!==a.inArray(c.keyCode,d)||(b.name in this.submitted||b===this.lastElement)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c=this.clean(b),d=this.validationTargetFor(c),e=!0;return this.lastElement=d,void 0===d?delete this.invalid[c.name]:(this.prepareElement(d),this.currentElements=a(d),e=this.check(d)!==!1,e?delete this.invalid[d.name]:this.invalid[d.name]=!0),a(b).attr("aria-invalid",!e),this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),e},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors();var b,c=this.elements().removeData("previousValue").removeAttr("aria-invalid");if(this.settings.unhighlight)for(b=0;c[b];b++)this.settings.unhighlight.call(this,c[b],this.settings.errorClass,"");else c.removeClass(this.settings.errorClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d=a(b),e=b.type;return"radio"===e||"checkbox"===e?this.findByName(b.name).filter(":checked").val():"number"===e&&"undefined"!=typeof b.validity?b.validity.badInput?!1:d.val():(c=d.val(),"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j instanceof TypeError&&(j.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+"")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b,method:c.method}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g=this.errorsFor(b),h=this.idOrName(b),i=a(b).attr("aria-describedby");g.length?(g.removeClass(this.settings.validClass).addClass(this.settings.errorClass),g.html(c)):(g=a("<"+this.settings.errorElement+">").attr("id",h+"-error").addClass(this.settings.errorClass).html(c||""),d=g,this.settings.wrapper&&(d=g.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),g.is("label")?g.attr("for",h):0===g.parents("label[for='"+h+"']").length&&(f=g.attr("id").replace(/(:|\.|\[|\]|\$)/g,"\\$1"),i?i.match(new RegExp("\\b"+f+"\\b"))||(i+=" "+f):i=f,a(b).attr("aria-describedby",i),e=this.groups[b.name],e&&a.each(this.groups,function(b,c){c===e&&a("[name='"+b+"']",this.currentForm).attr("aria-describedby",g.attr("id"))}))),!c&&this.settings.success&&(g.text(""),"string"==typeof this.settings.success?g.addClass(this.settings.success):this.settings.success(g,b)),this.toShow=this.toShow.add(g)},errorsFor:function(b){var c=this.idOrName(b),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+d.replace(/\s+/g,", #")),this.errors().filter(e)},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+b+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.off(".validate-equalTo").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e,f,g=this.previousValue(c);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),g.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=g.message,d="string"==typeof d&&{url:d}||d,g.old===b?g.valid:(g.old=b,e=this,this.startRequest(c),f={},f[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:f,context:e.currentForm,success:function(d){var f,h,i,j=d===!0||"true"===d;e.settings.messages[c.name].remote=g.originalMessage,j?(i=e.formSubmitted,e.prepareElement(c),e.formSubmitted=i,e.successList.push(c),delete e.invalid[c.name],e.showErrors()):(f={},h=d||e.defaultMessage(c,"remote"),f[c.name]=g.message=a.isFunction(h)?h(b):h,e.invalid[c.name]=!0,e.showErrors(f)),g.valid=j,e.stopRequest(c,j)}},d)),"pending")}}});var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)})});
--------------------------------------------------------------------------------