소스 검색

Save tests

feature/authentication-tests
Robin Thoni 9 년 전
부모
커밋
7482ddd78f

+ 17
- 1
Authentication-test/Web.config 파일 보기

@@ -42,7 +42,23 @@
42 42
       </dependentAssembly>
43 43
       <dependentAssembly>
44 44
         <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
45
-        <bindingRedirect oldVersion="1.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
45
+        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
46
+      </dependentAssembly>
47
+      <dependentAssembly>
48
+        <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
49
+        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
50
+      </dependentAssembly>
51
+      <dependentAssembly>
52
+        <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
53
+        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
54
+      </dependentAssembly>
55
+      <dependentAssembly>
56
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
57
+        <bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
58
+      </dependentAssembly>
59
+      <dependentAssembly>
60
+        <assemblyIdentity name="System.Web.Http.WebHost" publicKeyToken="31bf3856ad364e35" culture="neutral" />
61
+        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
46 62
       </dependentAssembly>
47 63
     </assemblyBinding>
48 64
   </runtime>

+ 19
- 0
Authentication/App.config 파일 보기

@@ -0,0 +1,19 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<configuration>
3
+  <configSections>
4
+    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
5
+  </configSections>
6
+  <entityFramework>
7
+    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
8
+      <parameters>
9
+        <parameter value="v11.0" />
10
+      </parameters>
11
+    </defaultConnectionFactory>
12
+    <providers>
13
+      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
14
+    </providers>
15
+  </entityFramework>
16
+  <connectionStrings>
17
+    <add name="UserEntities" connectionString="metadata=res://*/DataAccess.UserEntities.csdl|res://*/DataAccess.UserEntities.ssdl|res://*/DataAccess.UserEntities.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=Authentication-tests;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
18
+  </connectionStrings>
19
+</configuration>

+ 94
- 5
Authentication/Authentication.csproj 파일 보기

@@ -30,11 +30,44 @@
30 30
     <WarningLevel>4</WarningLevel>
31 31
   </PropertyGroup>
32 32
   <ItemGroup>
33
+    <Reference Include="Dynamic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=68293a411f0cabcc, processorArchitecture=MSIL">
34
+      <HintPath>..\packages\DynamicQuery.1.0\lib\35\Dynamic.dll</HintPath>
35
+      <Private>True</Private>
36
+    </Reference>
37
+    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
38
+      <HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll</HintPath>
39
+      <Private>True</Private>
40
+    </Reference>
41
+    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
42
+      <HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll</HintPath>
43
+      <Private>True</Private>
44
+    </Reference>
45
+    <Reference Include="Logs, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
46
+      <HintPath>..\packages\Logs.dll.1.2.2\lib\net45\Logs.dll</HintPath>
47
+      <Private>True</Private>
48
+    </Reference>
49
+    <Reference Include="Microsoft.Practices.EnterpriseLibrary.Common, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
50
+      <HintPath>..\packages\EnterpriseLibrary.Common.6.0.1304.0\lib\NET45\Microsoft.Practices.EnterpriseLibrary.Common.dll</HintPath>
51
+      <Private>True</Private>
52
+    </Reference>
53
+    <Reference Include="Microsoft.Practices.EnterpriseLibrary.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
54
+      <HintPath>..\packages\EnterpriseLibrary.Data.6.0.1304.0\lib\NET45\Microsoft.Practices.EnterpriseLibrary.Data.dll</HintPath>
55
+      <Private>True</Private>
56
+    </Reference>
57
+    <Reference Include="Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
58
+      <HintPath>..\packages\EnterpriseLibrary.Logging.6.0.1304.0\lib\NET45\Microsoft.Practices.EnterpriseLibrary.Logging.dll</HintPath>
59
+      <Private>True</Private>
60
+    </Reference>
61
+    <Reference Include="Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
62
+      <HintPath>..\packages\EnterpriseLibrary.Logging.Database.6.0.1304.0\lib\NET45\Microsoft.Practices.EnterpriseLibrary.Logging.Database.dll</HintPath>
63
+      <Private>True</Private>
64
+    </Reference>
33 65
     <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
34
-      <SpecificVersion>False</SpecificVersion>
35
-      <HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
66
+      <HintPath>..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
67
+      <Private>True</Private>
36 68
     </Reference>
37 69
     <Reference Include="System" />
70
+    <Reference Include="System.ComponentModel.DataAnnotations" />
38 71
     <Reference Include="System.Configuration" />
39 72
     <Reference Include="System.Core" />
40 73
     <Reference Include="System.IdentityModel" />
@@ -43,18 +76,28 @@
43 76
     </Reference>
44 77
     <Reference Include="System.Net.Http" />
45 78
     <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
46
-      <SpecificVersion>False</SpecificVersion>
47 79
       <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
80
+      <Private>True</Private>
48 81
     </Reference>
82
+    <Reference Include="System.Runtime.Serialization" />
83
+    <Reference Include="System.Security" />
49 84
     <Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
50
-      <SpecificVersion>False</SpecificVersion>
51 85
       <HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
86
+      <Private>True</Private>
87
+    </Reference>
88
+    <Reference Include="System.Web.Http.WebHost, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
89
+      <HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
90
+      <Private>True</Private>
52 91
     </Reference>
53 92
     <Reference Include="System.Xml.Linq" />
54 93
     <Reference Include="System.Data.DataSetExtensions" />
55 94
     <Reference Include="Microsoft.CSharp" />
56 95
     <Reference Include="System.Data" />
57 96
     <Reference Include="System.Xml" />
97
+    <Reference Include="WebApiUtils, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
98
+      <HintPath>..\packages\3ieWebApiUtils.dll.5.0.0\lib\net45\WebApiUtils.dll</HintPath>
99
+      <Private>True</Private>
100
+    </Reference>
58 101
   </ItemGroup>
59 102
   <ItemGroup>
60 103
     <Compile Include="Business\Attributes\AuthFilter.cs" />
@@ -62,12 +105,58 @@
62 105
     <Compile Include="Business\JWT\TokenManager.cs" />
63 106
     <Compile Include="Business\JWT\TokenValidationHandler.cs" />
64 107
     <Compile Include="Business\AuthProvider.cs" />
65
-    <Compile Include="DBO\UserDboAuth.cs" />
108
+    <Compile Include="Business\UserBasicBusiness.cs" />
109
+    <Compile Include="DataAccess\T_Users.cs">
110
+      <DependentUpon>UserEntities.tt</DependentUpon>
111
+    </Compile>
112
+    <Compile Include="DataAccess\UserEntities.Context.cs">
113
+      <AutoGen>True</AutoGen>
114
+      <DesignTime>True</DesignTime>
115
+      <DependentUpon>UserEntities.Context.tt</DependentUpon>
116
+    </Compile>
117
+    <Compile Include="DataAccess\UserEntities.cs">
118
+      <AutoGen>True</AutoGen>
119
+      <DesignTime>True</DesignTime>
120
+      <DependentUpon>UserEntities.tt</DependentUpon>
121
+    </Compile>
122
+    <Compile Include="DataAccess\UserEntities.Designer.cs">
123
+      <AutoGen>True</AutoGen>
124
+      <DesignTime>True</DesignTime>
125
+      <DependentUpon>UserEntities.edmx</DependentUpon>
126
+    </Compile>
127
+    <Compile Include="DataAccess\UserBasicManager.cs" />
128
+    <Compile Include="DBO\UserAdd.cs" />
129
+    <Compile Include="DBO\UserEdit.cs" />
130
+    <Compile Include="DBO\UserGet.cs" />
66 131
     <Compile Include="Properties\AssemblyInfo.cs" />
67 132
   </ItemGroup>
68 133
   <ItemGroup>
134
+    <EntityDeploy Include="DataAccess\UserEntities.edmx">
135
+      <Generator>EntityModelCodeGenerator</Generator>
136
+      <LastGenOutput>UserEntities.Designer.cs</LastGenOutput>
137
+    </EntityDeploy>
138
+    <None Include="App.config" />
139
+    <None Include="DataAccess\UserEntities.Context.tt">
140
+      <Generator>TextTemplatingFileGenerator</Generator>
141
+      <DependentUpon>UserEntities.edmx</DependentUpon>
142
+      <LastGenOutput>UserEntities.Context.cs</LastGenOutput>
143
+    </None>
144
+    <None Include="DataAccess\UserEntities.edmx.diagram">
145
+      <DependentUpon>UserEntities.edmx</DependentUpon>
146
+    </None>
147
+    <None Include="DataAccess\UserEntities.tt">
148
+      <Generator>TextTemplatingFileGenerator</Generator>
149
+      <DependentUpon>UserEntities.edmx</DependentUpon>
150
+      <LastGenOutput>UserEntities.cs</LastGenOutput>
151
+    </None>
69 152
     <None Include="packages.config" />
70 153
   </ItemGroup>
154
+  <ItemGroup>
155
+    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
156
+  </ItemGroup>
157
+  <ItemGroup>
158
+    <Content Include="Dynamic Expressions.html" />
159
+  </ItemGroup>
71 160
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
72 161
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
73 162
        Other similar extension points exist, see Microsoft.Common.targets.

+ 3
- 3
Authentication/Business/Attributes/AuthFilter.cs 파일 보기

@@ -13,7 +13,7 @@ namespace iiie.Authentication.Business.Attributes
13 13
         /// <summary>
14 14
         /// Authorized roles to access this method
15 15
         /// </summary>
16
-        public IEnumerable<int> Roles { get; set; }
16
+        public IEnumerable<int> UserRoles { get; set; }
17 17
 
18 18
         /// <summary>
19 19
         /// Constructor
@@ -21,7 +21,7 @@ namespace iiie.Authentication.Business.Attributes
21 21
         /// <param name="roles"></param>
22 22
         public AuthFilter(params int[] roles)
23 23
         {
24
-            Roles = roles.ToList();
24
+            UserRoles = roles.ToList();
25 25
         }
26 26
 
27 27
         /// <summary>
@@ -31,7 +31,7 @@ namespace iiie.Authentication.Business.Attributes
31 31
         /// <returns>True if user can access, false otherwise</returns>
32 32
         protected override bool IsAuthorized(HttpActionContext context)
33 33
         {
34
-            return !Roles.Any();// || (UsersBusiness.UserId != null && Roles.Contains(UsersBusiness.UserId.Role));
34
+            return !UserRoles.Any() || UserRoles.Any();// || (UsersBusiness.UserId != null && Roles.Contains(UsersBusiness.UserId.Role));
35 35
         }
36 36
     }
37 37
 }

+ 11
- 37
Authentication/Business/AuthProvider.cs 파일 보기

@@ -9,25 +9,19 @@ using Newtonsoft.Json;
9 9
 
10 10
 namespace iiie.Authentication.Business
11 11
 {
12
-    public abstract class AuthProvider<TUserDbo>
13
-        where TUserDbo : UserDboAuth
12
+    public static class AuthProvider
14 13
     {
15
-        /// <summary>
16
-        /// Application specific settings
17
-        /// </summary>
18
-        public static AuthProvider<TUserDbo> Instance { get; set; }
19
-
20 14
         /// <summary>
21 15
         /// The registered user dbo, or null if no user is logged
22 16
         /// </summary>
23
-        public static TUserDbo UserDbo
17
+        public static UserGet UserDbo
24 18
         {
25 19
             get
26 20
             {
27 21
                 var claim = ((ClaimsIdentity)Thread.CurrentPrincipal.Identity).Claims.FirstOrDefault(x => x != null && x.Type == "__userdbo__");
28 22
                 if (claim == null)
29 23
                     return null;
30
-                return JsonConvert.DeserializeObject<TUserDbo>(claim.Value);
24
+                return JsonConvert.DeserializeObject<UserGet>(claim.Value);
31 25
             }
32 26
             set
33 27
             {
@@ -62,11 +56,9 @@ namespace iiie.Authentication.Business
62 56
         /// <param name="key">The config file key</param>
63 57
         /// <param name="def">The default value</param>
64 58
         /// <returns>The found int</returns>
65
-        protected int GetInt(string key, int def)
59
+        public static int GetInt(string key, int def)
66 60
         {
67
-            var valueStr = ConfigurationManager.AppSettings[key];
68
-            if (valueStr == null)
69
-                return def;
61
+            var valueStr = GetString(key, def.ToString());
70 62
             int value;
71 63
             if (int.TryParse(valueStr, out value))
72 64
                 return value;
@@ -79,36 +71,18 @@ namespace iiie.Authentication.Business
79 71
         /// <param name="key">The config file key</param>
80 72
         /// <param name="def">The default value</param>
81 73
         /// <returns>The found string</returns>
82
-        protected string GetString(string key, string def)
74
+        public static string GetString(string key, string def)
83 75
         {
84 76
             var value = ConfigurationManager.AppSettings[key];
85 77
             if (value == null)
86 78
                 return def;
87 79
             return value;
88 80
         }
89
-        /// <summary>
90
-        /// Contructs a user dbo from the specified username and salt and register it into UserDbo
91
-        /// </summary>
92
-        /// <param name="username">The username of the verified token</param>
93
-        /// <param name="salt">The salt in the token</param>
94
-        /// <returns>The user dbo, or null if user is not valid</returns>
95
-        public TUserDbo GetAndRegisterUserDbo(string username, string salt)
96
-        {
97
-            return UserDbo = GetUserDbo(username, salt);
98
-        }
99
-
100
-        /// <summary>
101
-        /// Contructs a user dbo from the specified username and salt
102
-        /// </summary>
103
-        /// <param name="username">The username of the verified token</param>
104
-        /// <param name="salt">The salt in the token</param>
105
-        /// <returns>The user dbo, or null if user is not valid</returns>
106
-        public abstract TUserDbo GetUserDbo(string username, string salt);
107 81
 
108 82
         /// <summary>
109 83
         /// Const value to compute password hash
110 84
         /// </summary>
111
-        public virtual int GetPasswordSaltByteSize()
85
+        public static int GetPasswordSaltByteSize()
112 86
         {
113 87
             return GetInt("PasswordSaltByteSize", 42);
114 88
         }
@@ -116,7 +90,7 @@ namespace iiie.Authentication.Business
116 90
         /// <summary>
117 91
         /// Const value to compute password hash
118 92
         /// </summary>
119
-        public virtual int GetPasswordHashByteSize()
93
+        public static int GetPasswordHashByteSize()
120 94
         {
121 95
             return GetInt("PasswordHashByteSize", 42);
122 96
         }
@@ -124,7 +98,7 @@ namespace iiie.Authentication.Business
124 98
         /// <summary>
125 99
         /// Const value to compute password hash
126 100
         /// </summary>
127
-        public virtual int GetPasswordIterations()
101
+        public static int GetPasswordIterations()
128 102
         {
129 103
             return GetInt("PasswordIterations", 2048);
130 104
         }
@@ -134,7 +108,7 @@ namespace iiie.Authentication.Business
134 108
         /// Must be constant. Default is app setting 'ValidatorString'
135 109
         /// </summary>
136 110
         /// <returns>The string</returns>
137
-        public virtual string GetValidatorString()
111
+        public static string GetValidatorString()
138 112
         {
139 113
             return GetString("ValidatorString", "__default__");
140 114
         }
@@ -144,7 +118,7 @@ namespace iiie.Authentication.Business
144 118
         /// Must be constant. Default is app setting 'CredentialKey'
145 119
         /// </summary>
146 120
         /// <returns>The string</returns>
147
-        public virtual string GetCredentialKey()
121
+        public static string GetCredentialKey()
148 122
         {
149 123
             return GetString("CredentialKey", "__default__");
150 124
         }

+ 33
- 13
Authentication/Business/JWT/PasswordHash.cs 파일 보기

@@ -1,5 +1,6 @@
1 1
 using System;
2 2
 using System.Security.Cryptography;
3
+using System.Text;
3 4
 
4 5
 namespace iiie.Authentication.Business.JWT
5 6
 {
@@ -8,9 +9,29 @@ namespace iiie.Authentication.Business.JWT
8 9
     /// </summary>
9 10
     public static class PasswordHash
10 11
     {
11
-        private const int ITERATION_INDEX = 0;
12
-        private const int SALT_INDEX = 1;
13
-        private const int PBKDF2_INDEX = 2;
12
+        /// <summary>
13
+        /// Compute a random string
14
+        /// </summary>
15
+        /// <param name="size">The length of the string</param>
16
+        /// <returns>A random stirng</returns>
17
+        public static string RandomString(int size)
18
+        {
19
+            var random = new Random((int)DateTime.Now.Ticks);
20
+            StringBuilder builder = new StringBuilder();
21
+            for (int i = 0; i < size; i++)
22
+                builder.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(90 * random.NextDouble() + 33))));
23
+
24
+            return builder.ToString();
25
+        }
26
+
27
+        /// <summary>
28
+        /// Get a random salt
29
+        /// </summary>
30
+        /// <returns>A salt</returns>
31
+        public static string GetSalt()
32
+        {
33
+            return RandomString(10);
34
+        }
14 35
 
15 36
         /// <summary>
16 37
         /// Crée un hash à partir du password
@@ -20,16 +41,15 @@ namespace iiie.Authentication.Business.JWT
20 41
         public static string CreateHash(string password)
21 42
         {
22 43
             // génaration du SALT aléatoire
23
-            /*RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();
24
-            byte[] salt = new byte[AuthProvider.Instance.GetPasswordSaltByteSize()];
44
+            RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();
45
+            byte[] salt = new byte[AuthProvider.GetPasswordSaltByteSize()];
25 46
             csprng.GetBytes(salt);
26 47
 
27 48
             // hash le password et création de la chaine avec les paramêtres
28
-            byte[] hash = PBKDF2(password, salt, AuthProvider.Instance.GetPasswordIterations(),
29
-                AuthProvider.Instance.GetPasswordSaltByteSize());
30
-            return AuthProvider.Instance.GetPasswordIterations() + ":" +
31
-                Convert.ToBase64String(salt) + ":" + Convert.ToBase64String(hash);*/
32
-            return "";
49
+            byte[] hash = PBKDF2(password, salt, AuthProvider.GetPasswordIterations(),
50
+                AuthProvider.GetPasswordSaltByteSize());
51
+            return AuthProvider.GetPasswordIterations() + ":" +
52
+                Convert.ToBase64String(salt) + ":" + Convert.ToBase64String(hash);
33 53
         }
34 54
 
35 55
         /// <summary>
@@ -43,9 +63,9 @@ namespace iiie.Authentication.Business.JWT
43 63
             // Extraction des paramêtres du hash
44 64
             char[] delimiter = { ':' };
45 65
             string[] split = correctHash.Split(delimiter);
46
-            int iterations = Int32.Parse(split[ITERATION_INDEX]);
47
-            byte[] salt = Convert.FromBase64String(split[SALT_INDEX]);
48
-            byte[] hash = Convert.FromBase64String(split[PBKDF2_INDEX]);
66
+            int iterations = Int32.Parse(split[0]);
67
+            byte[] salt = Convert.FromBase64String(split[1]);
68
+            byte[] hash = Convert.FromBase64String(split[2]);
49 69
 
50 70
             byte[] testHash = PBKDF2(password, salt, iterations, hash.Length);
51 71
             return SlowEquals(hash, testHash);

+ 6
- 6
Authentication/Business/JWT/TokenManager.cs 파일 보기

@@ -1,7 +1,6 @@
1 1
 using System;
2 2
 using System.IdentityModel.Tokens;
3 3
 using System.Security.Claims;
4
-using iiie.Authentication.DBO;
5 4
 
6 5
 namespace iiie.Authentication.Business.JWT
7 6
 {
@@ -16,7 +15,7 @@ namespace iiie.Authentication.Business.JWT
16 15
         /// <returns>The credentials</returns>
17 16
         private static SigningCredentials CreateSigningCredentials()
18 17
         {
19
-            string symmetricKey = "";//AuthProvider.Instance.GetCredentialKey();
18
+            string symmetricKey = AuthProvider.GetCredentialKey();
20 19
             byte[] keybytes = Convert.FromBase64String(symmetricKey);
21 20
             SecurityKey securityKey = new InMemorySymmetricSecurityKey(keybytes);
22 21
             SigningCredentials signingCredentials =
@@ -30,15 +29,16 @@ namespace iiie.Authentication.Business.JWT
30 29
         /// Create a JWT token
31 30
         /// </summary>
32 31
         /// <param name="user">The user</param>
32
+        /// <param name="salt">The user salt</param>
33 33
         /// <returns>The token</returns>
34
-        public static string GetToken(UserDboAuth user, String salt)
34
+        public static string GetToken(string user, string salt)
35 35
         {
36
-            var stringValidator = "";//AuthProvider.Instance.GetValidatorString();
36
+            var stringValidator = AuthProvider.GetValidatorString();
37 37
             JwtSecurityToken jst = new JwtSecurityToken("urn:" + stringValidator,
38 38
                                               stringValidator,
39
-                                              new Claim[]
39
+                                              new []
40 40
                                                {
41
-                                                   new Claim(ClaimTypes.Name, user.Username),
41
+                                                   new Claim(ClaimTypes.Name, user),
42 42
                                                    new Claim(ClaimTypes.Authentication, salt)
43 43
                                                }, null, DateTime.Now.AddDays(1),
44 44
                                               CreateSigningCredentials());

+ 2
- 14
Authentication/Business/JWT/TokenValidationHandler.cs 파일 보기

@@ -7,7 +7,6 @@ using System.Security.Claims;
7 7
 using System.ServiceModel.Security.Tokens;
8 8
 using System.Threading;
9 9
 using System.Threading.Tasks;
10
-using iiie.Authentication.DBO;
11 10
 
12 11
 namespace iiie.Authentication.Business.JWT
13 12
 {
@@ -32,17 +31,6 @@ namespace iiie.Authentication.Business.JWT
32 31
             return true;
33 32
         }
34 33
 
35
-        /// <summary>
36
-        /// Contructs a user dbo from the specified username and salt
37
-        /// </summary>
38
-        /// <param name="username">The username of the verified token</param>
39
-        /// <param name="salt">The salt in the token</param>
40
-        /// <returns>The user dbo, or null if user is not valid</returns>
41
-        protected UserDboAuth GetUserDbo(string username, string salt)
42
-        {
43
-            return null;
44
-        }
45
-
46 34
         /// <summary>
47 35
         /// Attempts to verify user token
48 36
         /// </summary>
@@ -69,7 +57,7 @@ namespace iiie.Authentication.Business.JWT
69 57
                     }
70 58
                 };
71 59
 
72
-                var stringValidator = "";//AuthProvider.Instance.GetValidatorString();
60
+                var stringValidator = AuthProvider.GetValidatorString();
73 61
                 TokenValidationParameters validationParameters = new TokenValidationParameters()
74 62
                 {
75 63
                     RequireSignedTokens = true,
@@ -77,7 +65,7 @@ namespace iiie.Authentication.Business.JWT
77 65
                     ValidAudience = stringValidator,
78 66
                     ValidateIssuerSigningKey = true,
79 67
                     ValidIssuer = "urn:" + stringValidator,
80
-                    IssuerSigningToken = new BinarySecretSecurityToken(Convert.FromBase64String(/*AuthProvider.Instance.GetCredentialKey()*/""))
68
+                    IssuerSigningToken = new BinarySecretSecurityToken(Convert.FromBase64String(AuthProvider.GetCredentialKey()))
81 69
                 };
82 70
 
83 71
                 SecurityToken validateToken;

+ 19
- 0
Authentication/Business/UserBasicBusiness.cs 파일 보기

@@ -0,0 +1,19 @@
1
+using iiie.Authentication.DataAccess;
2
+using iiie.Authentication.DBO;
3
+using iiie.Logs.DBO;
4
+
5
+namespace iiie.Authentication.Business
6
+{
7
+    public class UserBasicBusiness
8
+    {
9
+        public OpResult<UserGet> GetSingleById(long id)
10
+        {
11
+            return UserBasicManager.GetSingleById(id);
12
+        }
13
+
14
+        public OpResult<UserGet> GetSingleByUsername(string username)
15
+        {
16
+            return UserBasicManager.GetSingleByUsername(username);
17
+        }
18
+    }
19
+}

+ 18
- 0
Authentication/DBO/UserAdd.cs 파일 보기

@@ -0,0 +1,18 @@
1
+namespace iiie.Authentication.DBO
2
+{
3
+    /// <summary>
4
+    /// Required fields to create user
5
+    /// </summary>
6
+    public class UserAdd : UserEdit
7
+    {
8
+        /// <summary>
9
+        /// The user username
10
+        /// </summary>
11
+        public string Username { get; set; }
12
+
13
+        /// <summary>
14
+        /// The optionnal user profile id
15
+        /// </summary>
16
+        public long? ProfileId { get; set; }
17
+    }
18
+}

+ 0
- 24
Authentication/DBO/UserDboAuth.cs 파일 보기

@@ -1,24 +0,0 @@
1
-
2
-namespace iiie.Authentication.DBO
3
-{
4
-    /// <summary>
5
-    /// Basic User representation
6
-    /// </summary>
7
-    public class UserDboAuth
8
-    {
9
-        /// <summary>
10
-        /// The user internal id
11
-        /// </summary>
12
-        public long Id { get; set; }
13
-
14
-        /// <summary>
15
-        /// User username
16
-        /// </summary>
17
-        public string Username { get; set; }
18
-
19
-        /// <summary>
20
-        /// User role
21
-        /// </summary>
22
-        public int Role { get; set; }
23
-    }
24
-}

+ 108
- 0
Authentication/DBO/UserEdit.cs 파일 보기

@@ -0,0 +1,108 @@
1
+using iiie.Authentication.Business.JWT;
2
+
3
+namespace iiie.Authentication.DBO
4
+{
5
+    /// <summary>
6
+    /// All editable user fields
7
+    /// </summary>
8
+    public class UserEdit
9
+    {
10
+        /// <summary>
11
+        /// When getting / setting from / to database: salt and password hash
12
+        /// When getting from controller: user plain text password
13
+        /// When returning from controller: empty or user token
14
+        /// </summary>
15
+        public object Private { get; private set; }
16
+
17
+        /// <summary>
18
+        /// Application specific user role(s)
19
+        /// </summary>
20
+        public int Role { get; set; }
21
+
22
+        /// <summary>
23
+        /// Optionnal user first name
24
+        /// </summary>
25
+        public string Firstname { get; set; }
26
+
27
+        /// <summary>
28
+        /// Optionnal user last name
29
+        /// </summary>
30
+        public string Lastname { get; set; }
31
+
32
+        /// <summary>
33
+        /// Get the user password salt from Private
34
+        /// </summary>
35
+        /// <returns>The salt</returns>
36
+        public string GetSalt()
37
+        {
38
+            return ((string[]) Private)[0];
39
+        }
40
+
41
+        /// <summary>
42
+        /// Set a value in the Private stirng array
43
+        /// </summary>
44
+        /// <param name="text">The value to be set</param>
45
+        /// <param name="pos">The position in the array</param>
46
+        private void SetArrayText(string text, int pos)
47
+        {
48
+            if (Private == null || Private.GetType() != typeof(string[]))
49
+                Private = new string[2];
50
+            ((string[]) Private)[pos] = text;
51
+        }
52
+
53
+        /// <summary>
54
+        /// Set the user password salt to Private
55
+        /// </summary>
56
+        /// <param name="salt">The salt</param>
57
+        public void SetSalt(string salt)
58
+        {
59
+            SetArrayText(salt, 0);
60
+        }
61
+
62
+        /// <summary>
63
+        /// Get the password hash from Private
64
+        /// </summary>
65
+        /// <returns>The hash</returns>
66
+        public string GetHash()
67
+        {
68
+            return ((string[])Private)[1];
69
+        }
70
+
71
+        /// <summary>
72
+        /// Compute and set the password hash to Private
73
+        /// </summary>
74
+        /// <param name="password">The plain text password</param>
75
+        public void SetPlainTextHash(string password)
76
+        {
77
+            SetArrayText(PasswordHash.CreateHash(password), 1);
78
+        }
79
+
80
+        /// <summary>
81
+        /// Set the password hash to Private
82
+        /// </summary>
83
+        /// <param name="hash">The password hash</param>
84
+        public void SetHash(string hash)
85
+        {
86
+            SetArrayText(hash, 1);
87
+        }
88
+
89
+        /// <summary>
90
+        /// Get the Private as string
91
+        /// </summary>
92
+        /// <returns>The string data</returns>
93
+        public string GetPlainTextPrivate()
94
+        {
95
+            return (string) Private;
96
+        }
97
+
98
+        /// <summary>
99
+        /// Compute and set the token to Private
100
+        /// </summary>
101
+        /// <param name="username">The user username</param>
102
+        /// <param name="salt">The use rpassword salt</param>
103
+        public void SetPlainTextToken(string username, string salt)
104
+        {
105
+            Private = TokenManager.GetToken(username, salt);
106
+        }
107
+    }
108
+}

+ 18
- 0
Authentication/DBO/UserGet.cs 파일 보기

@@ -0,0 +1,18 @@
1
+namespace iiie.Authentication.DBO
2
+{
3
+    /// <summary>
4
+    /// All basic user fields
5
+    /// </summary>
6
+    public class UserGet : UserAdd
7
+    {
8
+        /// <summary>
9
+        /// User id
10
+        /// </summary>
11
+        public long Id { get; set; }
12
+
13
+        /// <summary>
14
+        /// Additionnal application specific data
15
+        /// </summary>
16
+        public object Data { get; set; }
17
+    }
18
+}

+ 26
- 0
Authentication/DataAccess/T_Users.cs 파일 보기

@@ -0,0 +1,26 @@
1
+//------------------------------------------------------------------------------
2
+// <auto-generated>
3
+//     This code was generated from a template.
4
+//
5
+//     Manual changes to this file may cause unexpected behavior in your application.
6
+//     Manual changes to this file will be overwritten if the code is regenerated.
7
+// </auto-generated>
8
+//------------------------------------------------------------------------------
9
+
10
+namespace iiie.Authentication.DataAccess
11
+{
12
+    using System;
13
+    using System.Collections.Generic;
14
+    
15
+    public partial class T_Users
16
+    {
17
+        public long id { get; set; }
18
+        public string username { get; set; }
19
+        public string password { get; set; }
20
+        public string salt { get; set; }
21
+        public int role { get; set; }
22
+        public string firstname { get; set; }
23
+        public string lastname { get; set; }
24
+        public Nullable<long> profile_id { get; set; }
25
+    }
26
+}

+ 73
- 0
Authentication/DataAccess/UserBasicManager.cs 파일 보기

@@ -0,0 +1,73 @@
1
+using System;
2
+using System.Data.Entity;
3
+using iiie.Authentication.Business.JWT;
4
+using iiie.Authentication.DBO;
5
+using iiie.Logs.DBO;
6
+using iiie.WebApiUtils.BusinessManager;
7
+using iiie.WebApiUtils.DBO;
8
+
9
+namespace iiie.Authentication.DataAccess
10
+{
11
+    /// <summary>
12
+    /// Manage basic user informations
13
+    /// </summary>
14
+    public class UserBasicManager : SqlServerManager<T_Users, UserGet, UserAdd, UserEdit, UserEntities, UserBasicManager>
15
+    {
16
+        public override DbSet<T_Users> GetTable(UserEntities db)
17
+        {
18
+            return db.T_Users;
19
+        }
20
+
21
+        public override UserGet DbToDboGet(T_Users obj)
22
+        {
23
+            var user = new UserGet
24
+            {
25
+                Firstname = obj.firstname,
26
+                Id = obj.id,
27
+                Lastname = obj.lastname,
28
+                ProfileId = obj.profile_id,
29
+                Role = obj.role,
30
+                Username = obj.username
31
+            };
32
+            user.SetHash(obj.password);
33
+            user.SetSalt(obj.salt);
34
+            return user;
35
+        }
36
+
37
+        public override OpResult<bool> DboAddToDb(UserAdd obj, T_Users add)
38
+        {
39
+            add.username = obj.Username;
40
+            add.password = PasswordHash.CreateHash(obj.GetPlainTextPrivate());
41
+            add.salt = PasswordHash.GetSalt();
42
+            add.role = obj.Role;
43
+            add.firstname = obj.Firstname;
44
+            add.lastname = obj.Lastname;
45
+            add.profile_id = obj.ProfileId;
46
+            return OpResult<bool>.Ok(true);
47
+        }
48
+
49
+        public override OpResult<bool> DboEditToDb(UserEdit obj, T_Users edit)
50
+        {
51
+            if (obj.Private != null)
52
+            {
53
+                edit.salt = PasswordHash.GetSalt();
54
+                edit.password = PasswordHash.CreateHash(obj.GetPlainTextPrivate());
55
+            }
56
+            edit.firstname = obj.Firstname;
57
+            edit.lastname = obj.Lastname;
58
+            edit.role = obj.Role;
59
+            return OpResult<bool>.Ok(true);
60
+        }
61
+
62
+        public static OpResult<UserGet> GetSingleByUsername(string username)
63
+        {
64
+            return GetSingle(x => x.username.ToLower() == username.ToLower());
65
+        }
66
+
67
+        public static OpResult<DboGetMultiple<UserGet>> GetMultipleSearch(string query, int page = 0, int perPage = Int32.MaxValue)
68
+        {
69
+            return GetMultiple(x => x.firstname.ToLower().Contains(query) || x.lastname.ToLower().Contains(query)
70
+                    || x.username.ToLower().Contains(query), x => x.username, page, perPage);
71
+        }
72
+    }
73
+}

+ 30
- 0
Authentication/DataAccess/UserEntities.Context.cs 파일 보기

@@ -0,0 +1,30 @@
1
+//------------------------------------------------------------------------------
2
+// <auto-generated>
3
+//     This code was generated from a template.
4
+//
5
+//     Manual changes to this file may cause unexpected behavior in your application.
6
+//     Manual changes to this file will be overwritten if the code is regenerated.
7
+// </auto-generated>
8
+//------------------------------------------------------------------------------
9
+
10
+namespace iiie.Authentication.DataAccess
11
+{
12
+    using System;
13
+    using System.Data.Entity;
14
+    using System.Data.Entity.Infrastructure;
15
+    
16
+    public partial class UserEntities : DbContext
17
+    {
18
+        public UserEntities()
19
+            : base("name=UserEntities")
20
+        {
21
+        }
22
+    
23
+        protected override void OnModelCreating(DbModelBuilder modelBuilder)
24
+        {
25
+            throw new UnintentionalCodeFirstException();
26
+        }
27
+    
28
+        public virtual DbSet<T_Users> T_Users { get; set; }
29
+    }
30
+}

+ 636
- 0
Authentication/DataAccess/UserEntities.Context.tt 파일 보기

@@ -0,0 +1,636 @@
1
+<#@ template language="C#" debug="false" hostspecific="true"#>
2
+<#@ include file="EF6.Utility.CS.ttinclude"#><#@
3
+ output extension=".cs"#><#
4
+
5
+const string inputFile = @"UserEntities.edmx";
6
+var textTransform = DynamicTextTransformation.Create(this);
7
+var code = new CodeGenerationTools(this);
8
+var ef = new MetadataTools(this);
9
+var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
10
+var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
11
+var itemCollection = loader.CreateEdmItemCollection(inputFile);
12
+var modelNamespace = loader.GetModelNamespace(inputFile);
13
+var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
14
+
15
+var container = itemCollection.OfType<EntityContainer>().FirstOrDefault();
16
+if (container == null)
17
+{
18
+    return string.Empty;
19
+}
20
+#>
21
+//------------------------------------------------------------------------------
22
+// <auto-generated>
23
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
24
+//
25
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
26
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
27
+// </auto-generated>
28
+//------------------------------------------------------------------------------
29
+
30
+<#
31
+
32
+var codeNamespace = code.VsNamespaceSuggestion();
33
+if (!String.IsNullOrEmpty(codeNamespace))
34
+{
35
+#>
36
+namespace <#=code.EscapeNamespace(codeNamespace)#>
37
+{
38
+<#
39
+    PushIndent("    ");
40
+}
41
+
42
+#>
43
+using System;
44
+using System.Data.Entity;
45
+using System.Data.Entity.Infrastructure;
46
+<#
47
+if (container.FunctionImports.Any())
48
+{
49
+#>
50
+using System.Data.Entity.Core.Objects;
51
+using System.Linq;
52
+<#
53
+}
54
+#>
55
+
56
+<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
57
+{
58
+    public <#=code.Escape(container)#>()
59
+        : base("name=<#=container.Name#>")
60
+    {
61
+<#
62
+if (!loader.IsLazyLoadingEnabled(container))
63
+{
64
+#>
65
+        this.Configuration.LazyLoadingEnabled = false;
66
+<#
67
+}
68
+
69
+foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
70
+{
71
+    // Note: the DbSet members are defined below such that the getter and
72
+    // setter always have the same accessibility as the DbSet definition
73
+    if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
74
+    {
75
+#>
76
+        <#=codeStringGenerator.DbSetInitializer(entitySet)#>
77
+<#
78
+    }
79
+}
80
+#>
81
+    }
82
+
83
+    protected override void OnModelCreating(DbModelBuilder modelBuilder)
84
+    {
85
+        throw new UnintentionalCodeFirstException();
86
+    }
87
+
88
+<#
89
+    foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
90
+    {
91
+#>
92
+    <#=codeStringGenerator.DbSet(entitySet)#>
93
+<#
94
+    }
95
+
96
+    foreach (var edmFunction in container.FunctionImports)
97
+    {
98
+        WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
99
+    }
100
+#>
101
+}
102
+<#
103
+
104
+if (!String.IsNullOrEmpty(codeNamespace))
105
+{
106
+    PopIndent();
107
+#>
108
+}
109
+<#
110
+}
111
+#>
112
+<#+
113
+
114
+private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
115
+{
116
+    if (typeMapper.IsComposable(edmFunction))
117
+    {
118
+#>
119
+
120
+    [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
121
+    <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
122
+    {
123
+<#+
124
+        codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
125
+#>
126
+        <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
127
+    }
128
+<#+
129
+    }
130
+    else
131
+    {
132
+#>
133
+
134
+    <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
135
+    {
136
+<#+
137
+        codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
138
+#>
139
+        <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
140
+    }
141
+<#+
142
+        if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
143
+        {
144
+            WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
145
+        }
146
+    }
147
+}
148
+
149
+public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
150
+{
151
+#>
152
+        var <#=name#> = <#=isNotNull#> ?
153
+            <#=notNullInit#> :
154
+            <#=nullInit#>;
155
+
156
+<#+
157
+}
158
+
159
+public const string TemplateId = "CSharp_DbContext_Context_EF6";
160
+
161
+public class CodeStringGenerator
162
+{
163
+    private readonly CodeGenerationTools _code;
164
+    private readonly TypeMapper _typeMapper;
165
+    private readonly MetadataTools _ef;
166
+
167
+    public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
168
+    {
169
+        ArgumentNotNull(code, "code");
170
+        ArgumentNotNull(typeMapper, "typeMapper");
171
+        ArgumentNotNull(ef, "ef");
172
+
173
+        _code = code;
174
+        _typeMapper = typeMapper;
175
+        _ef = ef;
176
+    }
177
+
178
+    public string Property(EdmProperty edmProperty)
179
+    {
180
+        return string.Format(
181
+            CultureInfo.InvariantCulture,
182
+            "{0} {1} {2} {{ {3}get; {4}set; }}",
183
+            Accessibility.ForProperty(edmProperty),
184
+            _typeMapper.GetTypeName(edmProperty.TypeUsage),
185
+            _code.Escape(edmProperty),
186
+            _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
187
+            _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
188
+    }
189
+
190
+    public string NavigationProperty(NavigationProperty navProp)
191
+    {
192
+        var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
193
+        return string.Format(
194
+            CultureInfo.InvariantCulture,
195
+            "{0} {1} {2} {{ {3}get; {4}set; }}",
196
+            AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
197
+            navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
198
+            _code.Escape(navProp),
199
+            _code.SpaceAfter(Accessibility.ForGetter(navProp)),
200
+            _code.SpaceAfter(Accessibility.ForSetter(navProp)));
201
+    }
202
+    
203
+    public string AccessibilityAndVirtual(string accessibility)
204
+    {
205
+        return accessibility + (accessibility != "private" ? " virtual" : "");
206
+    }
207
+    
208
+    public string EntityClassOpening(EntityType entity)
209
+    {
210
+        return string.Format(
211
+            CultureInfo.InvariantCulture,
212
+            "{0} {1}partial class {2}{3}",
213
+            Accessibility.ForType(entity),
214
+            _code.SpaceAfter(_code.AbstractOption(entity)),
215
+            _code.Escape(entity),
216
+            _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
217
+    }
218
+    
219
+    public string EnumOpening(SimpleType enumType)
220
+    {
221
+        return string.Format(
222
+            CultureInfo.InvariantCulture,
223
+            "{0} enum {1} : {2}",
224
+            Accessibility.ForType(enumType),
225
+            _code.Escape(enumType),
226
+            _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
227
+        }
228
+    
229
+    public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
230
+    {
231
+        var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
232
+        foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
233
+        {
234
+            var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
235
+            var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
236
+            var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
237
+            writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
238
+        }
239
+    }
240
+    
241
+    public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
242
+    {
243
+        var parameters = _typeMapper.GetParameters(edmFunction);
244
+        
245
+        return string.Format(
246
+            CultureInfo.InvariantCulture,
247
+            "{0} IQueryable<{1}> {2}({3})",
248
+            AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
249
+            _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
250
+            _code.Escape(edmFunction),
251
+            string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
252
+    }
253
+    
254
+    public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
255
+    {
256
+        var parameters = _typeMapper.GetParameters(edmFunction);
257
+        
258
+        return string.Format(
259
+            CultureInfo.InvariantCulture,
260
+            "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
261
+            _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
262
+            edmFunction.NamespaceName,
263
+            edmFunction.Name,
264
+            string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
265
+            _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
266
+    }
267
+    
268
+    public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
269
+    {
270
+        var parameters = _typeMapper.GetParameters(edmFunction);
271
+        var returnType = _typeMapper.GetReturnType(edmFunction);
272
+
273
+        var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
274
+        if (includeMergeOption)
275
+        {
276
+            paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
277
+        }
278
+
279
+        return string.Format(
280
+            CultureInfo.InvariantCulture,
281
+            "{0} {1} {2}({3})",
282
+            AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
283
+            returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
284
+            _code.Escape(edmFunction),
285
+            paramList);
286
+    }
287
+    
288
+    public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
289
+    {
290
+        var parameters = _typeMapper.GetParameters(edmFunction);
291
+        var returnType = _typeMapper.GetReturnType(edmFunction);
292
+
293
+        var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
294
+        if (includeMergeOption)
295
+        {
296
+            callParams = ", mergeOption" + callParams;
297
+        }
298
+        
299
+        return string.Format(
300
+            CultureInfo.InvariantCulture,
301
+            "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
302
+            returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
303
+            edmFunction.Name,
304
+            callParams);
305
+    }
306
+    
307
+    public string DbSet(EntitySet entitySet)
308
+    {
309
+        return string.Format(
310
+            CultureInfo.InvariantCulture,
311
+            "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
312
+            Accessibility.ForReadOnlyProperty(entitySet),
313
+            _typeMapper.GetTypeName(entitySet.ElementType),
314
+            _code.Escape(entitySet));
315
+    }
316
+
317
+    public string DbSetInitializer(EntitySet entitySet)
318
+    {
319
+        return string.Format(
320
+            CultureInfo.InvariantCulture,
321
+            "{0} = Set<{1}>();",
322
+            _code.Escape(entitySet),
323
+            _typeMapper.GetTypeName(entitySet.ElementType));
324
+    }
325
+
326
+    public string UsingDirectives(bool inHeader, bool includeCollections = true)
327
+    {
328
+        return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
329
+            ? string.Format(
330
+                CultureInfo.InvariantCulture,
331
+                "{0}using System;{1}" +
332
+                "{2}",
333
+                inHeader ? Environment.NewLine : "",
334
+                includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
335
+                inHeader ? "" : Environment.NewLine)
336
+            : "";
337
+    }
338
+}
339
+
340
+public class TypeMapper
341
+{
342
+    private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
343
+
344
+    private readonly System.Collections.IList _errors;
345
+    private readonly CodeGenerationTools _code;
346
+    private readonly MetadataTools _ef;
347
+
348
+    public static string FixNamespaces(string typeName)
349
+    {
350
+        return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
351
+    }
352
+
353
+    public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
354
+    {
355
+        ArgumentNotNull(code, "code");
356
+        ArgumentNotNull(ef, "ef");
357
+        ArgumentNotNull(errors, "errors");
358
+
359
+        _code = code;
360
+        _ef = ef;
361
+        _errors = errors;
362
+    }
363
+
364
+    public string GetTypeName(TypeUsage typeUsage)
365
+    {
366
+        return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
367
+    }
368
+
369
+    public string GetTypeName(EdmType edmType)
370
+    {
371
+        return GetTypeName(edmType, isNullable: null, modelNamespace: null);
372
+    }
373
+
374
+    public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
375
+    {
376
+        return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
377
+    }
378
+
379
+    public string GetTypeName(EdmType edmType, string modelNamespace)
380
+    {
381
+        return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
382
+    }
383
+
384
+    public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
385
+    {
386
+        if (edmType == null)
387
+        {
388
+            return null;
389
+        }
390
+
391
+        var collectionType = edmType as CollectionType;
392
+        if (collectionType != null)
393
+        {
394
+            return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
395
+        }
396
+
397
+        var typeName = _code.Escape(edmType.MetadataProperties
398
+                                .Where(p => p.Name == ExternalTypeNameAttributeName)
399
+                                .Select(p => (string)p.Value)
400
+                                .FirstOrDefault())
401
+            ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
402
+                _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
403
+                _code.Escape(edmType));
404
+
405
+        if (edmType is StructuralType)
406
+        {
407
+            return typeName;
408
+        }
409
+
410
+        if (edmType is SimpleType)
411
+        {
412
+            var clrType = UnderlyingClrType(edmType);
413
+            if (!IsEnumType(edmType))
414
+            {
415
+                typeName = _code.Escape(clrType);
416
+            }
417
+
418
+            typeName = FixNamespaces(typeName);
419
+
420
+            return clrType.IsValueType && isNullable == true ?
421
+                String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
422
+                typeName;
423
+        }
424
+
425
+        throw new ArgumentException("edmType");
426
+    }
427
+    
428
+    public Type UnderlyingClrType(EdmType edmType)
429
+    {
430
+        ArgumentNotNull(edmType, "edmType");
431
+
432
+        var primitiveType = edmType as PrimitiveType;
433
+        if (primitiveType != null)
434
+        {
435
+            return primitiveType.ClrEquivalentType;
436
+        }
437
+
438
+        if (IsEnumType(edmType))
439
+        {
440
+            return GetEnumUnderlyingType(edmType).ClrEquivalentType;
441
+        }
442
+
443
+        return typeof(object);
444
+    }
445
+    
446
+    public object GetEnumMemberValue(MetadataItem enumMember)
447
+    {
448
+        ArgumentNotNull(enumMember, "enumMember");
449
+        
450
+        var valueProperty = enumMember.GetType().GetProperty("Value");
451
+        return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
452
+    }
453
+    
454
+    public string GetEnumMemberName(MetadataItem enumMember)
455
+    {
456
+        ArgumentNotNull(enumMember, "enumMember");
457
+        
458
+        var nameProperty = enumMember.GetType().GetProperty("Name");
459
+        return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
460
+    }
461
+
462
+    public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
463
+    {
464
+        ArgumentNotNull(enumType, "enumType");
465
+
466
+        var membersProperty = enumType.GetType().GetProperty("Members");
467
+        return membersProperty != null 
468
+            ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
469
+            : Enumerable.Empty<MetadataItem>();
470
+    }
471
+    
472
+    public bool EnumIsFlags(EdmType enumType)
473
+    {
474
+        ArgumentNotNull(enumType, "enumType");
475
+        
476
+        var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
477
+        return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
478
+    }
479
+
480
+    public bool IsEnumType(GlobalItem edmType)
481
+    {
482
+        ArgumentNotNull(edmType, "edmType");
483
+
484
+        return edmType.GetType().Name == "EnumType";
485
+    }
486
+
487
+    public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
488
+    {
489
+        ArgumentNotNull(enumType, "enumType");
490
+
491
+        return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
492
+    }
493
+
494
+    public string CreateLiteral(object value)
495
+    {
496
+        if (value == null || value.GetType() != typeof(TimeSpan))
497
+        {
498
+            return _code.CreateLiteral(value);
499
+        }
500
+
501
+        return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
502
+    }
503
+    
504
+    public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
505
+    {
506
+        ArgumentNotNull(types, "types");
507
+        ArgumentNotNull(sourceFile, "sourceFile");
508
+        
509
+        var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
510
+        if (types.Any(item => !hash.Add(item)))
511
+        {
512
+            _errors.Add(
513
+                new CompilerError(sourceFile, -1, -1, "6023",
514
+                    String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
515
+            return false;
516
+        }
517
+        return true;
518
+    }
519
+    
520
+    public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
521
+    {
522
+        return GetItemsToGenerate<SimpleType>(itemCollection)
523
+            .Where(e => IsEnumType(e));
524
+    }
525
+    
526
+    public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
527
+    {
528
+        return itemCollection
529
+            .OfType<T>()
530
+            .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
531
+            .OrderBy(i => i.Name);
532
+    }
533
+
534
+    public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
535
+    {
536
+        return itemCollection
537
+            .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
538
+            .Select(g => GetGlobalItemName(g));
539
+    }
540
+
541
+    public string GetGlobalItemName(GlobalItem item)
542
+    {
543
+        if (item is EdmType)
544
+        {
545
+            return ((EdmType)item).Name;
546
+        }
547
+        else
548
+        {
549
+            return ((EntityContainer)item).Name;
550
+        }
551
+    }
552
+
553
+    public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
554
+    {
555
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
556
+    }
557
+    
558
+    public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
559
+    {
560
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
561
+    }
562
+    
563
+    public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
564
+    {
565
+        return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
566
+    }
567
+    
568
+    public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
569
+    {
570
+        return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
571
+    }
572
+
573
+    public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
574
+    {
575
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
576
+    }
577
+    
578
+    public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
579
+    {
580
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
581
+    }
582
+
583
+    public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
584
+    {
585
+        return type.NavigationProperties.Where(np => np.DeclaringType == type);
586
+    }
587
+    
588
+    public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
589
+    {
590
+        return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
591
+    }
592
+    
593
+    public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
594
+    {
595
+        ArgumentNotNull(edmFunction, "edmFunction");
596
+
597
+        var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
598
+        return returnParamsProperty == null
599
+            ? edmFunction.ReturnParameter
600
+            : ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
601
+    }
602
+
603
+    public bool IsComposable(EdmFunction edmFunction)
604
+    {
605
+        ArgumentNotNull(edmFunction, "edmFunction");
606
+
607
+        var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
608
+        return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
609
+    }
610
+
611
+    public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
612
+    {
613
+        return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
614
+    }
615
+
616
+    public TypeUsage GetReturnType(EdmFunction edmFunction)
617
+    {
618
+        var returnParam = GetReturnParameter(edmFunction);
619
+        return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
620
+    }
621
+    
622
+    public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
623
+    {
624
+        var returnType = GetReturnType(edmFunction);
625
+        return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
626
+    }
627
+}
628
+
629
+public static void ArgumentNotNull<T>(T arg, string name) where T : class
630
+{
631
+    if (arg == null)
632
+    {
633
+        throw new ArgumentNullException(name);
634
+    }
635
+}
636
+#>

+ 10
- 0
Authentication/DataAccess/UserEntities.Designer.cs 파일 보기

@@ -0,0 +1,10 @@
1
+// T4 code generation is enabled for model 'C:\Users\robin.thoni\Documents\nuget-3ie\Authentication\DataAccess\UserEntities.edmx'. 
2
+// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
3
+// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
4
+// is open in the designer.
5
+
6
+// If no context and entity classes have been generated, it may be because you created an empty model but
7
+// have not yet chosen which version of Entity Framework to use. To generate a context class and entity
8
+// classes for your model, open the model in the designer, right-click on the designer surface, and
9
+// select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
10
+// Item...'.

+ 9
- 0
Authentication/DataAccess/UserEntities.cs 파일 보기

@@ -0,0 +1,9 @@
1
+//------------------------------------------------------------------------------
2
+// <auto-generated>
3
+//     This code was generated from a template.
4
+//
5
+//     Manual changes to this file may cause unexpected behavior in your application.
6
+//     Manual changes to this file will be overwritten if the code is regenerated.
7
+// </auto-generated>
8
+//------------------------------------------------------------------------------
9
+

+ 87
- 0
Authentication/DataAccess/UserEntities.edmx 파일 보기

@@ -0,0 +1,87 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
3
+  <!-- EF Runtime content -->
4
+  <edmx:Runtime>
5
+    <!-- SSDL content -->
6
+    <edmx:StorageModels>
7
+    <Schema Namespace="Model.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2012" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
8
+        <EntityType Name="T_Users">
9
+          <Key>
10
+            <PropertyRef Name="id" />
11
+          </Key>
12
+          <Property Name="id" Type="bigint" Nullable="false" />
13
+          <Property Name="username" Type="nvarchar" MaxLength="50" Nullable="false" />
14
+          <Property Name="password" Type="varchar" MaxLength="120" Nullable="false" />
15
+          <Property Name="salt" Type="varchar" MaxLength="10" Nullable="false" />
16
+          <Property Name="role" Type="int" Nullable="false" />
17
+          <Property Name="firstname" Type="nvarchar" MaxLength="50" />
18
+          <Property Name="lastname" Type="nvarchar" MaxLength="50" />
19
+          <Property Name="profile_id" Type="bigint" />
20
+        </EntityType>
21
+        <EntityContainer Name="ModelStoreContainer">
22
+          <EntitySet Name="T_Users" EntityType="Self.T_Users" Schema="dbo" store:Type="Tables" />
23
+        </EntityContainer>
24
+      </Schema></edmx:StorageModels>
25
+    <!-- CSDL content -->
26
+    <edmx:ConceptualModels>
27
+      <Schema Namespace="Model" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
28
+        <EntityContainer Name="UserEntities" annotation:LazyLoadingEnabled="true" >
29
+          <EntitySet Name="T_Users" EntityType="Model.T_Users" />
30
+        </EntityContainer>
31
+        <EntityType Name="T_Users">
32
+          <Key>
33
+            <PropertyRef Name="id" />
34
+          </Key>
35
+          <Property Name="id" Type="Int64" Nullable="false" />
36
+          <Property Name="username" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
37
+          <Property Name="password" Type="String" Nullable="false" MaxLength="120" FixedLength="false" Unicode="false" />
38
+          <Property Name="salt" Type="String" Nullable="false" MaxLength="10" FixedLength="false" Unicode="false" />
39
+          <Property Name="role" Type="Int32" Nullable="false" />
40
+          <Property Name="firstname" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
41
+          <Property Name="lastname" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
42
+          <Property Name="profile_id" Type="Int64" />
43
+        </EntityType>
44
+      </Schema>
45
+    </edmx:ConceptualModels>
46
+    <!-- C-S mapping content -->
47
+    <edmx:Mappings>
48
+      <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
49
+        <EntityContainerMapping StorageEntityContainer="ModelStoreContainer" CdmEntityContainer="UserEntities" >
50
+          <EntitySetMapping Name="T_Users">
51
+            <EntityTypeMapping TypeName="Model.T_Users">
52
+              <MappingFragment StoreEntitySet="T_Users">
53
+                <ScalarProperty Name="profile_id" ColumnName="profile_id" />
54
+                <ScalarProperty Name="lastname" ColumnName="lastname" />
55
+                <ScalarProperty Name="firstname" ColumnName="firstname" />
56
+                <ScalarProperty Name="role" ColumnName="role" />
57
+                <ScalarProperty Name="salt" ColumnName="salt" />
58
+                <ScalarProperty Name="password" ColumnName="password" />
59
+                <ScalarProperty Name="username" ColumnName="username" />
60
+                <ScalarProperty Name="id" ColumnName="id" />
61
+              </MappingFragment>
62
+            </EntityTypeMapping>
63
+          </EntitySetMapping>
64
+        </EntityContainerMapping>
65
+      </Mapping>
66
+    </edmx:Mappings>
67
+  </edmx:Runtime>
68
+  <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
69
+  <Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
70
+    <Connection>
71
+      <DesignerInfoPropertySet>
72
+        <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
73
+      </DesignerInfoPropertySet>
74
+    </Connection>
75
+    <Options>
76
+      <DesignerInfoPropertySet>
77
+        <DesignerProperty Name="ValidateOnBuild" Value="true" />
78
+        <DesignerProperty Name="EnablePluralization" Value="false" />
79
+        <DesignerProperty Name="IncludeForeignKeysInModel" Value="true" />
80
+        <DesignerProperty Name="UseLegacyProvider" Value="false" />
81
+        <DesignerProperty Name="CodeGenerationStrategy" Value="None" />
82
+      </DesignerInfoPropertySet>
83
+    </Options>
84
+    <!-- Diagram content (shape and connector positions) -->
85
+    <Diagrams></Diagrams>
86
+  </Designer>
87
+</edmx:Edmx>

+ 12
- 0
Authentication/DataAccess/UserEntities.edmx.diagram 파일 보기

@@ -0,0 +1,12 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
3
+ <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
4
+  <edmx:Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
5
+    <!-- Diagram content (shape and connector positions) -->
6
+    <edmx:Diagrams>
7
+      <Diagram DiagramId="8373c5f936d245f7906c672cdd7eb58a" Name="Diagram1" >
8
+        <EntityTypeShape EntityType="Model.T_Users" Width="1.5" PointX="0.75" PointY="0.75" />
9
+      </Diagram>
10
+    </edmx:Diagrams>
11
+  </edmx:Designer>
12
+</edmx:Edmx>

+ 726
- 0
Authentication/DataAccess/UserEntities.tt 파일 보기

@@ -0,0 +1,726 @@
1
+<#@ template language="C#" debug="false" hostspecific="true"#>
2
+<#@ include file="EF6.Utility.CS.ttinclude"#><#@ 
3
+ output extension=".cs"#><#
4
+
5
+const string inputFile = @"UserEntities.edmx";
6
+var textTransform = DynamicTextTransformation.Create(this);
7
+var code = new CodeGenerationTools(this);
8
+var ef = new MetadataTools(this);
9
+var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
10
+var	fileManager = EntityFrameworkTemplateFileManager.Create(this);
11
+var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
12
+var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
13
+
14
+if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
15
+{
16
+    return string.Empty;
17
+}
18
+
19
+WriteHeader(codeStringGenerator, fileManager);
20
+
21
+foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
22
+{
23
+    fileManager.StartNewFile(entity.Name + ".cs");
24
+    BeginNamespace(code);
25
+#>
26
+<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
27
+<#=codeStringGenerator.EntityClassOpening(entity)#>
28
+{
29
+<#
30
+    var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
31
+    var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
32
+    var complexProperties = typeMapper.GetComplexProperties(entity);
33
+
34
+    if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
35
+    {
36
+#>
37
+    public <#=code.Escape(entity)#>()
38
+    {
39
+<#
40
+        foreach (var edmProperty in propertiesWithDefaultValues)
41
+        {
42
+#>
43
+        this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
44
+<#
45
+        }
46
+
47
+        foreach (var navigationProperty in collectionNavigationProperties)
48
+        {
49
+#>
50
+        this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
51
+<#
52
+        }
53
+
54
+        foreach (var complexProperty in complexProperties)
55
+        {
56
+#>
57
+        this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
58
+<#
59
+        }
60
+#>
61
+    }
62
+
63
+<#
64
+    }
65
+
66
+    var simpleProperties = typeMapper.GetSimpleProperties(entity);
67
+    if (simpleProperties.Any())
68
+    {
69
+        foreach (var edmProperty in simpleProperties)
70
+        {
71
+#>
72
+    <#=codeStringGenerator.Property(edmProperty)#>
73
+<#
74
+        }
75
+    }
76
+
77
+    if (complexProperties.Any())
78
+    {
79
+#>
80
+
81
+<#
82
+        foreach(var complexProperty in complexProperties)
83
+        {
84
+#>
85
+    <#=codeStringGenerator.Property(complexProperty)#>
86
+<#
87
+        }
88
+    }
89
+
90
+    var navigationProperties = typeMapper.GetNavigationProperties(entity);
91
+    if (navigationProperties.Any())
92
+    {
93
+#>
94
+
95
+<#
96
+        foreach (var navigationProperty in navigationProperties)
97
+        {
98
+#>
99
+    <#=codeStringGenerator.NavigationProperty(navigationProperty)#>
100
+<#
101
+        }
102
+    }
103
+#>
104
+}
105
+<#
106
+    EndNamespace(code);
107
+}
108
+
109
+foreach (var complex in typeMapper.GetItemsToGenerate<ComplexType>(itemCollection))
110
+{
111
+    fileManager.StartNewFile(complex.Name + ".cs");
112
+    BeginNamespace(code);
113
+#>
114
+<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
115
+<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
116
+{
117
+<#
118
+    var complexProperties = typeMapper.GetComplexProperties(complex);
119
+    var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
120
+
121
+    if (propertiesWithDefaultValues.Any() || complexProperties.Any())
122
+    {
123
+#>
124
+    public <#=code.Escape(complex)#>()
125
+    {
126
+<#
127
+        foreach (var edmProperty in propertiesWithDefaultValues)
128
+        {
129
+#>
130
+        this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
131
+<#
132
+        }
133
+
134
+        foreach (var complexProperty in complexProperties)
135
+        {
136
+#>
137
+        this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
138
+<#
139
+        }
140
+#>
141
+    }
142
+
143
+<#
144
+    }
145
+
146
+    var simpleProperties = typeMapper.GetSimpleProperties(complex);
147
+    if (simpleProperties.Any())
148
+    {
149
+        foreach(var edmProperty in simpleProperties)
150
+        {
151
+#>
152
+    <#=codeStringGenerator.Property(edmProperty)#>
153
+<#
154
+        }
155
+    }
156
+
157
+    if (complexProperties.Any())
158
+    {
159
+#>
160
+
161
+<#
162
+        foreach(var edmProperty in complexProperties)
163
+        {
164
+#>
165
+    <#=codeStringGenerator.Property(edmProperty)#>
166
+<#
167
+        }
168
+    }
169
+#>
170
+}
171
+<#
172
+    EndNamespace(code);
173
+}
174
+
175
+foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
176
+{
177
+    fileManager.StartNewFile(enumType.Name + ".cs");
178
+    BeginNamespace(code);
179
+#>
180
+<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
181
+<#
182
+    if (typeMapper.EnumIsFlags(enumType))
183
+    {
184
+#>
185
+[Flags]
186
+<#
187
+    }
188
+#>
189
+<#=codeStringGenerator.EnumOpening(enumType)#>
190
+{
191
+<#
192
+    var foundOne = false;
193
+    
194
+    foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
195
+    {
196
+        foundOne = true;
197
+#>
198
+    <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
199
+<#
200
+    }
201
+
202
+    if (foundOne)
203
+    {
204
+        this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
205
+    }
206
+#>
207
+}
208
+<#
209
+    EndNamespace(code);
210
+}
211
+
212
+fileManager.Process();
213
+
214
+#>
215
+<#+
216
+
217
+public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
218
+{
219
+    fileManager.StartHeader();
220
+#>
221
+//------------------------------------------------------------------------------
222
+// <auto-generated>
223
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
224
+//
225
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
226
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
227
+// </auto-generated>
228
+//------------------------------------------------------------------------------
229
+<#=codeStringGenerator.UsingDirectives(inHeader: true)#>
230
+<#+
231
+    fileManager.EndBlock();
232
+}
233
+
234
+public void BeginNamespace(CodeGenerationTools code)
235
+{
236
+    var codeNamespace = code.VsNamespaceSuggestion();
237
+    if (!String.IsNullOrEmpty(codeNamespace))
238
+    {
239
+#>
240
+namespace <#=code.EscapeNamespace(codeNamespace)#>
241
+{
242
+<#+
243
+        PushIndent("    ");
244
+    }
245
+}
246
+
247
+public void EndNamespace(CodeGenerationTools code)
248
+{
249
+    if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
250
+    {
251
+        PopIndent();
252
+#>
253
+}
254
+<#+
255
+    }
256
+}
257
+
258
+public const string TemplateId = "CSharp_DbContext_Types_EF6";
259
+
260
+public class CodeStringGenerator
261
+{
262
+    private readonly CodeGenerationTools _code;
263
+    private readonly TypeMapper _typeMapper;
264
+    private readonly MetadataTools _ef;
265
+
266
+    public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
267
+    {
268
+        ArgumentNotNull(code, "code");
269
+        ArgumentNotNull(typeMapper, "typeMapper");
270
+        ArgumentNotNull(ef, "ef");
271
+
272
+        _code = code;
273
+        _typeMapper = typeMapper;
274
+        _ef = ef;
275
+    }
276
+
277
+    public string Property(EdmProperty edmProperty)
278
+    {
279
+        return string.Format(
280
+            CultureInfo.InvariantCulture,
281
+            "{0} {1} {2} {{ {3}get; {4}set; }}",
282
+            Accessibility.ForProperty(edmProperty),
283
+            _typeMapper.GetTypeName(edmProperty.TypeUsage),
284
+            _code.Escape(edmProperty),
285
+            _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
286
+            _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
287
+    }
288
+
289
+    public string NavigationProperty(NavigationProperty navProp)
290
+    {
291
+        var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
292
+        return string.Format(
293
+            CultureInfo.InvariantCulture,
294
+            "{0} {1} {2} {{ {3}get; {4}set; }}",
295
+            AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
296
+            navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
297
+            _code.Escape(navProp),
298
+            _code.SpaceAfter(Accessibility.ForGetter(navProp)),
299
+            _code.SpaceAfter(Accessibility.ForSetter(navProp)));
300
+    }
301
+    
302
+    public string AccessibilityAndVirtual(string accessibility)
303
+    {
304
+        return accessibility + (accessibility != "private" ? " virtual" : "");
305
+    }
306
+    
307
+    public string EntityClassOpening(EntityType entity)
308
+    {
309
+        return string.Format(
310
+            CultureInfo.InvariantCulture,
311
+            "{0} {1}partial class {2}{3}",
312
+            Accessibility.ForType(entity),
313
+            _code.SpaceAfter(_code.AbstractOption(entity)),
314
+            _code.Escape(entity),
315
+            _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
316
+    }
317
+    
318
+    public string EnumOpening(SimpleType enumType)
319
+    {
320
+        return string.Format(
321
+            CultureInfo.InvariantCulture,
322
+            "{0} enum {1} : {2}",
323
+            Accessibility.ForType(enumType),
324
+            _code.Escape(enumType),
325
+            _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
326
+        }
327
+    
328
+    public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
329
+    {
330
+        var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
331
+        foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
332
+        {
333
+            var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
334
+            var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
335
+            var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
336
+            writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
337
+        }
338
+    }
339
+    
340
+    public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
341
+    {
342
+        var parameters = _typeMapper.GetParameters(edmFunction);
343
+        
344
+        return string.Format(
345
+            CultureInfo.InvariantCulture,
346
+            "{0} IQueryable<{1}> {2}({3})",
347
+            AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
348
+            _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
349
+            _code.Escape(edmFunction),
350
+            string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
351
+    }
352
+    
353
+    public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
354
+    {
355
+        var parameters = _typeMapper.GetParameters(edmFunction);
356
+        
357
+        return string.Format(
358
+            CultureInfo.InvariantCulture,
359
+            "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
360
+            _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
361
+            edmFunction.NamespaceName,
362
+            edmFunction.Name,
363
+            string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
364
+            _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
365
+    }
366
+    
367
+    public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
368
+    {
369
+        var parameters = _typeMapper.GetParameters(edmFunction);
370
+        var returnType = _typeMapper.GetReturnType(edmFunction);
371
+
372
+        var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
373
+        if (includeMergeOption)
374
+        {
375
+            paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
376
+        }
377
+
378
+        return string.Format(
379
+            CultureInfo.InvariantCulture,
380
+            "{0} {1} {2}({3})",
381
+            AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
382
+            returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
383
+            _code.Escape(edmFunction),
384
+            paramList);
385
+    }
386
+    
387
+    public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
388
+    {
389
+        var parameters = _typeMapper.GetParameters(edmFunction);
390
+        var returnType = _typeMapper.GetReturnType(edmFunction);
391
+
392
+        var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
393
+        if (includeMergeOption)
394
+        {
395
+            callParams = ", mergeOption" + callParams;
396
+        }
397
+        
398
+        return string.Format(
399
+            CultureInfo.InvariantCulture,
400
+            "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
401
+            returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
402
+            edmFunction.Name,
403
+            callParams);
404
+    }
405
+    
406
+    public string DbSet(EntitySet entitySet)
407
+    {
408
+        return string.Format(
409
+            CultureInfo.InvariantCulture,
410
+            "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
411
+            Accessibility.ForReadOnlyProperty(entitySet),
412
+            _typeMapper.GetTypeName(entitySet.ElementType),
413
+            _code.Escape(entitySet));
414
+    }
415
+
416
+    public string UsingDirectives(bool inHeader, bool includeCollections = true)
417
+    {
418
+        return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
419
+            ? string.Format(
420
+                CultureInfo.InvariantCulture,
421
+                "{0}using System;{1}" +
422
+                "{2}",
423
+                inHeader ? Environment.NewLine : "",
424
+                includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
425
+                inHeader ? "" : Environment.NewLine)
426
+            : "";
427
+    }
428
+}
429
+
430
+public class TypeMapper
431
+{
432
+    private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
433
+
434
+    private readonly System.Collections.IList _errors;
435
+    private readonly CodeGenerationTools _code;
436
+    private readonly MetadataTools _ef;
437
+
438
+    public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
439
+    {
440
+        ArgumentNotNull(code, "code");
441
+        ArgumentNotNull(ef, "ef");
442
+        ArgumentNotNull(errors, "errors");
443
+
444
+        _code = code;
445
+        _ef = ef;
446
+        _errors = errors;
447
+    }
448
+
449
+    public static string FixNamespaces(string typeName)
450
+    {
451
+        return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
452
+    }
453
+
454
+    public string GetTypeName(TypeUsage typeUsage)
455
+    {
456
+        return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
457
+    }
458
+
459
+    public string GetTypeName(EdmType edmType)
460
+    {
461
+        return GetTypeName(edmType, isNullable: null, modelNamespace: null);
462
+    }
463
+
464
+    public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
465
+    {
466
+        return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
467
+    }
468
+
469
+    public string GetTypeName(EdmType edmType, string modelNamespace)
470
+    {
471
+        return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
472
+    }
473
+
474
+    public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
475
+    {
476
+        if (edmType == null)
477
+        {
478
+            return null;
479
+        }
480
+
481
+        var collectionType = edmType as CollectionType;
482
+        if (collectionType != null)
483
+        {
484
+            return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
485
+        }
486
+
487
+        var typeName = _code.Escape(edmType.MetadataProperties
488
+                                .Where(p => p.Name == ExternalTypeNameAttributeName)
489
+                                .Select(p => (string)p.Value)
490
+                                .FirstOrDefault())
491
+            ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
492
+                _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
493
+                _code.Escape(edmType));
494
+
495
+        if (edmType is StructuralType)
496
+        {
497
+            return typeName;
498
+        }
499
+
500
+        if (edmType is SimpleType)
501
+        {
502
+            var clrType = UnderlyingClrType(edmType);
503
+            if (!IsEnumType(edmType))
504
+            {
505
+                typeName = _code.Escape(clrType);
506
+            }
507
+
508
+            typeName = FixNamespaces(typeName);
509
+
510
+            return clrType.IsValueType && isNullable == true ?
511
+                String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
512
+                typeName;
513
+        }
514
+
515
+        throw new ArgumentException("edmType");
516
+    }
517
+    
518
+    public Type UnderlyingClrType(EdmType edmType)
519
+    {
520
+        ArgumentNotNull(edmType, "edmType");
521
+
522
+        var primitiveType = edmType as PrimitiveType;
523
+        if (primitiveType != null)
524
+        {
525
+            return primitiveType.ClrEquivalentType;
526
+        }
527
+
528
+        if (IsEnumType(edmType))
529
+        {
530
+            return GetEnumUnderlyingType(edmType).ClrEquivalentType;
531
+        }
532
+
533
+        return typeof(object);
534
+    }
535
+    
536
+    public object GetEnumMemberValue(MetadataItem enumMember)
537
+    {
538
+        ArgumentNotNull(enumMember, "enumMember");
539
+        
540
+        var valueProperty = enumMember.GetType().GetProperty("Value");
541
+        return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
542
+    }
543
+    
544
+    public string GetEnumMemberName(MetadataItem enumMember)
545
+    {
546
+        ArgumentNotNull(enumMember, "enumMember");
547
+        
548
+        var nameProperty = enumMember.GetType().GetProperty("Name");
549
+        return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
550
+    }
551
+
552
+    public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
553
+    {
554
+        ArgumentNotNull(enumType, "enumType");
555
+
556
+        var membersProperty = enumType.GetType().GetProperty("Members");
557
+        return membersProperty != null 
558
+            ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
559
+            : Enumerable.Empty<MetadataItem>();
560
+    }
561
+    
562
+    public bool EnumIsFlags(EdmType enumType)
563
+    {
564
+        ArgumentNotNull(enumType, "enumType");
565
+        
566
+        var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
567
+        return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
568
+    }
569
+
570
+    public bool IsEnumType(GlobalItem edmType)
571
+    {
572
+        ArgumentNotNull(edmType, "edmType");
573
+
574
+        return edmType.GetType().Name == "EnumType";
575
+    }
576
+
577
+    public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
578
+    {
579
+        ArgumentNotNull(enumType, "enumType");
580
+
581
+        return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
582
+    }
583
+
584
+    public string CreateLiteral(object value)
585
+    {
586
+        if (value == null || value.GetType() != typeof(TimeSpan))
587
+        {
588
+            return _code.CreateLiteral(value);
589
+        }
590
+
591
+        return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
592
+    }
593
+    
594
+    public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
595
+    {
596
+        ArgumentNotNull(types, "types");
597
+        ArgumentNotNull(sourceFile, "sourceFile");
598
+        
599
+        var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
600
+        if (types.Any(item => !hash.Add(item)))
601
+        {
602
+            _errors.Add(
603
+                new CompilerError(sourceFile, -1, -1, "6023",
604
+                    String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
605
+            return false;
606
+        }
607
+        return true;
608
+    }
609
+    
610
+    public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
611
+    {
612
+        return GetItemsToGenerate<SimpleType>(itemCollection)
613
+            .Where(e => IsEnumType(e));
614
+    }
615
+    
616
+    public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
617
+    {
618
+        return itemCollection
619
+            .OfType<T>()
620
+            .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
621
+            .OrderBy(i => i.Name);
622
+    }
623
+
624
+    public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
625
+    {
626
+        return itemCollection
627
+            .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
628
+            .Select(g => GetGlobalItemName(g));
629
+    }
630
+
631
+    public string GetGlobalItemName(GlobalItem item)
632
+    {
633
+        if (item is EdmType)
634
+        {
635
+            return ((EdmType)item).Name;
636
+        }
637
+        else
638
+        {
639
+            return ((EntityContainer)item).Name;
640
+        }
641
+    }
642
+
643
+    public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
644
+    {
645
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
646
+    }
647
+    
648
+    public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
649
+    {
650
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
651
+    }
652
+    
653
+    public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
654
+    {
655
+        return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
656
+    }
657
+    
658
+    public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
659
+    {
660
+        return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
661
+    }
662
+
663
+    public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
664
+    {
665
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
666
+    }
667
+    
668
+    public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
669
+    {
670
+        return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
671
+    }
672
+
673
+    public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
674
+    {
675
+        return type.NavigationProperties.Where(np => np.DeclaringType == type);
676
+    }
677
+    
678
+    public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
679
+    {
680
+        return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
681
+    }
682
+    
683
+    public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
684
+    {
685
+        ArgumentNotNull(edmFunction, "edmFunction");
686
+
687
+        var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
688
+        return returnParamsProperty == null
689
+            ? edmFunction.ReturnParameter
690
+            : ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
691
+    }
692
+
693
+    public bool IsComposable(EdmFunction edmFunction)
694
+    {
695
+        ArgumentNotNull(edmFunction, "edmFunction");
696
+
697
+        var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
698
+        return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
699
+    }
700
+
701
+    public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
702
+    {
703
+        return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
704
+    }
705
+
706
+    public TypeUsage GetReturnType(EdmFunction edmFunction)
707
+    {
708
+        var returnParam = GetReturnParameter(edmFunction);
709
+        return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
710
+    }
711
+    
712
+    public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
713
+    {
714
+        var returnType = GetReturnType(edmFunction);
715
+        return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
716
+    }
717
+}
718
+
719
+public static void ArgumentNotNull<T>(T arg, string name) where T : class
720
+{
721
+    if (arg == null)
722
+    {
723
+        throw new ArgumentNullException(name);
724
+    }
725
+}
726
+#>

+ 10
- 1
Authentication/packages.config 파일 보기

@@ -1,7 +1,16 @@
1 1
 <?xml version="1.0" encoding="utf-8"?>
2 2
 <packages>
3
+  <package id="3ieWebApiUtils.dll" version="5.0.0" targetFramework="net45" />
4
+  <package id="DynamicQuery" version="1.0" targetFramework="net45" />
5
+  <package id="EnterpriseLibrary.Common" version="6.0.1304.0" targetFramework="net45" />
6
+  <package id="EnterpriseLibrary.Data" version="6.0.1304.0" targetFramework="net45" />
7
+  <package id="EnterpriseLibrary.Logging" version="6.0.1304.0" targetFramework="net45" />
8
+  <package id="EnterpriseLibrary.Logging.Database" version="6.0.1304.0" targetFramework="net45" />
9
+  <package id="EntityFramework" version="6.1.3" targetFramework="net45" />
10
+  <package id="Logs.dll" version="1.2.2" targetFramework="net45" />
3 11
   <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
4 12
   <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
5
-  <package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
13
+  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
14
+  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
6 15
   <package id="System.IdentityModel.Tokens.Jwt" version="4.0.2.205111437" targetFramework="net45" />
7 16
 </packages>

Loading…
취소
저장