develop #3
13
.idea/.idea.AGSS/.idea/dataSources.xml
generated
Normal file
13
.idea/.idea.AGSS/.idea/dataSources.xml
generated
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
|
<data-source source="LOCAL" name="postgres@localhost" uuid="57f546cc-1ce0-48b6-9e0c-aac2d79175a9">
|
||||||
|
<driver-ref>postgresql</driver-ref>
|
||||||
|
<synchronize>true</synchronize>
|
||||||
|
<configured-by-url>true</configured-by-url>
|
||||||
|
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||||
|
<jdbc-url>jdbc:postgresql://localhost:5432/postgres?password=luolan12323&user=postgres</jdbc-url>
|
||||||
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
|
</data-source>
|
||||||
|
</component>
|
||||||
|
</project>
|
14
.idea/.idea.AGSS/.idea/deployment.xml
generated
Normal file
14
.idea/.idea.AGSS/.idea/deployment.xml
generated
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="PublishConfigData" serverName="zeronodebackend" remoteFilesAllowedToDisappearOnAutoupload="false">
|
||||||
|
<serverData>
|
||||||
|
<paths name="zeronodebackend">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
</serverData>
|
||||||
|
</component>
|
||||||
|
</project>
|
7
.idea/.idea.AGSS/.idea/dictionaries/project.xml
generated
Normal file
7
.idea/.idea.AGSS/.idea/dictionaries/project.xml
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="project">
|
||||||
|
<words>
|
||||||
|
<w>agss</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
10
.idea/.idea.AGSS/.idea/indexLayout.xml
generated
Normal file
10
.idea/.idea.AGSS/.idea/indexLayout.xml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="UserContentModel">
|
||||||
|
<attachedFolders />
|
||||||
|
<explicitIncludes>
|
||||||
|
<Path>script.sql</Path>
|
||||||
|
</explicitIncludes>
|
||||||
|
<explicitExcludes />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/.idea.AGSS/.idea/vcs.xml
generated
Normal file
6
.idea/.idea.AGSS/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
14
.idea/.idea.AGSS/.idea/webServers.xml
generated
Normal file
14
.idea/.idea.AGSS/.idea/webServers.xml
generated
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="WebServers">
|
||||||
|
<option name="servers">
|
||||||
|
<webServer id="e42f833b-2bef-4f83-be49-75a92fe7c98e" name="zeronodebackend" url="http://47.94.224.191/">
|
||||||
|
<fileTransfer rootFolder="/zeronode/backend" host="47.94.224.191" port="2121">
|
||||||
|
<advancedOptions>
|
||||||
|
<advancedOptions dataProtectionLevel="Private" passiveMode="true" shareSSLContext="true" />
|
||||||
|
</advancedOptions>
|
||||||
|
</fileTransfer>
|
||||||
|
</webServer>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
997
.idea/config/applicationhost.config
generated
Normal file
997
.idea/config/applicationhost.config
generated
Normal file
@ -0,0 +1,997 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
IIS configuration sections.
|
||||||
|
|
||||||
|
For schema documentation, see
|
||||||
|
%IIS_BIN%\config\schema\IIS_schema.xml.
|
||||||
|
|
||||||
|
Please make a backup of this file before making any changes to it.
|
||||||
|
|
||||||
|
NOTE: The following environment variables are available to be used
|
||||||
|
within this file and are understood by the IIS Express.
|
||||||
|
|
||||||
|
%IIS_USER_HOME% - The IIS Express home directory for the user
|
||||||
|
%IIS_SITES_HOME% - The default home directory for sites
|
||||||
|
%IIS_BIN% - The location of the IIS Express binaries
|
||||||
|
%SYSTEMDRIVE% - The drive letter of %IIS_BIN%
|
||||||
|
|
||||||
|
-->
|
||||||
|
<configuration>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <configSections> section controls the registration of sections.
|
||||||
|
Section is the basic unit of deployment, locking, searching and
|
||||||
|
containment for configuration settings.
|
||||||
|
|
||||||
|
Every section belongs to one section group.
|
||||||
|
A section group is a container of logically-related sections.
|
||||||
|
|
||||||
|
Sections cannot be nested.
|
||||||
|
Section groups may be nested.
|
||||||
|
|
||||||
|
<section
|
||||||
|
name="" [Required, Collection Key] [XML name of the section]
|
||||||
|
allowDefinition="Everywhere" [MachineOnly|MachineToApplication|AppHostOnly|Everywhere] [Level where it can be set]
|
||||||
|
overrideModeDefault="Allow" [Allow|Deny] [Default delegation mode]
|
||||||
|
allowLocation="true" [true|false] [Allowed in location tags]
|
||||||
|
/>
|
||||||
|
|
||||||
|
The recommended way to unlock sections is by using a location tag:
|
||||||
|
<location path="Default Web Site" overrideMode="Allow">
|
||||||
|
<system.webServer>
|
||||||
|
<asp />
|
||||||
|
</system.webServer>
|
||||||
|
</location>
|
||||||
|
|
||||||
|
-->
|
||||||
|
<configSections>
|
||||||
|
<sectionGroup name="system.applicationHost">
|
||||||
|
<section name="applicationPools" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="configHistory" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="customMetadata" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="listenerAdapters" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="log" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="serviceAutoStartProviders" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="sites" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="webLimits" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<sectionGroup name="system.webServer">
|
||||||
|
<section name="asp" overrideModeDefault="Deny" />
|
||||||
|
<section name="caching" overrideModeDefault="Allow" />
|
||||||
|
<section name="cgi" overrideModeDefault="Deny" />
|
||||||
|
<section name="defaultDocument" overrideModeDefault="Allow" />
|
||||||
|
<section name="directoryBrowse" overrideModeDefault="Allow" />
|
||||||
|
<section name="fastCgi" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="globalModules" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="handlers" overrideModeDefault="Deny" />
|
||||||
|
<section name="httpCompression" overrideModeDefault="Allow" allowDefinition="Everywhere" />
|
||||||
|
<section name="httpErrors" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpLogging" overrideModeDefault="Deny" />
|
||||||
|
<section name="httpProtocol" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpRedirect" overrideModeDefault="Allow" />
|
||||||
|
<section name="httpTracing" overrideModeDefault="Deny" />
|
||||||
|
<section name="isapiFilters" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||||
|
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
|
||||||
|
<section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
|
||||||
|
<section name="odbcLogging" overrideModeDefault="Deny" />
|
||||||
|
<sectionGroup name="security">
|
||||||
|
<section name="access" overrideModeDefault="Deny" />
|
||||||
|
<section name="applicationDependencies" overrideModeDefault="Deny" />
|
||||||
|
<sectionGroup name="authentication">
|
||||||
|
<section name="anonymousAuthentication" overrideModeDefault="Allow" />
|
||||||
|
<section name="basicAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="clientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="digestAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="iisClientCertificateMappingAuthentication" overrideModeDefault="Deny" />
|
||||||
|
<section name="windowsAuthentication" overrideModeDefault="Allow" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="authorization" overrideModeDefault="Allow" />
|
||||||
|
<section name="ipSecurity" overrideModeDefault="Deny" />
|
||||||
|
<section name="dynamicIpSecurity" overrideModeDefault="Deny" />
|
||||||
|
<section name="isapiCgiRestriction" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
|
||||||
|
<section name="requestFiltering" overrideModeDefault="Allow" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="serverRuntime" overrideModeDefault="Deny" />
|
||||||
|
<section name="serverSideInclude" overrideModeDefault="Deny" />
|
||||||
|
<section name="staticContent" overrideModeDefault="Allow" />
|
||||||
|
<sectionGroup name="tracing">
|
||||||
|
<section name="traceFailedRequests" overrideModeDefault="Allow" />
|
||||||
|
<section name="traceProviderDefinitions" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="urlCompression" overrideModeDefault="Allow" />
|
||||||
|
<section name="validation" overrideModeDefault="Allow" />
|
||||||
|
<sectionGroup name="webdav">
|
||||||
|
<section name="globalSettings" overrideModeDefault="Deny" />
|
||||||
|
<section name="authoring" overrideModeDefault="Deny" />
|
||||||
|
<section name="authoringRules" overrideModeDefault="Deny" />
|
||||||
|
</sectionGroup>
|
||||||
|
<sectionGroup name="rewrite">
|
||||||
|
<section name="allowedServerVariables" overrideModeDefault="Deny" />
|
||||||
|
<section name="rules" overrideModeDefault="Allow" />
|
||||||
|
<section name="outboundRules" overrideModeDefault="Allow" />
|
||||||
|
<section name="globalRules" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
|
||||||
|
<section name="providers" overrideModeDefault="Allow" />
|
||||||
|
<section name="rewriteMaps" overrideModeDefault="Allow" />
|
||||||
|
</sectionGroup>
|
||||||
|
<section name="webSocket" overrideModeDefault="Deny" />
|
||||||
|
<section name="aspNetCore" overrideModeDefault="Allow" />
|
||||||
|
</sectionGroup>
|
||||||
|
</configSections>
|
||||||
|
<configProtectedData>
|
||||||
|
<providers>
|
||||||
|
<add name="IISWASOnlyRsaProvider" type="" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
|
||||||
|
<add name="AesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisConfigurationKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAA/HKxkz6alrlAPez0IUgujj/6k3WxCDriHp6jvpv3yEZmo7h6SMzGLxo4mTrIQVHSkB7tmElHKfUFTzE2BWF7nFWHY6Z6qmGBauFzwJMwESjril7Gjz69RBFH259HQ6aRDq9Xfx7U7H4HtdmnKNqGjgl/hwPQBGeIlWiDh+sYv3vKB0QU971tjX6H2B+9armlnC8UOuA6JYMDMI/VLLL16sng0fWAy5JYe0YVABVjiAWDW264RZW9Tr1Oax4qHZKg+SdjULxeOc2YmpX+d0yeITo1HkPF1hN1gHpIPIUDo05ilHUNfR3OkjVCIQK4cFKCq1s8NH+y+13MxUC4Fn1AlQ==" />
|
||||||
|
<add name="IISWASOnlyAesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAALmU8lTC+v2qtfQiiiquvvLpUQqKLEXs+jSKoWCM/uPhyB++k4dwug19mGidNK5FYiWK2KYE1yhjVJcbp12E98Q0R2nT7eBiCMY2JairxQ591rqABK7keGaIjwH7PwGzSpILl3RJ4YFvJ/7ZXEJxeDZIjW8ZxWVXx+/VyHs9U3WguLEkgMUX3jrxJi8LouxaIVPJAv/YQ1ZCWs8zImitxX/C/7o7yaIxznfsN5nGQzQfpUDPeby99aw2zPVTtZI2LaWIBON8guABvZ6JtJVDWmfdK6sodbnwdZkr6/Z2rfvamT1dC1SpQrGG7ulR/f9/GXvCaW10ZVKxekBF/CYlNMg==" />
|
||||||
|
</providers>
|
||||||
|
</configProtectedData>
|
||||||
|
<system.applicationHost>
|
||||||
|
<applicationPools>
|
||||||
|
<add name="Clr4IntegratedAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||||
|
<add name="Clr4ClassicAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||||
|
<add name="Clr2IntegratedAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||||
|
<add name="Clr2ClassicAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
|
||||||
|
<add name="UnmanagedClassicAppPool" managedRuntimeVersion="" managedPipelineMode="Classic" autoStart="true" />
|
||||||
|
<applicationPoolDefaults managedRuntimeVersion="v4.0">
|
||||||
|
<processModel loadUserProfile="true" setProfileEnvironment="false" />
|
||||||
|
</applicationPoolDefaults>
|
||||||
|
<add name="AGSS AppPool" managedRuntimeVersion="" />
|
||||||
|
</applicationPools>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <listenerAdapters> section defines the protocols with which the
|
||||||
|
Windows Process Activation Service (WAS) binds.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<listenerAdapters>
|
||||||
|
<add name="http" />
|
||||||
|
</listenerAdapters>
|
||||||
|
<sites>
|
||||||
|
<siteDefaults>
|
||||||
|
<!-- To enable logging, please change the below attribute "enabled" to "true" -->
|
||||||
|
<logFile logFormat="W3C" directory="%AppData%\Microsoft\IISExpressLogs" enabled="false" />
|
||||||
|
<traceFailedRequestsLogging directory="%AppData%\Microsoft" enabled="false" maxLogFileSizeKB="1024" />
|
||||||
|
</siteDefaults>
|
||||||
|
<applicationDefaults applicationPool="Clr4IntegratedAppPool" />
|
||||||
|
<virtualDirectoryDefaults allowSubDirConfig="true" />
|
||||||
|
<site name="AGSS" id="1">
|
||||||
|
<application path="/" applicationPool="AGSS AppPool">
|
||||||
|
<virtualDirectory path="/" physicalPath="C:\Users\admin\source\repos\AGSS\AGSS" />
|
||||||
|
</application>
|
||||||
|
<bindings>
|
||||||
|
<binding protocol="http" bindingInformation="*:26445:localhost" />
|
||||||
|
<binding protocol="https" bindingInformation="*:44339:localhost" />
|
||||||
|
</bindings>
|
||||||
|
</site>
|
||||||
|
</sites>
|
||||||
|
<webLimits />
|
||||||
|
</system.applicationHost>
|
||||||
|
<system.webServer>
|
||||||
|
<serverRuntime />
|
||||||
|
<asp scriptErrorSentToBrowser="true">
|
||||||
|
<cache diskTemplateCacheDirectory="%TEMP%\iisexpress\ASP Compiled Templates" />
|
||||||
|
<limits />
|
||||||
|
</asp>
|
||||||
|
<caching enabled="true" enableKernelCache="true"></caching>
|
||||||
|
<cgi />
|
||||||
|
<defaultDocument enabled="true">
|
||||||
|
<files>
|
||||||
|
<add value="Default.htm" />
|
||||||
|
<add value="Default.asp" />
|
||||||
|
<add value="index.htm" />
|
||||||
|
<add value="index.html" />
|
||||||
|
<add value="iisstart.htm" />
|
||||||
|
<add value="default.aspx" />
|
||||||
|
</files>
|
||||||
|
</defaultDocument>
|
||||||
|
<directoryBrowse enabled="false" />
|
||||||
|
<fastCgi />
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The <globalModules> section defines all native-code modules.
|
||||||
|
To enable a module, specify it in the <modules> section.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<globalModules>
|
||||||
|
<add name="HttpLoggingModule" image="%IIS_BIN%\loghttp.dll" />
|
||||||
|
<add name="UriCacheModule" image="%IIS_BIN%\cachuri.dll" />
|
||||||
|
<add name="TokenCacheModule" image="%IIS_BIN%\cachtokn.dll" />
|
||||||
|
<add name="DynamicCompressionModule" image="%IIS_BIN%\compdyn.dll" />
|
||||||
|
<add name="StaticCompressionModule" image="%IIS_BIN%\compstat.dll" />
|
||||||
|
<add name="DefaultDocumentModule" image="%IIS_BIN%\defdoc.dll" />
|
||||||
|
<add name="DirectoryListingModule" image="%IIS_BIN%\dirlist.dll" />
|
||||||
|
<add name="ProtocolSupportModule" image="%IIS_BIN%\protsup.dll" />
|
||||||
|
<add name="HttpRedirectionModule" image="%IIS_BIN%\redirect.dll" />
|
||||||
|
<add name="ServerSideIncludeModule" image="%IIS_BIN%\iis_ssi.dll" />
|
||||||
|
<add name="StaticFileModule" image="%IIS_BIN%\static.dll" />
|
||||||
|
<add name="AnonymousAuthenticationModule" image="%IIS_BIN%\authanon.dll" />
|
||||||
|
<add name="CertificateMappingAuthenticationModule" image="%IIS_BIN%\authcert.dll" />
|
||||||
|
<add name="UrlAuthorizationModule" image="%IIS_BIN%\urlauthz.dll" />
|
||||||
|
<add name="BasicAuthenticationModule" image="%IIS_BIN%\authbas.dll" />
|
||||||
|
<add name="WindowsAuthenticationModule" image="%IIS_BIN%\authsspi.dll" />
|
||||||
|
<add name="IISCertificateMappingAuthenticationModule" image="%IIS_BIN%\authmap.dll" />
|
||||||
|
<add name="IpRestrictionModule" image="%IIS_BIN%\iprestr.dll" />
|
||||||
|
<add name="DynamicIpRestrictionModule" image="%IIS_BIN%\diprestr.dll" />
|
||||||
|
<add name="RequestFilteringModule" image="%IIS_BIN%\modrqflt.dll" />
|
||||||
|
<add name="CustomLoggingModule" image="%IIS_BIN%\logcust.dll" />
|
||||||
|
<add name="CustomErrorModule" image="%IIS_BIN%\custerr.dll" />
|
||||||
|
<add name="FailedRequestsTracingModule" image="%IIS_BIN%\iisfreb.dll" />
|
||||||
|
<add name="RequestMonitorModule" image="%IIS_BIN%\iisreqs.dll" />
|
||||||
|
<add name="IsapiModule" image="%IIS_BIN%\isapi.dll" />
|
||||||
|
<add name="IsapiFilterModule" image="%IIS_BIN%\filter.dll" />
|
||||||
|
<add name="CgiModule" image="%IIS_BIN%\cgi.dll" />
|
||||||
|
<add name="FastCgiModule" image="%IIS_BIN%\iisfcgi.dll" />
|
||||||
|
<!-- <add name="WebDAVModule" image="%IIS_BIN%\webdav.dll" /> -->
|
||||||
|
<add name="RewriteModule" image="%IIS_BIN%\rewrite.dll" />
|
||||||
|
<add name="ConfigurationValidationModule" image="%IIS_BIN%\validcfg.dll" />
|
||||||
|
<add name="WebSocketModule" image="%IIS_BIN%\iiswsock.dll" />
|
||||||
|
<add name="WebMatrixSupportModule" image="%IIS_BIN%\webmatrixsup.dll" />
|
||||||
|
<add name="ManagedEngine" image="%windir%\Microsoft.NET\Framework\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness32" />
|
||||||
|
<add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" />
|
||||||
|
<add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="ApplicationInitializationModule" image="%IIS_BIN%\warmup.dll" />
|
||||||
|
<add name="AspNetCoreModule" image="%IIS_BIN%\aspnetcore.dll" />
|
||||||
|
<add name="AspNetCoreModuleV2" image="%IIS_BIN%\Asp.Net Core Module\V2\aspnetcorev2.dll" />
|
||||||
|
</globalModules>
|
||||||
|
<httpCompression directory="%TEMP%">
|
||||||
|
<scheme name="gzip" dll="%IIS_BIN%\gzip.dll" />
|
||||||
|
<dynamicTypes>
|
||||||
|
<add mimeType="text/*" enabled="true" />
|
||||||
|
<add mimeType="message/*" enabled="true" />
|
||||||
|
<add mimeType="application/x-javascript" enabled="true" />
|
||||||
|
<add mimeType="application/javascript" enabled="true" />
|
||||||
|
<add mimeType="*/*" enabled="false" />
|
||||||
|
<add mimeType="text/event-stream" enabled="false" />
|
||||||
|
</dynamicTypes>
|
||||||
|
<staticTypes>
|
||||||
|
<add mimeType="text/*" enabled="true" />
|
||||||
|
<add mimeType="message/*" enabled="true" />
|
||||||
|
<add mimeType="application/javascript" enabled="true" />
|
||||||
|
<add mimeType="application/atom+xml" enabled="true" />
|
||||||
|
<add mimeType="application/xaml+xml" enabled="true" />
|
||||||
|
<add mimeType="image/svg+xml" enabled="true" />
|
||||||
|
<add mimeType="*/*" enabled="false" />
|
||||||
|
</staticTypes>
|
||||||
|
</httpCompression>
|
||||||
|
<httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath">
|
||||||
|
<error statusCode="401" prefixLanguageFilePath="%IIS_BIN%\custerr" path="401.htm" />
|
||||||
|
<error statusCode="403" prefixLanguageFilePath="%IIS_BIN%\custerr" path="403.htm" />
|
||||||
|
<error statusCode="404" prefixLanguageFilePath="%IIS_BIN%\custerr" path="404.htm" />
|
||||||
|
<error statusCode="405" prefixLanguageFilePath="%IIS_BIN%\custerr" path="405.htm" />
|
||||||
|
<error statusCode="406" prefixLanguageFilePath="%IIS_BIN%\custerr" path="406.htm" />
|
||||||
|
<error statusCode="412" prefixLanguageFilePath="%IIS_BIN%\custerr" path="412.htm" />
|
||||||
|
<error statusCode="500" prefixLanguageFilePath="%IIS_BIN%\custerr" path="500.htm" />
|
||||||
|
<error statusCode="501" prefixLanguageFilePath="%IIS_BIN%\custerr" path="501.htm" />
|
||||||
|
<error statusCode="502" prefixLanguageFilePath="%IIS_BIN%\custerr" path="502.htm" />
|
||||||
|
</httpErrors>
|
||||||
|
<httpLogging dontLog="false" />
|
||||||
|
<httpProtocol>
|
||||||
|
<customHeaders>
|
||||||
|
<clear />
|
||||||
|
<add name="X-Powered-By" value="ASP.NET" />
|
||||||
|
</customHeaders>
|
||||||
|
<redirectHeaders>
|
||||||
|
<clear />
|
||||||
|
</redirectHeaders>
|
||||||
|
</httpProtocol>
|
||||||
|
<httpRedirect enabled="false" />
|
||||||
|
<httpTracing />
|
||||||
|
<isapiFilters>
|
||||||
|
<filter name="ASP.Net_2.0.50727-64" path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv2.0" />
|
||||||
|
<filter name="ASP.Net_2.0.50727.0" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv2.0" />
|
||||||
|
<filter name="ASP.Net_2.0_for_v1.1" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="runtimeVersionv1.1" />
|
||||||
|
<filter name="ASP.Net_4.0_32bit" path="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv4.0" />
|
||||||
|
<filter name="ASP.Net_4.0_64bit" path="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv4.0" />
|
||||||
|
</isapiFilters>
|
||||||
|
<odbcLogging />
|
||||||
|
<security>
|
||||||
|
<access sslFlags="None" />
|
||||||
|
<applicationDependencies>
|
||||||
|
<application name="Active Server Pages" groupId="ASP" />
|
||||||
|
</applicationDependencies>
|
||||||
|
<authentication>
|
||||||
|
<anonymousAuthentication enabled="true" userName="" />
|
||||||
|
<basicAuthentication enabled="false" />
|
||||||
|
<clientCertificateMappingAuthentication enabled="false" />
|
||||||
|
<digestAuthentication enabled="false" />
|
||||||
|
<iisClientCertificateMappingAuthentication enabled="false"></iisClientCertificateMappingAuthentication>
|
||||||
|
<windowsAuthentication enabled="false">
|
||||||
|
<providers>
|
||||||
|
<add value="Negotiate" />
|
||||||
|
<add value="NTLM" />
|
||||||
|
</providers>
|
||||||
|
</windowsAuthentication>
|
||||||
|
</authentication>
|
||||||
|
<authorization>
|
||||||
|
<add accessType="Allow" users="*" />
|
||||||
|
</authorization>
|
||||||
|
<ipSecurity allowUnlisted="true" />
|
||||||
|
<isapiCgiRestriction notListedIsapisAllowed="true" notListedCgisAllowed="true">
|
||||||
|
<add path="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" />
|
||||||
|
<add path="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" />
|
||||||
|
<add path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
|
||||||
|
<add path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
|
||||||
|
</isapiCgiRestriction>
|
||||||
|
<requestFiltering>
|
||||||
|
<fileExtensions allowUnlisted="true" applyToWebDAV="true">
|
||||||
|
<add fileExtension=".asa" allowed="false" />
|
||||||
|
<add fileExtension=".asax" allowed="false" />
|
||||||
|
<add fileExtension=".ascx" allowed="false" />
|
||||||
|
<add fileExtension=".master" allowed="false" />
|
||||||
|
<add fileExtension=".skin" allowed="false" />
|
||||||
|
<add fileExtension=".browser" allowed="false" />
|
||||||
|
<add fileExtension=".sitemap" allowed="false" />
|
||||||
|
<add fileExtension=".config" allowed="false" />
|
||||||
|
<add fileExtension=".cs" allowed="false" />
|
||||||
|
<add fileExtension=".csproj" allowed="false" />
|
||||||
|
<add fileExtension=".vb" allowed="false" />
|
||||||
|
<add fileExtension=".vbproj" allowed="false" />
|
||||||
|
<add fileExtension=".webinfo" allowed="false" />
|
||||||
|
<add fileExtension=".licx" allowed="false" />
|
||||||
|
<add fileExtension=".resx" allowed="false" />
|
||||||
|
<add fileExtension=".resources" allowed="false" />
|
||||||
|
<add fileExtension=".mdb" allowed="false" />
|
||||||
|
<add fileExtension=".vjsproj" allowed="false" />
|
||||||
|
<add fileExtension=".java" allowed="false" />
|
||||||
|
<add fileExtension=".jsl" allowed="false" />
|
||||||
|
<add fileExtension=".ldb" allowed="false" />
|
||||||
|
<add fileExtension=".dsdgm" allowed="false" />
|
||||||
|
<add fileExtension=".ssdgm" allowed="false" />
|
||||||
|
<add fileExtension=".lsad" allowed="false" />
|
||||||
|
<add fileExtension=".ssmap" allowed="false" />
|
||||||
|
<add fileExtension=".cd" allowed="false" />
|
||||||
|
<add fileExtension=".dsprototype" allowed="false" />
|
||||||
|
<add fileExtension=".lsaprototype" allowed="false" />
|
||||||
|
<add fileExtension=".sdm" allowed="false" />
|
||||||
|
<add fileExtension=".sdmDocument" allowed="false" />
|
||||||
|
<add fileExtension=".mdf" allowed="false" />
|
||||||
|
<add fileExtension=".ldf" allowed="false" />
|
||||||
|
<add fileExtension=".ad" allowed="false" />
|
||||||
|
<add fileExtension=".dd" allowed="false" />
|
||||||
|
<add fileExtension=".ldd" allowed="false" />
|
||||||
|
<add fileExtension=".sd" allowed="false" />
|
||||||
|
<add fileExtension=".adprototype" allowed="false" />
|
||||||
|
<add fileExtension=".lddprototype" allowed="false" />
|
||||||
|
<add fileExtension=".exclude" allowed="false" />
|
||||||
|
<add fileExtension=".refresh" allowed="false" />
|
||||||
|
<add fileExtension=".compiled" allowed="false" />
|
||||||
|
<add fileExtension=".msgx" allowed="false" />
|
||||||
|
<add fileExtension=".vsdisco" allowed="false" />
|
||||||
|
<add fileExtension=".rules" allowed="false" />
|
||||||
|
</fileExtensions>
|
||||||
|
<verbs allowUnlisted="true" applyToWebDAV="true" />
|
||||||
|
<hiddenSegments applyToWebDAV="true">
|
||||||
|
<add segment="web.config" />
|
||||||
|
<add segment="bin" />
|
||||||
|
<add segment="App_code" />
|
||||||
|
<add segment="App_GlobalResources" />
|
||||||
|
<add segment="App_LocalResources" />
|
||||||
|
<add segment="App_WebReferences" />
|
||||||
|
<add segment="App_Data" />
|
||||||
|
<add segment="App_Browsers" />
|
||||||
|
</hiddenSegments>
|
||||||
|
</requestFiltering>
|
||||||
|
</security>
|
||||||
|
<serverSideInclude ssiExecDisable="false" />
|
||||||
|
<staticContent lockAttributes="isDocFooterFileName">
|
||||||
|
<mimeMap fileExtension=".323" mimeType="text/h323" />
|
||||||
|
<mimeMap fileExtension=".3g2" mimeType="video/3gpp2" />
|
||||||
|
<mimeMap fileExtension=".3gp2" mimeType="video/3gpp2" />
|
||||||
|
<mimeMap fileExtension=".3gp" mimeType="video/3gpp" />
|
||||||
|
<mimeMap fileExtension=".3gpp" mimeType="video/3gpp" />
|
||||||
|
<mimeMap fileExtension=".aac" mimeType="audio/aac" />
|
||||||
|
<mimeMap fileExtension=".aaf" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".aca" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".accdb" mimeType="application/msaccess" />
|
||||||
|
<mimeMap fileExtension=".accde" mimeType="application/msaccess" />
|
||||||
|
<mimeMap fileExtension=".accdt" mimeType="application/msaccess" />
|
||||||
|
<mimeMap fileExtension=".acx" mimeType="application/internet-property-stream" />
|
||||||
|
<mimeMap fileExtension=".adt" mimeType="audio/vnd.dlna.adts" />
|
||||||
|
<mimeMap fileExtension=".adts" mimeType="audio/vnd.dlna.adts" />
|
||||||
|
<mimeMap fileExtension=".afm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ai" mimeType="application/postscript" />
|
||||||
|
<mimeMap fileExtension=".aif" mimeType="audio/x-aiff" />
|
||||||
|
<mimeMap fileExtension=".aifc" mimeType="audio/aiff" />
|
||||||
|
<mimeMap fileExtension=".aiff" mimeType="audio/aiff" />
|
||||||
|
<mimeMap fileExtension=".appcache" mimeType="text/cache-manifest" />
|
||||||
|
<mimeMap fileExtension=".application" mimeType="application/x-ms-application" />
|
||||||
|
<mimeMap fileExtension=".art" mimeType="image/x-jg" />
|
||||||
|
<mimeMap fileExtension=".asd" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".asf" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".asi" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".asm" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".asr" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".asx" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".atom" mimeType="application/atom+xml" />
|
||||||
|
<mimeMap fileExtension=".au" mimeType="audio/basic" />
|
||||||
|
<mimeMap fileExtension=".avi" mimeType="video/avi" />
|
||||||
|
<mimeMap fileExtension=".axs" mimeType="application/olescript" />
|
||||||
|
<mimeMap fileExtension=".bas" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".bcpio" mimeType="application/x-bcpio" />
|
||||||
|
<mimeMap fileExtension=".bin" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".bmp" mimeType="image/bmp" />
|
||||||
|
<mimeMap fileExtension=".c" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".cab" mimeType="application/vnd.ms-cab-compressed" />
|
||||||
|
<mimeMap fileExtension=".calx" mimeType="application/vnd.ms-office.calx" />
|
||||||
|
<mimeMap fileExtension=".cat" mimeType="application/vnd.ms-pki.seccat" />
|
||||||
|
<mimeMap fileExtension=".cdf" mimeType="application/x-cdf" />
|
||||||
|
<mimeMap fileExtension=".chm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".class" mimeType="application/x-java-applet" />
|
||||||
|
<mimeMap fileExtension=".clp" mimeType="application/x-msclip" />
|
||||||
|
<mimeMap fileExtension=".cmx" mimeType="image/x-cmx" />
|
||||||
|
<mimeMap fileExtension=".cnf" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".cod" mimeType="image/cis-cod" />
|
||||||
|
<mimeMap fileExtension=".cpio" mimeType="application/x-cpio" />
|
||||||
|
<mimeMap fileExtension=".cpp" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".crd" mimeType="application/x-mscardfile" />
|
||||||
|
<mimeMap fileExtension=".crl" mimeType="application/pkix-crl" />
|
||||||
|
<mimeMap fileExtension=".crt" mimeType="application/x-x509-ca-cert" />
|
||||||
|
<mimeMap fileExtension=".csh" mimeType="application/x-csh" />
|
||||||
|
<mimeMap fileExtension=".css" mimeType="text/css" />
|
||||||
|
<mimeMap fileExtension=".csv" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".cur" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".dcr" mimeType="application/x-director" />
|
||||||
|
<mimeMap fileExtension=".deploy" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".der" mimeType="application/x-x509-ca-cert" />
|
||||||
|
<mimeMap fileExtension=".dib" mimeType="image/bmp" />
|
||||||
|
<mimeMap fileExtension=".dir" mimeType="application/x-director" />
|
||||||
|
<mimeMap fileExtension=".disco" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".dll" mimeType="application/x-msdownload" />
|
||||||
|
<mimeMap fileExtension=".dll.config" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".dlm" mimeType="text/dlm" />
|
||||||
|
<mimeMap fileExtension=".doc" mimeType="application/msword" />
|
||||||
|
<mimeMap fileExtension=".docm" mimeType="application/vnd.ms-word.document.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".docx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
|
||||||
|
<mimeMap fileExtension=".dot" mimeType="application/msword" />
|
||||||
|
<mimeMap fileExtension=".dotm" mimeType="application/vnd.ms-word.template.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".dotx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.template" />
|
||||||
|
<mimeMap fileExtension=".dsp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".dtd" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".dvi" mimeType="application/x-dvi" />
|
||||||
|
<mimeMap fileExtension=".dvr-ms" mimeType="video/x-ms-dvr" />
|
||||||
|
<mimeMap fileExtension=".dwf" mimeType="drawing/x-dwf" />
|
||||||
|
<mimeMap fileExtension=".dwp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".dxr" mimeType="application/x-director" />
|
||||||
|
<mimeMap fileExtension=".eml" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".emz" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
|
||||||
|
<mimeMap fileExtension=".eps" mimeType="application/postscript" />
|
||||||
|
<mimeMap fileExtension=".esd" mimeType="application/vnd.ms-cab-compressed" />
|
||||||
|
<mimeMap fileExtension=".etx" mimeType="text/x-setext" />
|
||||||
|
<mimeMap fileExtension=".evy" mimeType="application/envoy" />
|
||||||
|
<mimeMap fileExtension=".exe" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".exe.config" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".fdf" mimeType="application/vnd.fdf" />
|
||||||
|
<mimeMap fileExtension=".fif" mimeType="application/fractals" />
|
||||||
|
<mimeMap fileExtension=".fla" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".flr" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".flv" mimeType="video/x-flv" />
|
||||||
|
<mimeMap fileExtension=".gif" mimeType="image/gif" />
|
||||||
|
<mimeMap fileExtension=".glb" mimeType="model/gltf-binary" />
|
||||||
|
<mimeMap fileExtension=".gtar" mimeType="application/x-gtar" />
|
||||||
|
<mimeMap fileExtension=".gz" mimeType="application/x-gzip" />
|
||||||
|
<mimeMap fileExtension=".h" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".hdf" mimeType="application/x-hdf" />
|
||||||
|
<mimeMap fileExtension=".hdml" mimeType="text/x-hdml" />
|
||||||
|
<mimeMap fileExtension=".hhc" mimeType="application/x-oleobject" />
|
||||||
|
<mimeMap fileExtension=".hhk" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".hhp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".hlp" mimeType="application/winhlp" />
|
||||||
|
<mimeMap fileExtension=".hqx" mimeType="application/mac-binhex40" />
|
||||||
|
<mimeMap fileExtension=".hta" mimeType="application/hta" />
|
||||||
|
<mimeMap fileExtension=".htc" mimeType="text/x-component" />
|
||||||
|
<mimeMap fileExtension=".htm" mimeType="text/html" />
|
||||||
|
<mimeMap fileExtension=".html" mimeType="text/html" />
|
||||||
|
<mimeMap fileExtension=".htt" mimeType="text/webviewhtml" />
|
||||||
|
<mimeMap fileExtension=".hxt" mimeType="text/html" />
|
||||||
|
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
|
||||||
|
<mimeMap fileExtension=".ics" mimeType="text/calendar" />
|
||||||
|
<mimeMap fileExtension=".ief" mimeType="image/ief" />
|
||||||
|
<mimeMap fileExtension=".iii" mimeType="application/x-iphone" />
|
||||||
|
<mimeMap fileExtension=".inf" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ins" mimeType="application/x-internet-signup" />
|
||||||
|
<mimeMap fileExtension=".isp" mimeType="application/x-internet-signup" />
|
||||||
|
<mimeMap fileExtension=".IVF" mimeType="video/x-ivf" />
|
||||||
|
<mimeMap fileExtension=".jar" mimeType="application/java-archive" />
|
||||||
|
<mimeMap fileExtension=".java" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".jck" mimeType="application/liquidmotion" />
|
||||||
|
<mimeMap fileExtension=".jcz" mimeType="application/liquidmotion" />
|
||||||
|
<mimeMap fileExtension=".jfif" mimeType="image/pjpeg" />
|
||||||
|
<mimeMap fileExtension=".jpb" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".jpe" mimeType="image/jpeg" />
|
||||||
|
<mimeMap fileExtension=".jpeg" mimeType="image/jpeg" />
|
||||||
|
<mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
|
||||||
|
<mimeMap fileExtension=".js" mimeType="application/javascript" />
|
||||||
|
<mimeMap fileExtension=".json" mimeType="application/json" />
|
||||||
|
<mimeMap fileExtension=".jsonld" mimeType="application/ld+json" />
|
||||||
|
<mimeMap fileExtension=".jsx" mimeType="text/jscript" />
|
||||||
|
<mimeMap fileExtension=".latex" mimeType="application/x-latex" />
|
||||||
|
<mimeMap fileExtension=".less" mimeType="text/css" />
|
||||||
|
<mimeMap fileExtension=".lit" mimeType="application/x-ms-reader" />
|
||||||
|
<mimeMap fileExtension=".lpk" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".lsf" mimeType="video/x-la-asf" />
|
||||||
|
<mimeMap fileExtension=".lsx" mimeType="video/x-la-asf" />
|
||||||
|
<mimeMap fileExtension=".lzh" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".m13" mimeType="application/x-msmediaview" />
|
||||||
|
<mimeMap fileExtension=".m14" mimeType="application/x-msmediaview" />
|
||||||
|
<mimeMap fileExtension=".m1v" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".m2ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||||
|
<mimeMap fileExtension=".m3u" mimeType="audio/x-mpegurl" />
|
||||||
|
<mimeMap fileExtension=".m4a" mimeType="audio/mp4" />
|
||||||
|
<mimeMap fileExtension=".m4v" mimeType="video/mp4" />
|
||||||
|
<mimeMap fileExtension=".man" mimeType="application/x-troff-man" />
|
||||||
|
<mimeMap fileExtension=".manifest" mimeType="application/x-ms-manifest" />
|
||||||
|
<mimeMap fileExtension=".map" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".mdb" mimeType="application/x-msaccess" />
|
||||||
|
<mimeMap fileExtension=".mdp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".me" mimeType="application/x-troff-me" />
|
||||||
|
<mimeMap fileExtension=".mht" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".mhtml" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".mid" mimeType="audio/mid" />
|
||||||
|
<mimeMap fileExtension=".midi" mimeType="audio/mid" />
|
||||||
|
<mimeMap fileExtension=".mix" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".mmf" mimeType="application/x-smaf" />
|
||||||
|
<mimeMap fileExtension=".mno" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".mny" mimeType="application/x-msmoney" />
|
||||||
|
<mimeMap fileExtension=".mov" mimeType="video/quicktime" />
|
||||||
|
<mimeMap fileExtension=".movie" mimeType="video/x-sgi-movie" />
|
||||||
|
<mimeMap fileExtension=".mp2" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mp3" mimeType="audio/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
|
||||||
|
<mimeMap fileExtension=".mp4v" mimeType="video/mp4" />
|
||||||
|
<mimeMap fileExtension=".mpa" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpe" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpeg" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpg" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".mpp" mimeType="application/vnd.ms-project" />
|
||||||
|
<mimeMap fileExtension=".mpv2" mimeType="video/mpeg" />
|
||||||
|
<mimeMap fileExtension=".ms" mimeType="application/x-troff-ms" />
|
||||||
|
<mimeMap fileExtension=".msi" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".mso" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".mvb" mimeType="application/x-msmediaview" />
|
||||||
|
<mimeMap fileExtension=".mvc" mimeType="application/x-miva-compiled" />
|
||||||
|
<mimeMap fileExtension=".nc" mimeType="application/x-netcdf" />
|
||||||
|
<mimeMap fileExtension=".nsc" mimeType="video/x-ms-asf" />
|
||||||
|
<mimeMap fileExtension=".nws" mimeType="message/rfc822" />
|
||||||
|
<mimeMap fileExtension=".ocx" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".oda" mimeType="application/oda" />
|
||||||
|
<mimeMap fileExtension=".odc" mimeType="text/x-ms-odc" />
|
||||||
|
<mimeMap fileExtension=".ods" mimeType="application/oleobject" />
|
||||||
|
<mimeMap fileExtension=".oga" mimeType="audio/ogg" />
|
||||||
|
<mimeMap fileExtension=".ogg" mimeType="video/ogg" />
|
||||||
|
<mimeMap fileExtension=".ogv" mimeType="video/ogg" />
|
||||||
|
<mimeMap fileExtension=".one" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onea" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onetoc" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onetoc2" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onetmp" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".onepkg" mimeType="application/onenote" />
|
||||||
|
<mimeMap fileExtension=".osdx" mimeType="application/opensearchdescription+xml" />
|
||||||
|
<mimeMap fileExtension=".otf" mimeType="font/otf" />
|
||||||
|
<mimeMap fileExtension=".p10" mimeType="application/pkcs10" />
|
||||||
|
<mimeMap fileExtension=".p12" mimeType="application/x-pkcs12" />
|
||||||
|
<mimeMap fileExtension=".p7b" mimeType="application/x-pkcs7-certificates" />
|
||||||
|
<mimeMap fileExtension=".p7c" mimeType="application/pkcs7-mime" />
|
||||||
|
<mimeMap fileExtension=".p7m" mimeType="application/pkcs7-mime" />
|
||||||
|
<mimeMap fileExtension=".p7r" mimeType="application/x-pkcs7-certreqresp" />
|
||||||
|
<mimeMap fileExtension=".p7s" mimeType="application/pkcs7-signature" />
|
||||||
|
<mimeMap fileExtension=".pbm" mimeType="image/x-portable-bitmap" />
|
||||||
|
<mimeMap fileExtension=".pcx" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pcz" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pdf" mimeType="application/pdf" />
|
||||||
|
<mimeMap fileExtension=".pfb" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pfm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pfx" mimeType="application/x-pkcs12" />
|
||||||
|
<mimeMap fileExtension=".pgm" mimeType="image/x-portable-graymap" />
|
||||||
|
<mimeMap fileExtension=".pko" mimeType="application/vnd.ms-pki.pko" />
|
||||||
|
<mimeMap fileExtension=".pma" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pmc" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pml" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pmr" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".pmw" mimeType="application/x-perfmon" />
|
||||||
|
<mimeMap fileExtension=".png" mimeType="image/png" />
|
||||||
|
<mimeMap fileExtension=".pnm" mimeType="image/x-portable-anymap" />
|
||||||
|
<mimeMap fileExtension=".pnz" mimeType="image/png" />
|
||||||
|
<mimeMap fileExtension=".pot" mimeType="application/vnd.ms-powerpoint" />
|
||||||
|
<mimeMap fileExtension=".potm" mimeType="application/vnd.ms-powerpoint.template.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".potx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.template" />
|
||||||
|
<mimeMap fileExtension=".ppam" mimeType="application/vnd.ms-powerpoint.addin.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".ppm" mimeType="image/x-portable-pixmap" />
|
||||||
|
<mimeMap fileExtension=".pps" mimeType="application/vnd.ms-powerpoint" />
|
||||||
|
<mimeMap fileExtension=".ppsm" mimeType="application/vnd.ms-powerpoint.slideshow.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".ppsx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" />
|
||||||
|
<mimeMap fileExtension=".ppt" mimeType="application/vnd.ms-powerpoint" />
|
||||||
|
<mimeMap fileExtension=".pptm" mimeType="application/vnd.ms-powerpoint.presentation.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".pptx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
|
||||||
|
<mimeMap fileExtension=".prf" mimeType="application/pics-rules" />
|
||||||
|
<mimeMap fileExtension=".prm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".prx" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ps" mimeType="application/postscript" />
|
||||||
|
<mimeMap fileExtension=".psd" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".psm" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".psp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".pub" mimeType="application/x-mspublisher" />
|
||||||
|
<mimeMap fileExtension=".qt" mimeType="video/quicktime" />
|
||||||
|
<mimeMap fileExtension=".qtl" mimeType="application/x-quicktimeplayer" />
|
||||||
|
<mimeMap fileExtension=".qxd" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ra" mimeType="audio/x-pn-realaudio" />
|
||||||
|
<mimeMap fileExtension=".ram" mimeType="audio/x-pn-realaudio" />
|
||||||
|
<mimeMap fileExtension=".rar" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".ras" mimeType="image/x-cmu-raster" />
|
||||||
|
<mimeMap fileExtension=".rf" mimeType="image/vnd.rn-realflash" />
|
||||||
|
<mimeMap fileExtension=".rgb" mimeType="image/x-rgb" />
|
||||||
|
<mimeMap fileExtension=".rm" mimeType="application/vnd.rn-realmedia" />
|
||||||
|
<mimeMap fileExtension=".rmi" mimeType="audio/mid" />
|
||||||
|
<mimeMap fileExtension=".roff" mimeType="application/x-troff" />
|
||||||
|
<mimeMap fileExtension=".rpm" mimeType="audio/x-pn-realaudio-plugin" />
|
||||||
|
<mimeMap fileExtension=".rtf" mimeType="application/rtf" />
|
||||||
|
<mimeMap fileExtension=".rtx" mimeType="text/richtext" />
|
||||||
|
<mimeMap fileExtension=".scd" mimeType="application/x-msschedule" />
|
||||||
|
<mimeMap fileExtension=".sct" mimeType="text/scriptlet" />
|
||||||
|
<mimeMap fileExtension=".sea" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".setpay" mimeType="application/set-payment-initiation" />
|
||||||
|
<mimeMap fileExtension=".setreg" mimeType="application/set-registration-initiation" />
|
||||||
|
<mimeMap fileExtension=".sgml" mimeType="text/sgml" />
|
||||||
|
<mimeMap fileExtension=".sh" mimeType="application/x-sh" />
|
||||||
|
<mimeMap fileExtension=".shar" mimeType="application/x-shar" />
|
||||||
|
<mimeMap fileExtension=".sit" mimeType="application/x-stuffit" />
|
||||||
|
<mimeMap fileExtension=".sldm" mimeType="application/vnd.ms-powerpoint.slide.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".sldx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slide" />
|
||||||
|
<mimeMap fileExtension=".smd" mimeType="audio/x-smd" />
|
||||||
|
<mimeMap fileExtension=".smi" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".smx" mimeType="audio/x-smd" />
|
||||||
|
<mimeMap fileExtension=".smz" mimeType="audio/x-smd" />
|
||||||
|
<mimeMap fileExtension=".snd" mimeType="audio/basic" />
|
||||||
|
<mimeMap fileExtension=".snp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".spc" mimeType="application/x-pkcs7-certificates" />
|
||||||
|
<mimeMap fileExtension=".spl" mimeType="application/futuresplash" />
|
||||||
|
<mimeMap fileExtension=".spx" mimeType="audio/ogg" />
|
||||||
|
<mimeMap fileExtension=".src" mimeType="application/x-wais-source" />
|
||||||
|
<mimeMap fileExtension=".ssm" mimeType="application/streamingmedia" />
|
||||||
|
<mimeMap fileExtension=".sst" mimeType="application/vnd.ms-pki.certstore" />
|
||||||
|
<mimeMap fileExtension=".stl" mimeType="application/vnd.ms-pki.stl" />
|
||||||
|
<mimeMap fileExtension=".sv4cpio" mimeType="application/x-sv4cpio" />
|
||||||
|
<mimeMap fileExtension=".sv4crc" mimeType="application/x-sv4crc" />
|
||||||
|
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
|
||||||
|
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml" />
|
||||||
|
<mimeMap fileExtension=".swf" mimeType="application/x-shockwave-flash" />
|
||||||
|
<mimeMap fileExtension=".t" mimeType="application/x-troff" />
|
||||||
|
<mimeMap fileExtension=".tar" mimeType="application/x-tar" />
|
||||||
|
<mimeMap fileExtension=".tcl" mimeType="application/x-tcl" />
|
||||||
|
<mimeMap fileExtension=".tex" mimeType="application/x-tex" />
|
||||||
|
<mimeMap fileExtension=".texi" mimeType="application/x-texinfo" />
|
||||||
|
<mimeMap fileExtension=".texinfo" mimeType="application/x-texinfo" />
|
||||||
|
<mimeMap fileExtension=".tgz" mimeType="application/x-compressed" />
|
||||||
|
<mimeMap fileExtension=".thmx" mimeType="application/vnd.ms-officetheme" />
|
||||||
|
<mimeMap fileExtension=".thn" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".tif" mimeType="image/tiff" />
|
||||||
|
<mimeMap fileExtension=".tiff" mimeType="image/tiff" />
|
||||||
|
<mimeMap fileExtension=".toc" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".tr" mimeType="application/x-troff" />
|
||||||
|
<mimeMap fileExtension=".trm" mimeType="application/x-msterminal" />
|
||||||
|
<mimeMap fileExtension=".ts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||||
|
<mimeMap fileExtension=".tsv" mimeType="text/tab-separated-values" />
|
||||||
|
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".tts" mimeType="video/vnd.dlna.mpeg-tts" />
|
||||||
|
<mimeMap fileExtension=".txt" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".u32" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".uls" mimeType="text/iuls" />
|
||||||
|
<mimeMap fileExtension=".ustar" mimeType="application/x-ustar" />
|
||||||
|
<mimeMap fileExtension=".vbs" mimeType="text/vbscript" />
|
||||||
|
<mimeMap fileExtension=".vcf" mimeType="text/x-vcard" />
|
||||||
|
<mimeMap fileExtension=".vcs" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".vdx" mimeType="application/vnd.ms-visio.viewer" />
|
||||||
|
<mimeMap fileExtension=".vml" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".vsd" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vss" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vst" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vsto" mimeType="application/x-ms-vsto" />
|
||||||
|
<mimeMap fileExtension=".vsw" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vsx" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".vtx" mimeType="application/vnd.visio" />
|
||||||
|
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />
|
||||||
|
<mimeMap fileExtension=".wav" mimeType="audio/wav" />
|
||||||
|
<mimeMap fileExtension=".wax" mimeType="audio/x-ms-wax" />
|
||||||
|
<mimeMap fileExtension=".wbmp" mimeType="image/vnd.wap.wbmp" />
|
||||||
|
<mimeMap fileExtension=".wcm" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".wdb" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".webm" mimeType="video/webm" />
|
||||||
|
<mimeMap fileExtension=".wks" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".wm" mimeType="video/x-ms-wm" />
|
||||||
|
<mimeMap fileExtension=".wma" mimeType="audio/x-ms-wma" />
|
||||||
|
<mimeMap fileExtension=".wmd" mimeType="application/x-ms-wmd" />
|
||||||
|
<mimeMap fileExtension=".wmf" mimeType="application/x-msmetafile" />
|
||||||
|
<mimeMap fileExtension=".wml" mimeType="text/vnd.wap.wml" />
|
||||||
|
<mimeMap fileExtension=".wmlc" mimeType="application/vnd.wap.wmlc" />
|
||||||
|
<mimeMap fileExtension=".wmls" mimeType="text/vnd.wap.wmlscript" />
|
||||||
|
<mimeMap fileExtension=".wmlsc" mimeType="application/vnd.wap.wmlscriptc" />
|
||||||
|
<mimeMap fileExtension=".wmp" mimeType="video/x-ms-wmp" />
|
||||||
|
<mimeMap fileExtension=".wmv" mimeType="video/x-ms-wmv" />
|
||||||
|
<mimeMap fileExtension=".wmx" mimeType="video/x-ms-wmx" />
|
||||||
|
<mimeMap fileExtension=".wmz" mimeType="application/x-ms-wmz" />
|
||||||
|
<mimeMap fileExtension=".woff" mimeType="font/x-woff" />
|
||||||
|
<mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
|
||||||
|
<mimeMap fileExtension=".wps" mimeType="application/vnd.ms-works" />
|
||||||
|
<mimeMap fileExtension=".wri" mimeType="application/x-mswrite" />
|
||||||
|
<mimeMap fileExtension=".wrl" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".wrz" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".wsdl" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".wtv" mimeType="video/x-ms-wtv" />
|
||||||
|
<mimeMap fileExtension=".wvx" mimeType="video/x-ms-wvx" />
|
||||||
|
<mimeMap fileExtension=".x" mimeType="application/directx" />
|
||||||
|
<mimeMap fileExtension=".xaf" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".xaml" mimeType="application/xaml+xml" />
|
||||||
|
<mimeMap fileExtension=".xap" mimeType="application/x-silverlight-app" />
|
||||||
|
<mimeMap fileExtension=".xbap" mimeType="application/x-ms-xbap" />
|
||||||
|
<mimeMap fileExtension=".xbm" mimeType="image/x-xbitmap" />
|
||||||
|
<mimeMap fileExtension=".xdr" mimeType="text/plain" />
|
||||||
|
<mimeMap fileExtension=".xht" mimeType="application/xhtml+xml" />
|
||||||
|
<mimeMap fileExtension=".xhtml" mimeType="application/xhtml+xml" />
|
||||||
|
<mimeMap fileExtension=".xla" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xlam" mimeType="application/vnd.ms-excel.addin.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xlc" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xlm" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xls" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xlsb" mimeType="application/vnd.ms-excel.sheet.binary.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xlsm" mimeType="application/vnd.ms-excel.sheet.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xlsx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
|
||||||
|
<mimeMap fileExtension=".xlt" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xltm" mimeType="application/vnd.ms-excel.template.macroEnabled.12" />
|
||||||
|
<mimeMap fileExtension=".xltx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.template" />
|
||||||
|
<mimeMap fileExtension=".xlw" mimeType="application/vnd.ms-excel" />
|
||||||
|
<mimeMap fileExtension=".xml" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xof" mimeType="x-world/x-vrml" />
|
||||||
|
<mimeMap fileExtension=".xpm" mimeType="image/x-xpixmap" />
|
||||||
|
<mimeMap fileExtension=".xps" mimeType="application/vnd.ms-xpsdocument" />
|
||||||
|
<mimeMap fileExtension=".xsd" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xsf" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xsl" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xslt" mimeType="text/xml" />
|
||||||
|
<mimeMap fileExtension=".xsn" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".xtp" mimeType="application/octet-stream" />
|
||||||
|
<mimeMap fileExtension=".xwd" mimeType="image/x-xwindowdump" />
|
||||||
|
<mimeMap fileExtension=".z" mimeType="application/x-compress" />
|
||||||
|
<mimeMap fileExtension=".zip" mimeType="application/x-zip-compressed" />
|
||||||
|
</staticContent>
|
||||||
|
<tracing>
|
||||||
|
<traceFailedRequests>
|
||||||
|
<add path="*">
|
||||||
|
<traceAreas>
|
||||||
|
<add provider="ASP" verbosity="Verbose" />
|
||||||
|
<add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
|
||||||
|
<add provider="ISAPI Extension" verbosity="Verbose" />
|
||||||
|
<add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,Rewrite,WebSocket" verbosity="Verbose" />
|
||||||
|
</traceAreas>
|
||||||
|
<failureDefinitions statusCodes="200-999" />
|
||||||
|
</add>
|
||||||
|
</traceFailedRequests>
|
||||||
|
<traceProviderDefinitions>
|
||||||
|
<add name="WWW Server" guid="{3a2a4e84-4c21-4981-ae10-3fda0d9b0f83}">
|
||||||
|
<areas>
|
||||||
|
<clear />
|
||||||
|
<add name="Authentication" value="2" />
|
||||||
|
<add name="Security" value="4" />
|
||||||
|
<add name="Filter" value="8" />
|
||||||
|
<add name="StaticFile" value="16" />
|
||||||
|
<add name="CGI" value="32" />
|
||||||
|
<add name="Compression" value="64" />
|
||||||
|
<add name="Cache" value="128" />
|
||||||
|
<add name="RequestNotifications" value="256" />
|
||||||
|
<add name="Module" value="512" />
|
||||||
|
<add name="Rewrite" value="1024" />
|
||||||
|
<add name="FastCGI" value="4096" />
|
||||||
|
<add name="WebSocket" value="16384" />
|
||||||
|
<add name="ANCM" value="65536" />
|
||||||
|
</areas>
|
||||||
|
</add>
|
||||||
|
<add name="ASP" guid="{06b94d9a-b15e-456e-a4ef-37c984a2cb4b}">
|
||||||
|
<areas>
|
||||||
|
<clear />
|
||||||
|
</areas>
|
||||||
|
</add>
|
||||||
|
<add name="ISAPI Extension" guid="{a1c2040e-8840-4c31-ba11-9871031a19ea}">
|
||||||
|
<areas>
|
||||||
|
<clear />
|
||||||
|
</areas>
|
||||||
|
</add>
|
||||||
|
<add name="ASPNET" guid="{AFF081FE-0247-4275-9C4E-021F3DC1DA35}">
|
||||||
|
<areas>
|
||||||
|
<add name="Infrastructure" value="1" />
|
||||||
|
<add name="Module" value="2" />
|
||||||
|
<add name="Page" value="4" />
|
||||||
|
<add name="AppServices" value="8" />
|
||||||
|
</areas>
|
||||||
|
</add>
|
||||||
|
</traceProviderDefinitions>
|
||||||
|
</tracing>
|
||||||
|
<urlCompression />
|
||||||
|
<validation />
|
||||||
|
<webdav>
|
||||||
|
<globalSettings>
|
||||||
|
<propertyStores>
|
||||||
|
<add name="webdav_simple_prop" image="%IIS_BIN%\webdav_simple_prop.dll" image32="%IIS_BIN%\webdav_simple_prop.dll" />
|
||||||
|
</propertyStores>
|
||||||
|
<lockStores>
|
||||||
|
<add name="webdav_simple_lock" image="%IIS_BIN%\webdav_simple_lock.dll" image32="%IIS_BIN%\webdav_simple_lock.dll" />
|
||||||
|
</lockStores>
|
||||||
|
</globalSettings>
|
||||||
|
<authoring>
|
||||||
|
<locks enabled="true" lockStore="webdav_simple_lock" />
|
||||||
|
</authoring>
|
||||||
|
<authoringRules />
|
||||||
|
</webdav>
|
||||||
|
<webSocket />
|
||||||
|
<applicationInitialization />
|
||||||
|
</system.webServer>
|
||||||
|
<location path="" overrideMode="Allow">
|
||||||
|
<system.webServer>
|
||||||
|
<modules>
|
||||||
|
<add name="IsapiFilterModule" lockItem="true" />
|
||||||
|
<add name="BasicAuthenticationModule" lockItem="true" />
|
||||||
|
<add name="IsapiModule" lockItem="true" />
|
||||||
|
<add name="HttpLoggingModule" lockItem="true" />
|
||||||
|
<add name="DynamicCompressionModule" lockItem="true" />
|
||||||
|
<add name="StaticCompressionModule" lockItem="true" />
|
||||||
|
<add name="DefaultDocumentModule" lockItem="true" />
|
||||||
|
<add name="DirectoryListingModule" lockItem="true" />
|
||||||
|
<add name="ProtocolSupportModule" lockItem="true" />
|
||||||
|
<add name="HttpRedirectionModule" lockItem="true" />
|
||||||
|
<add name="ServerSideIncludeModule" lockItem="true" />
|
||||||
|
<add name="StaticFileModule" lockItem="true" />
|
||||||
|
<add name="AnonymousAuthenticationModule" lockItem="false" />
|
||||||
|
<add name="CertificateMappingAuthenticationModule" lockItem="true" />
|
||||||
|
<add name="UrlAuthorizationModule" lockItem="true" />
|
||||||
|
<add name="WindowsAuthenticationModule" lockItem="false" />
|
||||||
|
<add name="IISCertificateMappingAuthenticationModule" lockItem="true" />
|
||||||
|
<add name="WebMatrixSupportModule" lockItem="true" />
|
||||||
|
<add name="IpRestrictionModule" lockItem="true" />
|
||||||
|
<add name="DynamicIpRestrictionModule" lockItem="true" />
|
||||||
|
<add name="RequestFilteringModule" lockItem="true" />
|
||||||
|
<add name="CustomLoggingModule" lockItem="true" />
|
||||||
|
<add name="CustomErrorModule" lockItem="true" />
|
||||||
|
<add name="FailedRequestsTracingModule" lockItem="true" />
|
||||||
|
<add name="CgiModule" lockItem="true" />
|
||||||
|
<add name="FastCgiModule" lockItem="true" />
|
||||||
|
<!-- <add name="WebDAVModule" /> -->
|
||||||
|
<add name="RewriteModule" />
|
||||||
|
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" preCondition="managedHandler" />
|
||||||
|
<add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition="managedHandler" />
|
||||||
|
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" preCondition="managedHandler" />
|
||||||
|
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="managedHandler" />
|
||||||
|
<add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" preCondition="managedHandler" />
|
||||||
|
<add name="RoleManager" type="System.Web.Security.RoleManagerModule" preCondition="managedHandler" />
|
||||||
|
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />
|
||||||
|
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" preCondition="managedHandler" />
|
||||||
|
<add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" preCondition="managedHandler" />
|
||||||
|
<add name="Profile" type="System.Web.Profile.ProfileModule" preCondition="managedHandler" />
|
||||||
|
<add name="UrlMappingsModule" type="System.Web.UrlMappingsModule" preCondition="managedHandler" />
|
||||||
|
<add name="ApplicationInitializationModule" lockItem="true" />
|
||||||
|
<add name="WebSocketModule" lockItem="true" />
|
||||||
|
<add name="ServiceModel-4.0" type="System.ServiceModel.Activation.ServiceHttpModule,System.ServiceModel.Activation,Version=4.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||||
|
<add name="ConfigurationValidationModule" lockItem="true" />
|
||||||
|
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||||
|
<add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
|
||||||
|
<add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler,runtimeVersionv2.0" />
|
||||||
|
<add name="AspNetCoreModule" lockItem="true" />
|
||||||
|
<add name="AspNetCoreModuleV2" lockItem="true" />
|
||||||
|
</modules>
|
||||||
|
<handlers accessPolicy="Read, Script">
|
||||||
|
<!-- <add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" /> -->
|
||||||
|
<add name="AXD-ISAPI-4.0_64bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="PageHandlerFactory-ISAPI-4.0_64bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="SimpleHandlerFactory-ISAPI-4.0_64bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="WebServiceHandlerFactory-ISAPI-4.0_64bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_64bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_64bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="svc-ISAPI-4.0_64bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="rules-ISAPI-4.0_64bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="xoml-ISAPI-4.0_64bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="xamlx-ISAPI-4.0_64bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
|
||||||
|
<add name="aspq-ISAPI-4.0_64bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="cshtm-ISAPI-4.0_64bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="cshtml-ISAPI-4.0_64bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="vbhtm-ISAPI-4.0_64bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="vbhtml-ISAPI-4.0_64bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="svc-Integrated" path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="svc-ISAPI-2.0" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
|
||||||
|
<add name="xoml-Integrated" path="*.xoml" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="xoml-ISAPI-2.0" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
|
||||||
|
<add name="rules-Integrated" path="*.rules" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="rules-ISAPI-2.0" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
|
||||||
|
<add name="AXD-ISAPI-4.0_32bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="PageHandlerFactory-ISAPI-4.0_32bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="SimpleHandlerFactory-ISAPI-4.0_32bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="WebServiceHandlerFactory-ISAPI-4.0_32bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_32bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_32bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="svc-ISAPI-4.0_32bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="rules-ISAPI-4.0_32bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="xoml-ISAPI-4.0_32bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="xamlx-ISAPI-4.0_32bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
|
||||||
|
<add name="aspq-ISAPI-4.0_32bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="cshtm-ISAPI-4.0_32bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="cshtml-ISAPI-4.0_32bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="vbhtm-ISAPI-4.0_32bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="vbhtml-ISAPI-4.0_32bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="TraceHandler-Integrated-4.0" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="WebAdminHandler-Integrated-4.0" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="AssemblyResourceLoader-Integrated-4.0" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="WebServiceHandlerFactory-Integrated-4.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-Integrated-4.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-Integrated-4.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="rules-Integrated-4.0" path="*.rules" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="xoml-Integrated-4.0" path="*.xoml" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="xamlx-Integrated-4.0" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="aspq-Integrated-4.0" path="*.aspq" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="cshtm-Integrated-4.0" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="cshtml-Integrated-4.0" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="vbhtm-Integrated-4.0" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="vbhtml-Integrated-4.0" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="ScriptHandlerFactoryAppServices-Integrated-4.0" path="*_AppService.axd" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="ScriptResourceIntegrated-4.0" path="*ScriptResource.axd" verb="GET,HEAD" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
|
<add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" />
|
||||||
|
<add name="SecurityCertificate" path="*.cer" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" />
|
||||||
|
<add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
|
||||||
|
<add name="TraceHandler-Integrated" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="WebAdminHandler-Integrated" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="AssemblyResourceLoader-Integrated" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="PageHandlerFactory-Integrated" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="SimpleHandlerFactory-Integrated" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="WebServiceHandlerFactory-Integrated" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Services.Protocols.WebServiceHandlerFactory,System.Web.Services,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-Integrated" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-Integrated" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
|
||||||
|
<add name="AXD-ISAPI-2.0" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="PageHandlerFactory-ISAPI-2.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="SimpleHandlerFactory-ISAPI-2.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="WebServiceHandlerFactory-ISAPI-2.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="svc-ISAPI-2.0-64" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" />
|
||||||
|
<add name="AXD-ISAPI-2.0-64" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="PageHandlerFactory-ISAPI-2.0-64" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="SimpleHandlerFactory-ISAPI-2.0-64" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="WebServiceHandlerFactory-ISAPI-2.0-64" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0-64" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0-64" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="rules-64-ISAPI-2.0" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" />
|
||||||
|
<add name="xoml-64-ISAPI-2.0" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" />
|
||||||
|
<add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
|
||||||
|
<add name="SSINC-stm" path="*.stm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
|
||||||
|
<add name="SSINC-shtm" path="*.shtm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
|
||||||
|
<add name="SSINC-shtml" path="*.shtml" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
|
||||||
|
<add name="TRACEVerbHandler" path="*" verb="TRACE" modules="ProtocolSupportModule" requireAccess="None" />
|
||||||
|
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" />
|
||||||
|
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||||
|
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||||
|
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
|
||||||
|
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
|
||||||
|
</handlers>
|
||||||
|
</system.webServer>
|
||||||
|
</location>
|
||||||
|
<location path="AGSS" inheritInChildApplications="false">
|
||||||
|
<system.webServer>
|
||||||
|
<security>
|
||||||
|
<authentication>
|
||||||
|
<anonymousAuthentication enabled="true" />
|
||||||
|
<windowsAuthentication enabled="false" />
|
||||||
|
</authentication>
|
||||||
|
</security>
|
||||||
|
<handlers>
|
||||||
|
<add name="aspNetCore" path="*" verb="*" resourceType="Unspecified" modules="AspNetCoreModuleV2" />
|
||||||
|
</handlers>
|
||||||
|
<modules>
|
||||||
|
<remove name="WebMatrixSupportModule" />
|
||||||
|
</modules>
|
||||||
|
<aspNetCore stdoutLogEnabled="false" startupTimeLimit="3600" requestTimeout="23:00:00" processPath="%ANCM_LAUNCHER_PATH%" hostingModel="InProcess" arguments="%ANCM_LAUNCHER_ARGS%" />
|
||||||
|
<httpCompression>
|
||||||
|
<dynamicTypes>
|
||||||
|
<add mimeType="text/event-stream" enabled="false" />
|
||||||
|
</dynamicTypes>
|
||||||
|
</httpCompression>
|
||||||
|
</system.webServer>
|
||||||
|
</location>
|
||||||
|
</configuration>
|
@ -1,22 +1,33 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Auth0.ManagementApi" Version="7.38.0" />
|
<PackageReference Include="Auth0.ManagementApi" Version="7.38.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.17" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.17" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="9.0.6" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.6" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.6">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.12.1" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.12.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Controllers\" />
|
<Folder Include="Middleware\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
10
AGSS/Areas/Identity/Pages/Account/AccessDenied.cshtml
Normal file
10
AGSS/Areas/Identity/Pages/Account/AccessDenied.cshtml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@page
|
||||||
|
@model AccessDeniedModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Access denied";
|
||||||
|
}
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1 class="text-danger">@ViewData["Title"]</h1>
|
||||||
|
<p class="text-danger">You do not have access to this resource.</p>
|
||||||
|
</header>
|
23
AGSS/Areas/Identity/Pages/Account/AccessDenied.cshtml.cs
Normal file
23
AGSS/Areas/Identity/Pages/Account/AccessDenied.cshtml.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class AccessDeniedModel : PageModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public void OnGet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
AGSS/Areas/Identity/Pages/Account/ConfirmEmail.cshtml
Normal file
8
AGSS/Areas/Identity/Pages/Account/ConfirmEmail.cshtml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@page
|
||||||
|
@model ConfirmEmailModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Confirm email";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<partial name="_StatusMessage" model="Model.StatusMessage" />
|
52
AGSS/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs
Normal file
52
AGSS/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
public class ConfirmEmailModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
|
||||||
|
public ConfirmEmailModel(UserManager<UserModel> userManager)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
public async Task<IActionResult> OnGetAsync(string userId, string code)
|
||||||
|
{
|
||||||
|
if (userId == null || code == null)
|
||||||
|
{
|
||||||
|
return RedirectToPage("/Index");
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await _userManager.FindByIdAsync(userId);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{userId}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code));
|
||||||
|
var result = await _userManager.ConfirmEmailAsync(user, code);
|
||||||
|
StatusMessage = result.Succeeded ? "Thank you for confirming your email." : "Error confirming your email.";
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
@page
|
||||||
|
@model ConfirmEmailChangeModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Confirm email change";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<partial name="_StatusMessage" model="Model.StatusMessage" />
|
@ -0,0 +1,70 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
public class ConfirmEmailChangeModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
|
||||||
|
public ConfirmEmailChangeModel(UserManager<UserModel> userManager, SignInManager<UserModel> signInManager)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync(string userId, string email, string code)
|
||||||
|
{
|
||||||
|
if (userId == null || email == null || code == null)
|
||||||
|
{
|
||||||
|
return RedirectToPage("/Index");
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await _userManager.FindByIdAsync(userId);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{userId}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code));
|
||||||
|
var result = await _userManager.ChangeEmailAsync(user, email, code);
|
||||||
|
if (!result.Succeeded)
|
||||||
|
{
|
||||||
|
StatusMessage = "Error changing email.";
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
// In our UI email and user name are one and the same, so when we update the email
|
||||||
|
// we need to update the user name.
|
||||||
|
var setUserNameResult = await _userManager.SetUserNameAsync(user, email);
|
||||||
|
if (!setUserNameResult.Succeeded)
|
||||||
|
{
|
||||||
|
StatusMessage = "Error changing user name.";
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
await _signInManager.RefreshSignInAsync(user);
|
||||||
|
StatusMessage = "Thank you for confirming your email change.";
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
AGSS/Areas/Identity/Pages/Account/ExternalLogin.cshtml
Normal file
33
AGSS/Areas/Identity/Pages/Account/ExternalLogin.cshtml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
@page
|
||||||
|
@model ExternalLoginModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Register";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<h2 id="external-login-title">Associate your @Model.ProviderDisplayName account.</h2>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<p id="external-login-description" class="text-info">
|
||||||
|
You've successfully authenticated with <strong>@Model.ProviderDisplayName</strong>.
|
||||||
|
Please enter an email address for this site below and click the Register button to finish
|
||||||
|
logging in.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form asp-page-handler="Confirmation" asp-route-returnUrl="@Model.ReturnUrl" method="post">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Email" class="form-control" autocomplete="email" placeholder="Please enter your email."/>
|
||||||
|
<label asp-for="Input.Email" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-100 btn btn-lg btn-primary">Register</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
224
AGSS/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs
Normal file
224
AGSS/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
[AllowAnonymous]
|
||||||
|
public class ExternalLoginModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly IUserStore<UserModel> _userStore;
|
||||||
|
private readonly IUserEmailStore<UserModel> _emailStore;
|
||||||
|
private readonly IEmailSender _emailSender;
|
||||||
|
private readonly ILogger<ExternalLoginModel> _logger;
|
||||||
|
|
||||||
|
public ExternalLoginModel(
|
||||||
|
SignInManager<UserModel> signInManager,
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
IUserStore<UserModel> userStore,
|
||||||
|
ILogger<ExternalLoginModel> logger,
|
||||||
|
IEmailSender emailSender)
|
||||||
|
{
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_userManager = userManager;
|
||||||
|
_userStore = userStore;
|
||||||
|
_emailStore = GetEmailStore();
|
||||||
|
_logger = logger;
|
||||||
|
_emailSender = emailSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string ProviderDisplayName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string ErrorMessage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
public string Email { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult OnGet() => RedirectToPage("./Login");
|
||||||
|
|
||||||
|
public IActionResult OnPost(string provider, string returnUrl = null)
|
||||||
|
{
|
||||||
|
// Request a redirect to the external login provider.
|
||||||
|
var redirectUrl = Url.Page("./ExternalLogin", pageHandler: "Callback", values: new { returnUrl });
|
||||||
|
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
|
||||||
|
return new ChallengeResult(provider, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null)
|
||||||
|
{
|
||||||
|
returnUrl = returnUrl ?? Url.Content("~/");
|
||||||
|
if (remoteError != null)
|
||||||
|
{
|
||||||
|
ErrorMessage = $"Error from external provider: {remoteError}";
|
||||||
|
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
|
||||||
|
}
|
||||||
|
var info = await _signInManager.GetExternalLoginInfoAsync();
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
ErrorMessage = "Error loading external login information.";
|
||||||
|
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign in the user with this external login provider if the user already has a login.
|
||||||
|
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity.Name, info.LoginProvider);
|
||||||
|
return LocalRedirect(returnUrl);
|
||||||
|
}
|
||||||
|
if (result.IsLockedOut)
|
||||||
|
{
|
||||||
|
return RedirectToPage("./Lockout");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the user does not have an account, then ask the user to create an account.
|
||||||
|
ReturnUrl = returnUrl;
|
||||||
|
ProviderDisplayName = info.ProviderDisplayName;
|
||||||
|
if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email))
|
||||||
|
{
|
||||||
|
Input = new InputModel
|
||||||
|
{
|
||||||
|
Email = info.Principal.FindFirstValue(ClaimTypes.Email)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostConfirmationAsync(string returnUrl = null)
|
||||||
|
{
|
||||||
|
returnUrl = returnUrl ?? Url.Content("~/");
|
||||||
|
// Get the information about the user from the external login provider
|
||||||
|
var info = await _signInManager.GetExternalLoginInfoAsync();
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
ErrorMessage = "Error loading external login information during confirmation.";
|
||||||
|
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var user = CreateUser();
|
||||||
|
|
||||||
|
await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
|
||||||
|
await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
|
||||||
|
|
||||||
|
var result = await _userManager.CreateAsync(user);
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
result = await _userManager.AddLoginAsync(user, info);
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||||
|
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
|
||||||
|
var callbackUrl = Url.Page(
|
||||||
|
"/Account/ConfirmEmail",
|
||||||
|
pageHandler: null,
|
||||||
|
values: new { area = "Identity", userId = userId, code = code },
|
||||||
|
protocol: Request.Scheme);
|
||||||
|
|
||||||
|
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
|
||||||
|
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
|
||||||
|
|
||||||
|
// If account confirmation is required, we need to show the link if we don't have a real email sender
|
||||||
|
if (_userManager.Options.SignIn.RequireConfirmedAccount)
|
||||||
|
{
|
||||||
|
return RedirectToPage("./RegisterConfirmation", new { Email = Input.Email });
|
||||||
|
}
|
||||||
|
|
||||||
|
await _signInManager.SignInAsync(user, isPersistent: false, info.LoginProvider);
|
||||||
|
return LocalRedirect(returnUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var error in result.Errors)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, error.Description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProviderDisplayName = info.ProviderDisplayName;
|
||||||
|
ReturnUrl = returnUrl;
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserModel CreateUser()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Activator.CreateInstance<UserModel>();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Can't create an instance of '{nameof(UserModel)}'. " +
|
||||||
|
$"Ensure that '{nameof(UserModel)}' is not an abstract class and has a parameterless constructor, or alternatively " +
|
||||||
|
$"override the external login page in /Areas/Identity/Pages/Account/ExternalLogin.cshtml");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IUserEmailStore<UserModel> GetEmailStore()
|
||||||
|
{
|
||||||
|
if (!_userManager.SupportsUserEmail)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("The default UI requires a user store with email support.");
|
||||||
|
}
|
||||||
|
return (IUserEmailStore<UserModel>)_userStore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
AGSS/Areas/Identity/Pages/Account/ForgotPassword.cshtml
Normal file
26
AGSS/Areas/Identity/Pages/Account/ForgotPassword.cshtml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
@page
|
||||||
|
@model ForgotPasswordModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Forgot your password?";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<h2>Enter your email.</h2>
|
||||||
|
<hr />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form method="post">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
|
||||||
|
<label asp-for="Input.Email" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-100 btn btn-lg btn-primary">Reset Password</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
85
AGSS/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs
Normal file
85
AGSS/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
public class ForgotPasswordModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly IEmailSender _emailSender;
|
||||||
|
|
||||||
|
public ForgotPasswordModel(UserManager<UserModel> userManager, IEmailSender emailSender)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_emailSender = emailSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
public string Email { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var user = await _userManager.FindByEmailAsync(Input.Email);
|
||||||
|
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))
|
||||||
|
{
|
||||||
|
// Don't reveal that the user does not exist or is not confirmed
|
||||||
|
return RedirectToPage("./ForgotPasswordConfirmation");
|
||||||
|
}
|
||||||
|
|
||||||
|
// For more information on how to enable account confirmation and password reset please
|
||||||
|
// visit https://go.microsoft.com/fwlink/?LinkID=532713
|
||||||
|
var code = await _userManager.GeneratePasswordResetTokenAsync(user);
|
||||||
|
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
|
||||||
|
var callbackUrl = Url.Page(
|
||||||
|
"/Account/ResetPassword",
|
||||||
|
pageHandler: null,
|
||||||
|
values: new { area = "Identity", code },
|
||||||
|
protocol: Request.Scheme);
|
||||||
|
|
||||||
|
await _emailSender.SendEmailAsync(
|
||||||
|
Input.Email,
|
||||||
|
"Reset Password",
|
||||||
|
$"Please reset your password by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
|
||||||
|
|
||||||
|
return RedirectToPage("./ForgotPasswordConfirmation");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
@page
|
||||||
|
@model ForgotPasswordConfirmation
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Forgot password confirmation";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<p>
|
||||||
|
Please check your email to reset your password.
|
||||||
|
</p>
|
@ -0,0 +1,25 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[AllowAnonymous]
|
||||||
|
public class ForgotPasswordConfirmation : PageModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public void OnGet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
AGSS/Areas/Identity/Pages/Account/Lockout.cshtml
Normal file
10
AGSS/Areas/Identity/Pages/Account/Lockout.cshtml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@page
|
||||||
|
@model LockoutModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Locked out";
|
||||||
|
}
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1 class="text-danger">@ViewData["Title"]</h1>
|
||||||
|
<p class="text-danger">This account has been locked out, please try again later.</p>
|
||||||
|
</header>
|
25
AGSS/Areas/Identity/Pages/Account/Lockout.cshtml.cs
Normal file
25
AGSS/Areas/Identity/Pages/Account/Lockout.cshtml.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[AllowAnonymous]
|
||||||
|
public class LockoutModel : PageModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public void OnGet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
82
AGSS/Areas/Identity/Pages/Account/Login.cshtml
Normal file
82
AGSS/Areas/Identity/Pages/Account/Login.cshtml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
@page
|
||||||
|
@model LoginModel
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "登录";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<section>
|
||||||
|
<form id="account" method="post">
|
||||||
|
<h2>使用本地账户登录。</h2>
|
||||||
|
<hr />
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
|
||||||
|
<label asp-for="Input.Email" class="form-label">电子邮件</label>
|
||||||
|
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Password" class="form-control" autocomplete="current-password" aria-required="true" placeholder="password" />
|
||||||
|
<label asp-for="Input.Password" class="form-label">密码</label>
|
||||||
|
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox mb-3">
|
||||||
|
<label asp-for="Input.RememberMe" class="form-label">
|
||||||
|
<input class="form-check-input" asp-for="Input.RememberMe" />
|
||||||
|
记住我
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button id="login-submit" type="submit" class="w-100 btn btn-lg btn-primary">登录</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<a id="forgot-password" asp-page="./ForgotPassword">忘记密码?</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">注册为新用户</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a id="resend-confirmation" asp-page="./ResendEmailConfirmation">重新发送电子邮件确认</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-md-offset-2">
|
||||||
|
<section>
|
||||||
|
<h3>使用其他服务登录。</h3>
|
||||||
|
<hr />
|
||||||
|
@{
|
||||||
|
if ((Model.ExternalLogins?.Count ?? 0) == 0)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
没有配置外部身份验证服务。请参阅<a href="https://go.microsoft.com/fwlink/?LinkID=532715">关于设置此ASP.NET应用程序以支持通过外部服务登录的文章</a>。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
@foreach (var provider in Model.ExternalLogins!)
|
||||||
|
{
|
||||||
|
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
156
AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs
Normal file
156
AGSS/Areas/Identity/Pages/Account/Login.cshtml.cs
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using AGSS.Utilities;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
public class LoginModel : PageModel
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly ILogger<LoginModel> _logger;
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly Jwt _jwt;
|
||||||
|
|
||||||
|
|
||||||
|
public LoginModel(SignInManager<UserModel> signInManager, ILogger<LoginModel> logger,UserManager<UserModel> userManager,Jwt jwt
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_logger = logger;
|
||||||
|
_userManager = userManager;
|
||||||
|
_jwt = jwt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public IList<AuthenticationScheme> ExternalLogins { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string ErrorMessage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "Remember me?")]
|
||||||
|
public bool RememberMe { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnGetAsync(string returnUrl = null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(ErrorMessage))
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, ErrorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
returnUrl ??= Url.Content("~/");
|
||||||
|
|
||||||
|
// Clear the existing external cookie to ensure a clean login process
|
||||||
|
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
|
||||||
|
|
||||||
|
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
|
||||||
|
|
||||||
|
ReturnUrl = returnUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
|
||||||
|
{
|
||||||
|
returnUrl ??= Url.Content("~/");
|
||||||
|
|
||||||
|
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
|
||||||
|
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
// This doesn't count login failures towards account lockout
|
||||||
|
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
|
||||||
|
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("User logged in.");
|
||||||
|
|
||||||
|
var user = await _userManager.FindByEmailAsync(Input.Email);
|
||||||
|
var token = _jwt.GenerateJwtToken(user);
|
||||||
|
|
||||||
|
var frontendCallback = $"{Request.Query["frontendCallback"]}?token={token}";
|
||||||
|
|
||||||
|
return Redirect(frontendCallback);
|
||||||
|
}
|
||||||
|
if (result.RequiresTwoFactor)
|
||||||
|
{
|
||||||
|
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
|
||||||
|
}
|
||||||
|
if (result.IsLockedOut)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("User account locked out.");
|
||||||
|
return RedirectToPage("./Lockout");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got this far, something failed, redisplay form
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
AGSS/Areas/Identity/Pages/Account/LoginWith2fa.cshtml
Normal file
39
AGSS/Areas/Identity/Pages/Account/LoginWith2fa.cshtml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
@page
|
||||||
|
@model LoginWith2faModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Two-factor authentication";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<hr />
|
||||||
|
<p>Your login is protected with an authenticator app. Enter your authenticator code below.</p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form method="post" asp-route-returnUrl="@Model.ReturnUrl">
|
||||||
|
<input asp-for="RememberMe" type="hidden" />
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.TwoFactorCode" class="form-control" autocomplete="off" />
|
||||||
|
<label asp-for="Input.TwoFactorCode" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.TwoFactorCode" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox mb-3">
|
||||||
|
<label asp-for="Input.RememberMachine" class="form-label">
|
||||||
|
<input asp-for="Input.RememberMachine" />
|
||||||
|
@Html.DisplayNameFor(m => m.Input.RememberMachine)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Don't have access to your authenticator device? You can
|
||||||
|
<a id="recovery-code-login" asp-page="./LoginWithRecoveryCode" asp-route-returnUrl="@Model.ReturnUrl">log in with a recovery code</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
132
AGSS/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs
Normal file
132
AGSS/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
public class LoginWith2faModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly ILogger<LoginWith2faModel> _logger;
|
||||||
|
|
||||||
|
public LoginWith2faModel(
|
||||||
|
SignInManager<UserModel> signInManager,
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
ILogger<LoginWith2faModel> logger)
|
||||||
|
{
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_userManager = userManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public bool RememberMe { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[StringLength(7, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
|
||||||
|
[DataType(DataType.Text)]
|
||||||
|
[Display(Name = "Authenticator code")]
|
||||||
|
public string TwoFactorCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "Remember this machine")]
|
||||||
|
public bool RememberMachine { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync(bool rememberMe, string returnUrl = null)
|
||||||
|
{
|
||||||
|
// Ensure the user has gone through the username & password screen first
|
||||||
|
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Unable to load two-factor authentication user.");
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnUrl = returnUrl;
|
||||||
|
RememberMe = rememberMe;
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync(bool rememberMe, string returnUrl = null)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
returnUrl = returnUrl ?? Url.Content("~/");
|
||||||
|
|
||||||
|
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Unable to load two-factor authentication user.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var authenticatorCode = Input.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty);
|
||||||
|
|
||||||
|
var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, Input.RememberMachine);
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' logged in with 2fa.", user.Id);
|
||||||
|
return LocalRedirect(returnUrl);
|
||||||
|
}
|
||||||
|
else if (result.IsLockedOut)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("User with ID '{UserId}' account locked out.", user.Id);
|
||||||
|
return RedirectToPage("./Lockout");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Invalid authenticator code entered for user with ID '{UserId}'.", user.Id);
|
||||||
|
ModelState.AddModelError(string.Empty, "Invalid authenticator code.");
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
@page
|
||||||
|
@model LoginWithRecoveryCodeModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Recovery code verification";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<hr />
|
||||||
|
<p>
|
||||||
|
You have requested to log in with a recovery code. This login will not be remembered until you provide
|
||||||
|
an authenticator app code at log in or disable 2FA and log in again.
|
||||||
|
</p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form method="post">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.RecoveryCode" class="form-control" autocomplete="off" placeholder="RecoveryCode" />
|
||||||
|
<label asp-for="Input.RecoveryCode" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.RecoveryCode" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
public class LoginWithRecoveryCodeModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly ILogger<LoginWithRecoveryCodeModel> _logger;
|
||||||
|
|
||||||
|
public LoginWithRecoveryCodeModel(
|
||||||
|
SignInManager<UserModel> signInManager,
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
ILogger<LoginWithRecoveryCodeModel> logger)
|
||||||
|
{
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_userManager = userManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.Text)]
|
||||||
|
[Display(Name = "Recovery Code")]
|
||||||
|
public string RecoveryCode { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync(string returnUrl = null)
|
||||||
|
{
|
||||||
|
// Ensure the user has gone through the username & password screen first
|
||||||
|
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Unable to load two-factor authentication user.");
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnUrl = returnUrl;
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Unable to load two-factor authentication user.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var recoveryCode = Input.RecoveryCode.Replace(" ", string.Empty);
|
||||||
|
|
||||||
|
var result = await _signInManager.TwoFactorRecoveryCodeSignInAsync(recoveryCode);
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' logged in with a recovery code.", user.Id);
|
||||||
|
return LocalRedirect(returnUrl ?? Url.Content("~/"));
|
||||||
|
}
|
||||||
|
if (result.IsLockedOut)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("User account locked out.");
|
||||||
|
return RedirectToPage("./Lockout");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Invalid recovery code entered for user with ID '{UserId}' ", user.Id);
|
||||||
|
ModelState.AddModelError(string.Empty, "Invalid recovery code entered.");
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
AGSS/Areas/Identity/Pages/Account/Logout.cshtml
Normal file
21
AGSS/Areas/Identity/Pages/Account/Logout.cshtml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@page
|
||||||
|
@model LogoutModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Log out";
|
||||||
|
}
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
@{
|
||||||
|
if (User.Identity?.IsAuthenticated ?? false)
|
||||||
|
{
|
||||||
|
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post">
|
||||||
|
<button type="submit" class="nav-link btn btn-link text-dark">Click here to Logout</button>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<p>You have successfully logged out of the application.</p>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</header>
|
43
AGSS/Areas/Identity/Pages/Account/Logout.cshtml.cs
Normal file
43
AGSS/Areas/Identity/Pages/Account/Logout.cshtml.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
public class LogoutModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly ILogger<LogoutModel> _logger;
|
||||||
|
|
||||||
|
public LogoutModel(SignInManager<UserModel> signInManager, ILogger<LogoutModel> logger)
|
||||||
|
{
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPost(string returnUrl = null)
|
||||||
|
{
|
||||||
|
await _signInManager.SignOutAsync();
|
||||||
|
_logger.LogInformation("User logged out.");
|
||||||
|
if (returnUrl != null)
|
||||||
|
{
|
||||||
|
return LocalRedirect(returnUrl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This needs to be a redirect so that the browser performs a new
|
||||||
|
// request and the identity for the user gets updated.
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
@page
|
||||||
|
@model ChangePasswordModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Change password";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.ChangePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form id="change-password-form" method="post">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.OldPassword" class="form-control" autocomplete="current-password" aria-required="true" placeholder="Please enter your old password." />
|
||||||
|
<label asp-for="Input.OldPassword" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.OldPassword" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.NewPassword" class="form-control" autocomplete="new-password" aria-required="true" placeholder="Please enter your new password." />
|
||||||
|
<label asp-for="Input.NewPassword" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.NewPassword" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.ConfirmPassword" class="form-control" autocomplete="new-password" aria-required="true" placeholder="Please confirm your new password."/>
|
||||||
|
<label asp-for="Input.ConfirmPassword" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-100 btn btn-lg btn-primary">Update password</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class ChangePasswordModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly ILogger<ChangePasswordModel> _logger;
|
||||||
|
|
||||||
|
public ChangePasswordModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
SignInManager<UserModel> signInManager,
|
||||||
|
ILogger<ChangePasswordModel> logger)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Current password")]
|
||||||
|
public string OldPassword { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "New password")]
|
||||||
|
public string NewPassword { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Confirm new password")]
|
||||||
|
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasPassword = await _userManager.HasPasswordAsync(user);
|
||||||
|
if (!hasPassword)
|
||||||
|
{
|
||||||
|
return RedirectToPage("./SetPassword");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var changePasswordResult = await _userManager.ChangePasswordAsync(user, Input.OldPassword, Input.NewPassword);
|
||||||
|
if (!changePasswordResult.Succeeded)
|
||||||
|
{
|
||||||
|
foreach (var error in changePasswordResult.Errors)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, error.Description);
|
||||||
|
}
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
await _signInManager.RefreshSignInAsync(user);
|
||||||
|
_logger.LogInformation("User changed their password successfully.");
|
||||||
|
StatusMessage = "Your password has been changed.";
|
||||||
|
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
@page
|
||||||
|
@model DeletePersonalDataModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Delete Personal Data";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.PersonalData;
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<p>
|
||||||
|
<strong>Deleting this data will permanently remove your account, and this cannot be recovered.</strong>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<form id="delete-user" method="post">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
@if (Model.RequirePassword)
|
||||||
|
{
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Password" class="form-control" autocomplete="current-password" aria-required="true" placeholder="Please enter your password." />
|
||||||
|
<label asp-for="Input.Password" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<button class="w-100 btn btn-lg btn-danger" type="submit">Delete data and close my account</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class DeletePersonalDataModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly ILogger<DeletePersonalDataModel> _logger;
|
||||||
|
|
||||||
|
public DeletePersonalDataModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
SignInManager<UserModel> signInManager,
|
||||||
|
ILogger<DeletePersonalDataModel> logger)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public bool RequirePassword { get; set; }
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGet()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
RequirePassword = await _userManager.HasPasswordAsync(user);
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
RequirePassword = await _userManager.HasPasswordAsync(user);
|
||||||
|
if (RequirePassword)
|
||||||
|
{
|
||||||
|
if (!await _userManager.CheckPasswordAsync(user, Input.Password))
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, "Incorrect password.");
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await _userManager.DeleteAsync(user);
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
if (!result.Succeeded)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Unexpected error occurred deleting user.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await _signInManager.SignOutAsync();
|
||||||
|
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' deleted themselves.", userId);
|
||||||
|
|
||||||
|
return Redirect("~/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
AGSS/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml
Normal file
25
AGSS/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
@page
|
||||||
|
@model Disable2faModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Disable two-factor authentication (2FA)";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<p>
|
||||||
|
<strong>This action only disables 2FA.</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Disabling 2FA does not change the keys used in authenticator apps. If you wish to change the key
|
||||||
|
used in an authenticator app you should <a asp-page="./ResetAuthenticator">reset your authenticator keys.</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<form method="post">
|
||||||
|
<button class="btn btn-danger" type="submit">Disable 2FA</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
@ -0,0 +1,70 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class Disable2faModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly ILogger<Disable2faModel> _logger;
|
||||||
|
|
||||||
|
public Disable2faModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
ILogger<Disable2faModel> logger)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGet()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await _userManager.GetTwoFactorEnabledAsync(user))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Cannot disable 2FA for user as it's not currently enabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var disable2faResult = await _userManager.SetTwoFactorEnabledAsync(user, false);
|
||||||
|
if (!disable2faResult.Succeeded)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Unexpected error occurred disabling 2FA.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' has disabled 2fa.", _userManager.GetUserId(User));
|
||||||
|
StatusMessage = "2fa has been disabled. You can reenable 2fa when you setup an authenticator app";
|
||||||
|
return RedirectToPage("./TwoFactorAuthentication");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
@page
|
||||||
|
@model DownloadPersonalDataModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Download Your Data";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.PersonalData;
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class DownloadPersonalDataModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly ILogger<DownloadPersonalDataModel> _logger;
|
||||||
|
|
||||||
|
public DownloadPersonalDataModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
ILogger<DownloadPersonalDataModel> logger)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult OnGet()
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' asked for their personal data.", _userManager.GetUserId(User));
|
||||||
|
|
||||||
|
// Only include personal data for download
|
||||||
|
var personalData = new Dictionary<string, string>();
|
||||||
|
var personalDataProps = typeof(UserModel).GetProperties().Where(
|
||||||
|
prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute)));
|
||||||
|
foreach (var p in personalDataProps)
|
||||||
|
{
|
||||||
|
personalData.Add(p.Name, p.GetValue(user)?.ToString() ?? "null");
|
||||||
|
}
|
||||||
|
|
||||||
|
var logins = await _userManager.GetLoginsAsync(user);
|
||||||
|
foreach (var l in logins)
|
||||||
|
{
|
||||||
|
personalData.Add($"{l.LoginProvider} external login provider key", l.ProviderKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
personalData.Add($"Authenticator Key", await _userManager.GetAuthenticatorKeyAsync(user));
|
||||||
|
|
||||||
|
Response.Headers.TryAdd("Content-Disposition", "attachment; filename=PersonalData.json");
|
||||||
|
return new FileContentResult(JsonSerializer.SerializeToUtf8Bytes(personalData), "application/json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
AGSS/Areas/Identity/Pages/Account/Manage/Email.cshtml
Normal file
44
AGSS/Areas/Identity/Pages/Account/Manage/Email.cshtml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@page
|
||||||
|
@model EmailModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Manage Email";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.Email;
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form id="email-form" method="post">
|
||||||
|
<div asp-validation-summary="All" class="text-danger" role="alert"></div>
|
||||||
|
@if (Model.IsEmailConfirmed)
|
||||||
|
{
|
||||||
|
<div class="form-floating mb-3 input-group">
|
||||||
|
<input asp-for="Email" class="form-control" placeholder="Please enter your email." disabled />
|
||||||
|
<div class="input-group-append">
|
||||||
|
<span class="h-100 input-group-text text-success font-weight-bold">✓</span>
|
||||||
|
</div>
|
||||||
|
<label asp-for="Email" class="form-label"></label>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Email" class="form-control" placeholder="Please enter your email." disabled />
|
||||||
|
<label asp-for="Email" class="form-label"></label>
|
||||||
|
<button id="email-verification" type="submit" asp-page-handler="SendVerificationEmail" class="btn btn-link">Send verification email</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.NewEmail" class="form-control" autocomplete="email" aria-required="true" placeholder="Please enter new email." />
|
||||||
|
<label asp-for="Input.NewEmail" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.NewEmail" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button id="change-email-button" type="submit" asp-page-handler="ChangeEmail" class="w-100 btn btn-lg btn-primary">Change email</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
172
AGSS/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs
Normal file
172
AGSS/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class EmailModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly IEmailSender _emailSender;
|
||||||
|
|
||||||
|
public EmailModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
SignInManager<UserModel> signInManager,
|
||||||
|
IEmailSender emailSender)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_emailSender = emailSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsEmailConfirmed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
[Display(Name = "New email")]
|
||||||
|
public string NewEmail { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadAsync(UserModel user)
|
||||||
|
{
|
||||||
|
var email = await _userManager.GetEmailAsync(user);
|
||||||
|
Email = email;
|
||||||
|
|
||||||
|
Input = new InputModel
|
||||||
|
{
|
||||||
|
NewEmail = email,
|
||||||
|
};
|
||||||
|
|
||||||
|
IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await LoadAsync(user);
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostChangeEmailAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
await LoadAsync(user);
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
var email = await _userManager.GetEmailAsync(user);
|
||||||
|
if (Input.NewEmail != email)
|
||||||
|
{
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
var code = await _userManager.GenerateChangeEmailTokenAsync(user, Input.NewEmail);
|
||||||
|
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
|
||||||
|
var callbackUrl = Url.Page(
|
||||||
|
"/Account/ConfirmEmailChange",
|
||||||
|
pageHandler: null,
|
||||||
|
values: new { area = "Identity", userId = userId, email = Input.NewEmail, code = code },
|
||||||
|
protocol: Request.Scheme);
|
||||||
|
await _emailSender.SendEmailAsync(
|
||||||
|
Input.NewEmail,
|
||||||
|
"Confirm your email",
|
||||||
|
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
|
||||||
|
|
||||||
|
StatusMessage = "Confirmation link to change email sent. Please check your email.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusMessage = "Your email is unchanged.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostSendVerificationEmailAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
await LoadAsync(user);
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
var email = await _userManager.GetEmailAsync(user);
|
||||||
|
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||||
|
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
|
||||||
|
var callbackUrl = Url.Page(
|
||||||
|
"/Account/ConfirmEmail",
|
||||||
|
pageHandler: null,
|
||||||
|
values: new { area = "Identity", userId = userId, code = code },
|
||||||
|
protocol: Request.Scheme);
|
||||||
|
await _emailSender.SendEmailAsync(
|
||||||
|
email,
|
||||||
|
"Confirm your email",
|
||||||
|
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
|
||||||
|
|
||||||
|
StatusMessage = "Verification email sent. Please check your email.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
@page
|
||||||
|
@model EnableAuthenticatorModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Configure authenticator app";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
<div>
|
||||||
|
<p>To use an authenticator app go through the following steps:</p>
|
||||||
|
<ol class="list">
|
||||||
|
<li>
|
||||||
|
<p>
|
||||||
|
Download a two-factor authenticator app like Microsoft Authenticator for
|
||||||
|
<a href="https://go.microsoft.com/fwlink/?Linkid=825072">Android</a> and
|
||||||
|
<a href="https://go.microsoft.com/fwlink/?Linkid=825073">iOS</a> or
|
||||||
|
Google Authenticator for
|
||||||
|
<a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en">Android</a> and
|
||||||
|
<a href="https://itunes.apple.com/us/app/google-authenticator/id388497605?mt=8">iOS</a>.
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Scan the QR Code or enter this key <kbd>@Model.SharedKey</kbd> into your two factor authenticator app. Spaces and casing do not matter.</p>
|
||||||
|
<div class="alert alert-info">Learn how to <a href="https://go.microsoft.com/fwlink/?Linkid=852423">enable QR code generation</a>.</div>
|
||||||
|
<div id="qrCode"></div>
|
||||||
|
<div id="qrCodeData" data-url="@Model.AuthenticatorUri"></div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>
|
||||||
|
Once you have scanned the QR code or input the key above, your two factor authentication app will provide you
|
||||||
|
with a unique code. Enter the code in the confirmation box below.
|
||||||
|
</p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form id="send-code" method="post">
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Code" class="form-control" autocomplete="off" placeholder="Please enter the code."/>
|
||||||
|
<label asp-for="Input.Code" class="control-label form-label">Verification Code</label>
|
||||||
|
<span asp-validation-for="Input.Code" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-100 btn btn-lg btn-primary">Verify</button>
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
@ -0,0 +1,189 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class EnableAuthenticatorModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly ILogger<EnableAuthenticatorModel> _logger;
|
||||||
|
private readonly UrlEncoder _urlEncoder;
|
||||||
|
|
||||||
|
private const string AuthenticatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6";
|
||||||
|
|
||||||
|
public EnableAuthenticatorModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
ILogger<EnableAuthenticatorModel> logger,
|
||||||
|
UrlEncoder urlEncoder)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_logger = logger;
|
||||||
|
_urlEncoder = urlEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string SharedKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string AuthenticatorUri { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string[] RecoveryCodes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[StringLength(7, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
|
||||||
|
[DataType(DataType.Text)]
|
||||||
|
[Display(Name = "Verification Code")]
|
||||||
|
public string Code { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await LoadSharedKeyAndQrCodeUriAsync(user);
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
await LoadSharedKeyAndQrCodeUriAsync(user);
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip spaces and hyphens
|
||||||
|
var verificationCode = Input.Code.Replace(" ", string.Empty).Replace("-", string.Empty);
|
||||||
|
|
||||||
|
var is2faTokenValid = await _userManager.VerifyTwoFactorTokenAsync(
|
||||||
|
user, _userManager.Options.Tokens.AuthenticatorTokenProvider, verificationCode);
|
||||||
|
|
||||||
|
if (!is2faTokenValid)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError("Input.Code", "Verification code is invalid.");
|
||||||
|
await LoadSharedKeyAndQrCodeUriAsync(user);
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
await _userManager.SetTwoFactorEnabledAsync(user, true);
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' has enabled 2FA with an authenticator app.", userId);
|
||||||
|
|
||||||
|
StatusMessage = "Your authenticator app has been verified.";
|
||||||
|
|
||||||
|
if (await _userManager.CountRecoveryCodesAsync(user) == 0)
|
||||||
|
{
|
||||||
|
var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
|
||||||
|
RecoveryCodes = recoveryCodes.ToArray();
|
||||||
|
return RedirectToPage("./ShowRecoveryCodes");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RedirectToPage("./TwoFactorAuthentication");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadSharedKeyAndQrCodeUriAsync(UserModel user)
|
||||||
|
{
|
||||||
|
// Load the authenticator key & QR code URI to display on the form
|
||||||
|
var unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user);
|
||||||
|
if (string.IsNullOrEmpty(unformattedKey))
|
||||||
|
{
|
||||||
|
await _userManager.ResetAuthenticatorKeyAsync(user);
|
||||||
|
unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedKey = FormatKey(unformattedKey);
|
||||||
|
|
||||||
|
var email = await _userManager.GetEmailAsync(user);
|
||||||
|
AuthenticatorUri = GenerateQrCodeUri(email, unformattedKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string FormatKey(string unformattedKey)
|
||||||
|
{
|
||||||
|
var result = new StringBuilder();
|
||||||
|
int currentPosition = 0;
|
||||||
|
while (currentPosition + 4 < unformattedKey.Length)
|
||||||
|
{
|
||||||
|
result.Append(unformattedKey.AsSpan(currentPosition, 4)).Append(' ');
|
||||||
|
currentPosition += 4;
|
||||||
|
}
|
||||||
|
if (currentPosition < unformattedKey.Length)
|
||||||
|
{
|
||||||
|
result.Append(unformattedKey.AsSpan(currentPosition));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToString().ToLowerInvariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GenerateQrCodeUri(string email, string unformattedKey)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
AuthenticatorUriFormat,
|
||||||
|
_urlEncoder.Encode("Microsoft.AspNetCore.Identity.UI"),
|
||||||
|
_urlEncoder.Encode(email),
|
||||||
|
unformattedKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
@page
|
||||||
|
@model ExternalLoginsModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Manage your external logins";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.ExternalLogins;
|
||||||
|
}
|
||||||
|
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
@if (Model.CurrentLogins?.Count > 0)
|
||||||
|
{
|
||||||
|
<h3>Registered Logins</h3>
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
@foreach (var login in Model.CurrentLogins)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td id="@($"login-provider-{login.LoginProvider}")">@login.ProviderDisplayName</td>
|
||||||
|
<td>
|
||||||
|
@if (Model.ShowRemoveButton)
|
||||||
|
{
|
||||||
|
<form id="@($"remove-login-{login.LoginProvider}")" asp-page-handler="RemoveLogin" method="post">
|
||||||
|
<div>
|
||||||
|
<input asp-for="@login.LoginProvider" name="LoginProvider" type="hidden" />
|
||||||
|
<input asp-for="@login.ProviderKey" name="ProviderKey" type="hidden" />
|
||||||
|
<button type="submit" class="btn btn-primary" title="Remove this @login.ProviderDisplayName login from your account">Remove</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@:
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
}
|
||||||
|
@if (Model.OtherLogins?.Count > 0)
|
||||||
|
{
|
||||||
|
<h4>Add another service to log in.</h4>
|
||||||
|
<hr />
|
||||||
|
<form id="link-login-form" asp-page-handler="LinkLogin" method="post" class="form-horizontal">
|
||||||
|
<div id="socialLoginList">
|
||||||
|
<p>
|
||||||
|
@foreach (var provider in Model.OtherLogins)
|
||||||
|
{
|
||||||
|
<button id="@($"link-login-button-{provider.Name}")" type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
@ -0,0 +1,142 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class ExternalLoginsModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly IUserStore<UserModel> _userStore;
|
||||||
|
|
||||||
|
public ExternalLoginsModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
SignInManager<UserModel> signInManager,
|
||||||
|
IUserStore<UserModel> userStore)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_userStore = userStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public IList<UserLoginInfo> CurrentLogins { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public IList<AuthenticationScheme> OtherLogins { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public bool ShowRemoveButton { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentLogins = await _userManager.GetLoginsAsync(user);
|
||||||
|
OtherLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
|
||||||
|
.Where(auth => CurrentLogins.All(ul => auth.Name != ul.LoginProvider))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
string passwordHash = null;
|
||||||
|
if (_userStore is IUserPasswordStore<UserModel> userPasswordStore)
|
||||||
|
{
|
||||||
|
passwordHash = await userPasswordStore.GetPasswordHashAsync(user, HttpContext.RequestAborted);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowRemoveButton = passwordHash != null || CurrentLogins.Count > 1;
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostRemoveLoginAsync(string loginProvider, string providerKey)
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await _userManager.RemoveLoginAsync(user, loginProvider, providerKey);
|
||||||
|
if (!result.Succeeded)
|
||||||
|
{
|
||||||
|
StatusMessage = "The external login was not removed.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
await _signInManager.RefreshSignInAsync(user);
|
||||||
|
StatusMessage = "The external login was removed.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostLinkLoginAsync(string provider)
|
||||||
|
{
|
||||||
|
// Clear the existing external cookie to ensure a clean login process
|
||||||
|
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
|
||||||
|
|
||||||
|
// Request a redirect to the external login provider to link a login for the current user
|
||||||
|
var redirectUrl = Url.Page("./ExternalLogins", pageHandler: "LinkLoginCallback");
|
||||||
|
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
|
||||||
|
return new ChallengeResult(provider, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetLinkLoginCallbackAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
var info = await _signInManager.GetExternalLoginInfoAsync(userId);
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Unexpected error occurred loading external login info.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await _userManager.AddLoginAsync(user, info);
|
||||||
|
if (!result.Succeeded)
|
||||||
|
{
|
||||||
|
StatusMessage = "The external login was not added. External logins can only be associated with one account.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the existing external cookie to ensure a clean login process
|
||||||
|
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
|
||||||
|
|
||||||
|
StatusMessage = "The external login was added.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
@page
|
||||||
|
@model GenerateRecoveryCodesModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Generate two-factor authentication (2FA) recovery codes";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<p>
|
||||||
|
<span class="glyphicon glyphicon-warning-sign"></span>
|
||||||
|
<strong>Put these codes in a safe place.</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you lose your device and don't have the recovery codes you will lose access to your account.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Generating new recovery codes does not change the keys used in authenticator apps. If you wish to change the key
|
||||||
|
used in an authenticator app you should <a asp-page="./ResetAuthenticator">reset your authenticator keys.</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<form method="post">
|
||||||
|
<button class="btn btn-danger" type="submit">Generate Recovery Codes</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
@ -0,0 +1,83 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class GenerateRecoveryCodesModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly ILogger<GenerateRecoveryCodesModel> _logger;
|
||||||
|
|
||||||
|
public GenerateRecoveryCodesModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
ILogger<GenerateRecoveryCodesModel> logger)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string[] RecoveryCodes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var isTwoFactorEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
|
||||||
|
if (!isTwoFactorEnabled)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Cannot generate recovery codes for user because they do not have 2FA enabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var isTwoFactorEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
if (!isTwoFactorEnabled)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Cannot generate recovery codes for user as they do not have 2FA enabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
|
||||||
|
RecoveryCodes = recoveryCodes.ToArray();
|
||||||
|
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' has generated new 2FA recovery codes.", userId);
|
||||||
|
StatusMessage = "You have generated new recovery codes.";
|
||||||
|
return RedirectToPage("./ShowRecoveryCodes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
AGSS/Areas/Identity/Pages/Account/Manage/Index.cshtml
Normal file
30
AGSS/Areas/Identity/Pages/Account/Manage/Index.cshtml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
@page
|
||||||
|
@model IndexModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Profile";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form id="profile-form" method="post">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Username" class="form-control" placeholder="Please choose your username." disabled />
|
||||||
|
<label asp-for="Username" class="form-label"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.PhoneNumber" class="form-control" placeholder="Please enter your phone number."/>
|
||||||
|
<label asp-for="Input.PhoneNumber" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.PhoneNumber" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button id="update-profile-button" type="submit" class="w-100 btn btn-lg btn-primary">Save</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
119
AGSS/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs
Normal file
119
AGSS/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class IndexModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
|
||||||
|
public IndexModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
SignInManager<UserModel> signInManager)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string Username { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Phone]
|
||||||
|
[Display(Name = "Phone number")]
|
||||||
|
public string PhoneNumber { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadAsync(UserModel user)
|
||||||
|
{
|
||||||
|
var userName = await _userManager.GetUserNameAsync(user);
|
||||||
|
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
|
||||||
|
|
||||||
|
Username = userName;
|
||||||
|
|
||||||
|
Input = new InputModel
|
||||||
|
{
|
||||||
|
PhoneNumber = phoneNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await LoadAsync(user);
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
await LoadAsync(user);
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
|
||||||
|
if (Input.PhoneNumber != phoneNumber)
|
||||||
|
{
|
||||||
|
var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
|
||||||
|
if (!setPhoneResult.Succeeded)
|
||||||
|
{
|
||||||
|
StatusMessage = "Unexpected error when trying to set phone number.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _signInManager.RefreshSignInAsync(user);
|
||||||
|
StatusMessage = "Your profile has been updated";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
123
AGSS/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs
Normal file
123
AGSS/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static class ManageNavPages
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string Index => "Index";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string Email => "Email";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string ChangePassword => "ChangePassword";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string DownloadPersonalData => "DownloadPersonalData";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string DeletePersonalData => "DeletePersonalData";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string ExternalLogins => "ExternalLogins";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string PersonalData => "PersonalData";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string TwoFactorAuthentication => "TwoFactorAuthentication";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string IndexNavClass(ViewContext viewContext) => PageNavClass(viewContext, Index);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string EmailNavClass(ViewContext viewContext) => PageNavClass(viewContext, Email);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string ChangePasswordNavClass(ViewContext viewContext) => PageNavClass(viewContext, ChangePassword);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string DownloadPersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, DownloadPersonalData);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string DeletePersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, DeletePersonalData);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string ExternalLoginsNavClass(ViewContext viewContext) => PageNavClass(viewContext, ExternalLogins);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string PersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, PersonalData);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string TwoFactorAuthenticationNavClass(ViewContext viewContext) => PageNavClass(viewContext, TwoFactorAuthentication);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public static string PageNavClass(ViewContext viewContext, string page)
|
||||||
|
{
|
||||||
|
var activePage = viewContext.ViewData["ActivePage"] as string
|
||||||
|
?? System.IO.Path.GetFileNameWithoutExtension(viewContext.ActionDescriptor.DisplayName);
|
||||||
|
return string.Equals(activePage, page, StringComparison.OrdinalIgnoreCase) ? "active" : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
AGSS/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml
Normal file
27
AGSS/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
@page
|
||||||
|
@model PersonalDataModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "个人数据";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.PersonalData;
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>个人数据</h3>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<p>Your account contains personal data that you have given us. This page allows you to download or delete that data.</p>
|
||||||
|
<p>
|
||||||
|
<strong>Deleting this data will permanently remove your account, and this cannot be recovered.</strong>
|
||||||
|
</p>
|
||||||
|
<form id="download-data" asp-page="DownloadPersonalData" method="post">
|
||||||
|
<button class="btn btn-primary" type="submit">Download</button>
|
||||||
|
</form>
|
||||||
|
<p>
|
||||||
|
<a id="delete" asp-page="DeletePersonalData" class="btn btn-danger">Delete</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class PersonalDataModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly ILogger<PersonalDataModel> _logger;
|
||||||
|
|
||||||
|
public PersonalDataModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
ILogger<PersonalDataModel> logger)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGet()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
@page
|
||||||
|
@model ResetAuthenticatorModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Reset authenticator key";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<p>
|
||||||
|
<span class="glyphicon glyphicon-warning-sign"></span>
|
||||||
|
<strong>If you reset your authenticator key your authenticator app will not work until you reconfigure it.</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This process disables 2FA until you verify your authenticator app.
|
||||||
|
If you do not complete your authenticator app configuration you may lose access to your account.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<form id="reset-authenticator-form" method="post">
|
||||||
|
<button id="reset-authenticator-button" class="btn btn-danger" type="submit">Reset authenticator key</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
@ -0,0 +1,68 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class ResetAuthenticatorModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly ILogger<ResetAuthenticatorModel> _logger;
|
||||||
|
|
||||||
|
public ResetAuthenticatorModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
SignInManager<UserModel> signInManager,
|
||||||
|
ILogger<ResetAuthenticatorModel> logger)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGet()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await _userManager.SetTwoFactorEnabledAsync(user, false);
|
||||||
|
await _userManager.ResetAuthenticatorKeyAsync(user);
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' has reset their authentication app key.", user.Id);
|
||||||
|
|
||||||
|
await _signInManager.RefreshSignInAsync(user);
|
||||||
|
StatusMessage = "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key.";
|
||||||
|
|
||||||
|
return RedirectToPage("./EnableAuthenticator");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
AGSS/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml
Normal file
35
AGSS/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
@page
|
||||||
|
@model SetPasswordModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Set password";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.ChangePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>Set your password</h3>
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<p class="text-info">
|
||||||
|
You do not have a local username/password for this site. Add a local
|
||||||
|
account so you can log in without an external login.
|
||||||
|
</p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form id="set-password-form" method="post">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.NewPassword" class="form-control" autocomplete="new-password" placeholder="Please enter your new password."/>
|
||||||
|
<label asp-for="Input.NewPassword" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.NewPassword" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.ConfirmPassword" class="form-control" autocomplete="new-password" placeholder="Please confirm your new password."/>
|
||||||
|
<label asp-for="Input.ConfirmPassword" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-100 btn btn-lg btn-primary">Set password</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
115
AGSS/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs
Normal file
115
AGSS/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class SetPasswordModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
|
||||||
|
public SetPasswordModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
SignInManager<UserModel> signInManager)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "New password")]
|
||||||
|
public string NewPassword { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Confirm new password")]
|
||||||
|
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasPassword = await _userManager.HasPasswordAsync(user);
|
||||||
|
|
||||||
|
if (hasPassword)
|
||||||
|
{
|
||||||
|
return RedirectToPage("./ChangePassword");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var addPasswordResult = await _userManager.AddPasswordAsync(user, Input.NewPassword);
|
||||||
|
if (!addPasswordResult.Succeeded)
|
||||||
|
{
|
||||||
|
foreach (var error in addPasswordResult.Errors)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, error.Description);
|
||||||
|
}
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
await _signInManager.RefreshSignInAsync(user);
|
||||||
|
StatusMessage = "Your password has been set.";
|
||||||
|
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
@page
|
||||||
|
@model ShowRecoveryCodesModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Recovery codes";
|
||||||
|
ViewData["ActivePage"] = "TwoFactorAuthentication";
|
||||||
|
}
|
||||||
|
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<p>
|
||||||
|
<strong>Put these codes in a safe place.</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you lose your device and don't have the recovery codes you will lose access to your account.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
@for (var row = 0; row < Model.RecoveryCodes.Length; row += 2)
|
||||||
|
{
|
||||||
|
<code class="recovery-code">@Model.RecoveryCodes[row]</code><text> </text><code class="recovery-code">@Model.RecoveryCodes[row + 1]</code><br />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,47 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class ShowRecoveryCodesModel : PageModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string[] RecoveryCodes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public IActionResult OnGet()
|
||||||
|
{
|
||||||
|
if (RecoveryCodes == null || RecoveryCodes.Length == 0)
|
||||||
|
{
|
||||||
|
return RedirectToPage("./TwoFactorAuthentication");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
@page
|
||||||
|
@using Microsoft.AspNetCore.Http.Features
|
||||||
|
@model TwoFactorAuthenticationModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Two-factor authentication (2FA)";
|
||||||
|
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
<partial name="_StatusMessage" for="StatusMessage" />
|
||||||
|
<h3>@ViewData["Title"]</h3>
|
||||||
|
@{
|
||||||
|
var consentFeature = HttpContext.Features.Get<ITrackingConsentFeature>();
|
||||||
|
@if (consentFeature?.CanTrack ?? true)
|
||||||
|
{
|
||||||
|
@if (Model.Is2faEnabled)
|
||||||
|
{
|
||||||
|
if (Model.RecoveryCodesLeft == 0)
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<strong>You have no recovery codes left.</strong>
|
||||||
|
<p>You must <a asp-page="./GenerateRecoveryCodes">generate a new set of recovery codes</a> before you can log in with a recovery code.</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else if (Model.RecoveryCodesLeft == 1)
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<strong>You have 1 recovery code left.</strong>
|
||||||
|
<p>You can <a asp-page="./GenerateRecoveryCodes">generate a new set of recovery codes</a>.</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else if (Model.RecoveryCodesLeft <= 3)
|
||||||
|
{
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<strong>You have @Model.RecoveryCodesLeft recovery codes left.</strong>
|
||||||
|
<p>You should <a asp-page="./GenerateRecoveryCodes">generate a new set of recovery codes</a>.</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Model.IsMachineRemembered)
|
||||||
|
{
|
||||||
|
<form method="post" style="display: inline-block">
|
||||||
|
<button type="submit" class="btn btn-primary">Forget this browser</button>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
<a asp-page="./Disable2fa" class="btn btn-primary">Disable 2FA</a>
|
||||||
|
<a asp-page="./GenerateRecoveryCodes" class="btn btn-primary">Reset recovery codes</a>
|
||||||
|
}
|
||||||
|
|
||||||
|
<h4>Authenticator app</h4>
|
||||||
|
@if (!Model.HasAuthenticator)
|
||||||
|
{
|
||||||
|
<a id="enable-authenticator" asp-page="./EnableAuthenticator" class="btn btn-primary">Add authenticator app</a>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<a id="enable-authenticator" asp-page="./EnableAuthenticator" class="btn btn-primary">Set up authenticator app</a>
|
||||||
|
<a id="reset-authenticator" asp-page="./ResetAuthenticator" class="btn btn-primary">Reset authenticator app</a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<strong>Privacy and cookie policy have not been accepted.</strong>
|
||||||
|
<p>You must accept the policy before you can enable two factor authentication.</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account.Manage
|
||||||
|
{
|
||||||
|
public class TwoFactorAuthenticationModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly ILogger<TwoFactorAuthenticationModel> _logger;
|
||||||
|
|
||||||
|
public TwoFactorAuthenticationModel(
|
||||||
|
UserManager<UserModel> userManager, SignInManager<UserModel> signInManager, ILogger<TwoFactorAuthenticationModel> logger)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public bool HasAuthenticator { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public int RecoveryCodesLeft { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public bool Is2faEnabled { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsMachineRemembered { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
HasAuthenticator = await _userManager.GetAuthenticatorKeyAsync(user) != null;
|
||||||
|
Is2faEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
|
||||||
|
IsMachineRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user);
|
||||||
|
RecoveryCodesLeft = await _userManager.CountRecoveryCodesAsync(user);
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await _signInManager.ForgetTwoFactorClientAsync();
|
||||||
|
StatusMessage = "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
AGSS/Areas/Identity/Pages/Account/Manage/_Layout.cshtml
Normal file
29
AGSS/Areas/Identity/Pages/Account/Manage/_Layout.cshtml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@{
|
||||||
|
if (ViewData.TryGetValue("ParentLayout", out var parentLayout) && parentLayout != null)
|
||||||
|
{
|
||||||
|
Layout = parentLayout.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Layout = "/Areas/Identity/Pages/_Layout.cshtml";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>Manage your account</h1>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2>Change your account settings</h2>
|
||||||
|
<hr />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<partial name="_ManageNav" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
@RenderBody()
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
@RenderSection("Scripts", required: false)
|
||||||
|
}
|
15
AGSS/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml
Normal file
15
AGSS/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@inject SignInManager<UserModel> SignInManager
|
||||||
|
@{
|
||||||
|
var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any();
|
||||||
|
}
|
||||||
|
<ul class="nav nav-pills flex-column">
|
||||||
|
<li class="nav-item"><a class="nav-link @ManageNavPages.IndexNavClass(ViewContext)" id="profile" asp-page="./Index">Profile</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link @ManageNavPages.EmailNavClass(ViewContext)" id="email" asp-page="./Email">Email</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link @ManageNavPages.ChangePasswordNavClass(ViewContext)" id="change-password" asp-page="./ChangePassword">Password</a></li>
|
||||||
|
@if (hasExternalLogins)
|
||||||
|
{
|
||||||
|
<li id="external-logins" class="nav-item"><a id="external-login" class="nav-link @ManageNavPages.ExternalLoginsNavClass(ViewContext)" asp-page="./ExternalLogins">External logins</a></li>
|
||||||
|
}
|
||||||
|
<li class="nav-item"><a class="nav-link @ManageNavPages.TwoFactorAuthenticationNavClass(ViewContext)" id="two-factor" asp-page="./TwoFactorAuthentication">Two-factor authentication</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link @ManageNavPages.PersonalDataNavClass(ViewContext)" id="personal-data" asp-page="./PersonalData">Personal data</a></li>
|
||||||
|
</ul>
|
@ -0,0 +1,10 @@
|
|||||||
|
@model string
|
||||||
|
|
||||||
|
@if (!String.IsNullOrEmpty(Model))
|
||||||
|
{
|
||||||
|
var statusMessageClass = Model.StartsWith("Error") ? "danger" : "success";
|
||||||
|
<div class="alert alert-@statusMessageClass alert-dismissible" role="alert">
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
@Model
|
||||||
|
</div>
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
@using AGSS.Areas.Identity.Pages.Account.Manage
|
66
AGSS/Areas/Identity/Pages/Account/Register.cshtml
Normal file
66
AGSS/Areas/Identity/Pages/Account/Register.cshtml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
@page
|
||||||
|
@model RegisterModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "注册";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>注册</h1>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form id="registerForm" asp-route-returnUrl="@Model.ReturnUrl" method="post">
|
||||||
|
<h2>创建新账户。</h2>
|
||||||
|
<hr />
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
|
||||||
|
<label asp-for="Input.Email">电子邮件</label>
|
||||||
|
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Password" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
|
||||||
|
<label asp-for="Input.Password">密码</label>
|
||||||
|
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.ConfirmPassword" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
|
||||||
|
<label asp-for="Input.ConfirmPassword">确认密码</label>
|
||||||
|
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button id="registerSubmit" type="submit" class="w-100 btn btn-lg btn-primary">注册</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-md-offset-2">
|
||||||
|
<section>
|
||||||
|
<h3>使用其他服务注册。</h3>
|
||||||
|
<hr />
|
||||||
|
@{
|
||||||
|
if ((Model.ExternalLogins?.Count ?? 0) == 0)
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
没有配置外部身份验证服务。请参阅<a href="https://go.microsoft.com/fwlink/?LinkID=532715">关于设置此ASP.NET应用程序以支持通过外部服务登录的文章</a>。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
@foreach (var provider in Model.ExternalLogins!)
|
||||||
|
{
|
||||||
|
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
171
AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs
Normal file
171
AGSS/Areas/Identity/Pages/Account/Register.cshtml.cs
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using AGSS.Utilities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
public class RegisterModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly IUserStore<UserModel> _userStore;
|
||||||
|
private readonly IUserEmailStore<UserModel> _emailStore;
|
||||||
|
private readonly ILogger<RegisterModel> _logger;
|
||||||
|
private readonly IEmailSender _emailSender;
|
||||||
|
private readonly Jwt _jwt;
|
||||||
|
|
||||||
|
public RegisterModel(
|
||||||
|
UserManager<UserModel> userManager,
|
||||||
|
IUserStore<UserModel> userStore,
|
||||||
|
SignInManager<UserModel> signInManager,
|
||||||
|
ILogger<RegisterModel> logger,
|
||||||
|
IEmailSender emailSender,
|
||||||
|
Jwt jwt
|
||||||
|
)
|
||||||
|
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_userStore = userStore;
|
||||||
|
_emailStore = GetEmailStore();
|
||||||
|
_signInManager = signInManager;
|
||||||
|
_logger = logger;
|
||||||
|
_emailSender = emailSender;
|
||||||
|
_jwt = jwt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public IList<AuthenticationScheme> ExternalLogins { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
[Display(Name = "Email")]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Password")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Confirm password")]
|
||||||
|
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task OnGetAsync(string returnUrl = null)
|
||||||
|
{
|
||||||
|
ReturnUrl = returnUrl;
|
||||||
|
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
|
||||||
|
{
|
||||||
|
returnUrl ??= Url.Content("~/");
|
||||||
|
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var user = CreateUser();
|
||||||
|
|
||||||
|
await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
|
||||||
|
await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
|
||||||
|
var result = await _userManager.CreateAsync(user, Input.Password);
|
||||||
|
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("User created a new account with password.");
|
||||||
|
var user1 = await _userManager.FindByEmailAsync(Input.Email);
|
||||||
|
var token = _jwt.GenerateJwtToken(user1);
|
||||||
|
|
||||||
|
var frontendCallback = $"{Request.Query["frontendCallback"]}?token={token}";
|
||||||
|
|
||||||
|
return Redirect(frontendCallback);
|
||||||
|
}
|
||||||
|
foreach (var error in result.Errors)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, error.Description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got this far, something failed, redisplay form
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserModel CreateUser()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Activator.CreateInstance<UserModel>();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Can't create an instance of '{nameof(UserModel)}'. " +
|
||||||
|
$"Ensure that '{nameof(UserModel)}' is not an abstract class and has a parameterless constructor, or alternatively " +
|
||||||
|
$"override the register page in /Areas/Identity/Pages/Account/Register.cshtml");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IUserEmailStore<UserModel> GetEmailStore()
|
||||||
|
{
|
||||||
|
if (!_userManager.SupportsUserEmail)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("The default UI requires a user store with email support.");
|
||||||
|
}
|
||||||
|
return (IUserEmailStore<UserModel>)_userStore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
@page
|
||||||
|
@model RegisterConfirmationModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Register confirmation";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
@{
|
||||||
|
if (@Model.DisplayConfirmAccountLink)
|
||||||
|
{
|
||||||
|
<p>
|
||||||
|
This app does not currently have a real email sender registered, see <a href="https://aka.ms/aspaccountconf">these docs</a> for how to configure a real email sender.
|
||||||
|
Normally this would be emailed: <a id="confirm-link" href="@Model.EmailConfirmationUrl">Click here to confirm your account</a>
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<p>
|
||||||
|
Please check your email to confirm your account.
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,80 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
[AllowAnonymous]
|
||||||
|
public class RegisterConfirmationModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly IEmailSender _sender;
|
||||||
|
|
||||||
|
public RegisterConfirmationModel(UserManager<UserModel> userManager, IEmailSender sender)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public bool DisplayConfirmAccountLink { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string EmailConfirmationUrl { get; set; }
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
|
||||||
|
{
|
||||||
|
if (email == null)
|
||||||
|
{
|
||||||
|
return RedirectToPage("/Index");
|
||||||
|
}
|
||||||
|
returnUrl = returnUrl ?? Url.Content("~/");
|
||||||
|
|
||||||
|
var user = await _userManager.FindByEmailAsync(email);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with email '{email}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Email = email;
|
||||||
|
// Once you add a real email sender, you should remove this code that lets you confirm the account
|
||||||
|
DisplayConfirmAccountLink = true;
|
||||||
|
if (DisplayConfirmAccountLink)
|
||||||
|
{
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||||
|
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
|
||||||
|
EmailConfirmationUrl = Url.Page(
|
||||||
|
"/Account/ConfirmEmail",
|
||||||
|
pageHandler: null,
|
||||||
|
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
|
||||||
|
protocol: Request.Scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
@page
|
||||||
|
@model ResendEmailConfirmationModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Resend email confirmation";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<h2>Enter your email.</h2>
|
||||||
|
<hr />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form method="post">
|
||||||
|
<div asp-validation-summary="All" class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Email" class="form-control" aria-required="true" placeholder="name@example.com" />
|
||||||
|
<label asp-for="Input.Email" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-100 btn btn-lg btn-primary">Resend</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
[AllowAnonymous]
|
||||||
|
public class ResendEmailConfirmationModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
private readonly IEmailSender _emailSender;
|
||||||
|
|
||||||
|
public ResendEmailConfirmationModel(UserManager<UserModel> userManager, IEmailSender emailSender)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_emailSender = emailSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
public string Email { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnGet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await _userManager.FindByEmailAsync(Input.Email);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||||
|
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
|
||||||
|
var callbackUrl = Url.Page(
|
||||||
|
"/Account/ConfirmEmail",
|
||||||
|
pageHandler: null,
|
||||||
|
values: new { userId = userId, code = code },
|
||||||
|
protocol: Request.Scheme);
|
||||||
|
await _emailSender.SendEmailAsync(
|
||||||
|
Input.Email,
|
||||||
|
"Confirm your email",
|
||||||
|
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
|
||||||
|
|
||||||
|
ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
AGSS/Areas/Identity/Pages/Account/ResetPassword.cshtml
Normal file
37
AGSS/Areas/Identity/Pages/Account/ResetPassword.cshtml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
@page
|
||||||
|
@model ResetPasswordModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Reset password";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<h2>Reset your password.</h2>
|
||||||
|
<hr />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form method="post">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
|
||||||
|
<input asp-for="Input.Code" type="hidden" />
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
|
||||||
|
<label asp-for="Input.Email" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.Password" class="form-control" autocomplete="new-password" aria-required="true" placeholder="Please enter your password." />
|
||||||
|
<label asp-for="Input.Password" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input asp-for="Input.ConfirmPassword" class="form-control" autocomplete="new-password" aria-required="true" placeholder="Please confirm your password." />
|
||||||
|
<label asp-for="Input.ConfirmPassword" class="form-label"></label>
|
||||||
|
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-100 btn btn-lg btn-primary">Reset</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
118
AGSS/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs
Normal file
118
AGSS/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
public class ResetPasswordModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
|
||||||
|
public ResetPasswordModel(UserManager<UserModel> userManager)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[BindProperty]
|
||||||
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public class InputModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Confirm password")]
|
||||||
|
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public string Code { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult OnGet(string code = null)
|
||||||
|
{
|
||||||
|
if (code == null)
|
||||||
|
{
|
||||||
|
return BadRequest("A code must be supplied for password reset.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Input = new InputModel
|
||||||
|
{
|
||||||
|
Code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code))
|
||||||
|
};
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPostAsync()
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await _userManager.FindByEmailAsync(Input.Email);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
// Don't reveal that the user does not exist
|
||||||
|
return RedirectToPage("./ResetPasswordConfirmation");
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await _userManager.ResetPasswordAsync(user, Input.Code, Input.Password);
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
return RedirectToPage("./ResetPasswordConfirmation");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var error in result.Errors)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, error.Description);
|
||||||
|
}
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
@page
|
||||||
|
@model ResetPasswordConfirmationModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Reset password confirmation";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
<p>
|
||||||
|
Your password has been reset. Please <a asp-page="./Login">click here to log in</a>.
|
||||||
|
</p>
|
@ -0,0 +1,25 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[AllowAnonymous]
|
||||||
|
public class ResetPasswordConfirmationModel : PageModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public void OnGet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
AGSS/Areas/Identity/Pages/Account/_StatusMessage.cshtml
Normal file
10
AGSS/Areas/Identity/Pages/Account/_StatusMessage.cshtml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@model string
|
||||||
|
|
||||||
|
@if (!String.IsNullOrEmpty(Model))
|
||||||
|
{
|
||||||
|
var statusMessageClass = Model.StartsWith("Error") ? "danger" : "success";
|
||||||
|
<div class="alert alert-@statusMessageClass alert-dismissible" role="alert">
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
@Model
|
||||||
|
</div>
|
||||||
|
}
|
1
AGSS/Areas/Identity/Pages/Account/_ViewImports.cshtml
Normal file
1
AGSS/Areas/Identity/Pages/Account/_ViewImports.cshtml
Normal file
@ -0,0 +1 @@
|
|||||||
|
@using AGSS.Areas.Identity.Pages.Account
|
23
AGSS/Areas/Identity/Pages/Error.cshtml
Normal file
23
AGSS/Areas/Identity/Pages/Error.cshtml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
@page
|
||||||
|
@model ErrorModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1 class="text-danger">Error.</h1>
|
||||||
|
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||||
|
|
||||||
|
@if (Model.ShowRequestId)
|
||||||
|
{
|
||||||
|
<p>
|
||||||
|
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>Development Mode</h3>
|
||||||
|
<p>
|
||||||
|
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
|
||||||
|
</p>
|
41
AGSS/Areas/Identity/Pages/Error.cshtml.cs
Normal file
41
AGSS/Areas/Identity/Pages/Error.cshtml.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace AGSS.Areas.Identity.Pages
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
|
public class ErrorModel : PageModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public string RequestId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
|
||||||
|
/// directly from your code. This API may change or be removed in future releases.
|
||||||
|
/// </summary>
|
||||||
|
public void OnGet()
|
||||||
|
{
|
||||||
|
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
AGSS/Areas/Identity/Pages/_ViewImports.cshtml
Normal file
5
AGSS/Areas/Identity/Pages/_ViewImports.cshtml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
@using AGSS.Areas.Identity
|
||||||
|
@using AGSS.Areas.Identity.Pages
|
||||||
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
|
@using AGSS.Models.Entities
|
4
AGSS/Areas/Identity/Pages/_ViewStart.cshtml
Normal file
4
AGSS/Areas/Identity/Pages/_ViewStart.cshtml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
@{
|
||||||
|
Layout = "/Pages/Shared/_Layout.cshtml";
|
||||||
|
}
|
45
AGSS/Controllers/User/UserControllers.cs
Normal file
45
AGSS/Controllers/User/UserControllers.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using System.Security.Claims;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using AGSS.Models.Template;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace AGSS.Controllers.User;
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
[Route("api/v1/[controller]")]
|
||||||
|
public class UserControllers:ControllerBase
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly UserService _userService;
|
||||||
|
|
||||||
|
public UserControllers(UserService userService, UserManager<UserModel> userManager)
|
||||||
|
{
|
||||||
|
_userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> My()
|
||||||
|
{
|
||||||
|
string userId = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
|
||||||
|
if (string.IsNullOrEmpty(userId))
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(500,"获取用户失败(JWT解析错误)",null));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var userProfile = await _userService.GetUserProfileAsync(userId);
|
||||||
|
return Ok(new ReturnTemplate(200,"获取成功!",userProfile));
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
return NotFound(ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
14
AGSS/DbSet/UserSet.cs
Normal file
14
AGSS/DbSet/UserSet.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace AGSS.DbSet
|
||||||
|
{
|
||||||
|
public class ApplicationDbContext : IdentityDbContext<UserModel>
|
||||||
|
{
|
||||||
|
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||||
|
: base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
AGSS/Migrations/20250702100149_Initial.Designer.cs
generated
Normal file
53
AGSS/Migrations/20250702100149_Initial.Designer.cs
generated
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using AGSS.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DBContext))]
|
||||||
|
[Migration("20250702100149_Initial")]
|
||||||
|
partial class Initial
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "9.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AGSS.Models.Entities.UserModel", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("AuthId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("UserModels");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
AGSS/Migrations/20250702100149_Initial.cs
Normal file
36
AGSS/Migrations/20250702100149_Initial.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Initial : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "UserModels",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
AuthId = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Email = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Password = table.Column<string>(type: "text", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_UserModels", x => x.Id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "UserModels");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
AGSS/Migrations/20250702110815_usernew.Designer.cs
generated
Normal file
45
AGSS/Migrations/20250702110815_usernew.Designer.cs
generated
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using AGSS.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DBContext))]
|
||||||
|
[Migration("20250702110815_usernew")]
|
||||||
|
partial class usernew
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "9.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AGSS.Models.Entities.UserModel", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("AuthId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("UserModels");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
AGSS/Migrations/20250702110815_usernew.cs
Normal file
40
AGSS/Migrations/20250702110815_usernew.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class usernew : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Email",
|
||||||
|
table: "UserModels");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Password",
|
||||||
|
table: "UserModels");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Email",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Password",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
70
AGSS/Migrations/20250705081221_newuser.Designer.cs
generated
Normal file
70
AGSS/Migrations/20250705081221_newuser.Designer.cs
generated
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using AGSS.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DBContext))]
|
||||||
|
[Migration("20250705081221_newuser")]
|
||||||
|
partial class newuser
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "9.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AGSS.Models.Entities.UserModel", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("AuthId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<string>("Birthday")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.Property<string>("Config")
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)");
|
||||||
|
|
||||||
|
b.Property<string>("JobCode")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<string>("JobName")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<string>("Sex")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("UserModels");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
102
AGSS/Migrations/20250705081221_newuser.cs
Normal file
102
AGSS/Migrations/20250705081221_newuser.cs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class newuser : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "AuthId",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "character varying(50)",
|
||||||
|
maxLength: 50,
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "text");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Birthday",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "character varying(20)",
|
||||||
|
maxLength: 20,
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Config",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "character varying(200)",
|
||||||
|
maxLength: 200,
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Description",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "character varying(100)",
|
||||||
|
maxLength: 100,
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "JobCode",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "character varying(10)",
|
||||||
|
maxLength: 10,
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "JobName",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "character varying(10)",
|
||||||
|
maxLength: 10,
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "Sex",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "character varying(20)",
|
||||||
|
maxLength: 20,
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Birthday",
|
||||||
|
table: "UserModels");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Config",
|
||||||
|
table: "UserModels");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Description",
|
||||||
|
table: "UserModels");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "JobCode",
|
||||||
|
table: "UserModels");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "JobName",
|
||||||
|
table: "UserModels");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Sex",
|
||||||
|
table: "UserModels");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "AuthId",
|
||||||
|
table: "UserModels",
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "character varying(50)",
|
||||||
|
oldMaxLength: 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
300
AGSS/Migrations/20250708111442_user.Designer.cs
generated
Normal file
300
AGSS/Migrations/20250708111442_user.Designer.cs
generated
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using AGSS.DbSet;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20250708111442_user")]
|
||||||
|
partial class user
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "9.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AGSS.Models.Entities.UserModel", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Birthday")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Config")
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("JobCode")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<string>("JobName")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Sex")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
229
AGSS/Migrations/20250708111442_user.cs
Normal file
229
AGSS/Migrations/20250708111442_user.cs
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class user : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetRoles",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
|
NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
|
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUsers",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Sex = table.Column<string>(type: "text", nullable: true),
|
||||||
|
Description = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
||||||
|
Config = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
||||||
|
JobCode = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: true),
|
||||||
|
JobName = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: true),
|
||||||
|
Birthday = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
|
||||||
|
UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
|
NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
|
Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
|
NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||||
|
EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
PasswordHash = table.Column<string>(type: "text", nullable: true),
|
||||||
|
SecurityStamp = table.Column<string>(type: "text", nullable: true),
|
||||||
|
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
|
||||||
|
PhoneNumber = table.Column<string>(type: "text", nullable: true),
|
||||||
|
PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
||||||
|
LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
AccessFailedCount = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetRoleClaims",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
RoleId = table.Column<string>(type: "text", nullable: false),
|
||||||
|
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||||
|
ClaimValue = table.Column<string>(type: "text", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
||||||
|
column: x => x.RoleId,
|
||||||
|
principalTable: "AspNetRoles",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserClaims",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
UserId = table.Column<string>(type: "text", nullable: false),
|
||||||
|
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||||
|
ClaimValue = table.Column<string>(type: "text", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserLogins",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||||
|
ProviderKey = table.Column<string>(type: "text", nullable: false),
|
||||||
|
ProviderDisplayName = table.Column<string>(type: "text", nullable: true),
|
||||||
|
UserId = table.Column<string>(type: "text", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserRoles",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
UserId = table.Column<string>(type: "text", nullable: false),
|
||||||
|
RoleId = table.Column<string>(type: "text", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
||||||
|
column: x => x.RoleId,
|
||||||
|
principalTable: "AspNetRoles",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AspNetUserTokens",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
UserId = table.Column<string>(type: "text", nullable: false),
|
||||||
|
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Name = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Value = table.Column<string>(type: "text", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
||||||
|
column: x => x.UserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetRoleClaims_RoleId",
|
||||||
|
table: "AspNetRoleClaims",
|
||||||
|
column: "RoleId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "RoleNameIndex",
|
||||||
|
table: "AspNetRoles",
|
||||||
|
column: "NormalizedName",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetUserClaims_UserId",
|
||||||
|
table: "AspNetUserClaims",
|
||||||
|
column: "UserId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetUserLogins_UserId",
|
||||||
|
table: "AspNetUserLogins",
|
||||||
|
column: "UserId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AspNetUserRoles_RoleId",
|
||||||
|
table: "AspNetUserRoles",
|
||||||
|
column: "RoleId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "EmailIndex",
|
||||||
|
table: "AspNetUsers",
|
||||||
|
column: "NormalizedEmail");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "UserNameIndex",
|
||||||
|
table: "AspNetUsers",
|
||||||
|
column: "NormalizedUserName",
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetRoleClaims");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserClaims");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserLogins");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserRoles");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUserTokens");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetRoles");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AspNetUsers");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
297
AGSS/Migrations/ApplicationDbContextModelSnapshot.cs
Normal file
297
AGSS/Migrations/ApplicationDbContextModelSnapshot.cs
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using AGSS.DbSet;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "9.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AGSS.Models.Entities.UserModel", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<string>("Birthday")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Config")
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("JobCode")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<string>("JobName")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Sex")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("character varying(256)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
AGSS/Migrations/DBContextModelSnapshot.cs
Normal file
67
AGSS/Migrations/DBContextModelSnapshot.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using AGSS.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AGSS.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DBContext))]
|
||||||
|
partial class DBContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "9.0.6")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AGSS.Models.Entities.UserModel", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("AuthId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)");
|
||||||
|
|
||||||
|
b.Property<string>("Birthday")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.Property<string>("Config")
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)");
|
||||||
|
|
||||||
|
b.Property<string>("JobCode")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<string>("JobName")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)");
|
||||||
|
|
||||||
|
b.Property<string>("Sex")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("UserModels");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
AGSS/Models/DBContext.cs
Normal file
14
AGSS/Models/DBContext.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using AGSS.Models.Entities;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace AGSS.Models;
|
||||||
|
|
||||||
|
public class DBContext : DbContext
|
||||||
|
{
|
||||||
|
public DBContext(DbContextOptions<DBContext> options)
|
||||||
|
: base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
14
AGSS/Models/DTOs/UserProfile.cs
Normal file
14
AGSS/Models/DTOs/UserProfile.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace AGSS.Models;
|
||||||
|
|
||||||
|
public class UserProfile
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string? Sex { get; set; }
|
||||||
|
public string? Description { get; set; }
|
||||||
|
public string? Config { get; set; }
|
||||||
|
public string? JobCode { get; set; }
|
||||||
|
public string? JobName { get; set; }
|
||||||
|
public string? Birthday { get; set; }
|
||||||
|
}
|
133
AGSS/Models/DTOs/UserRequest.cs
Normal file
133
AGSS/Models/DTOs/UserRequest.cs
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace AGSS.Models.DTOs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用于封装用户请求数据的类,主要用于提交或更新用户的个人信息。
|
||||||
|
/// </summary>
|
||||||
|
public class UserRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表示用户的性别。此属性可以为空,最大长度为20个字符。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string? Sex { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户的描述信息,最大长度为100个字符。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 代表用户请求中配置信息的字符串。此字段允许存储长度不超过200个字符的配置数据。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(200)]
|
||||||
|
public string? Config { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 代表用户的职业代码,用于标识用户的职业类别。
|
||||||
|
/// 此属性的值应遵循特定格式或标准,具体取决于应用的需求。
|
||||||
|
/// 最大长度为10个字符。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>此字段在数据传输对象(如UserRequest和UserReturn)以及实体类UserModel中定义,确保了从客户端到服务器的数据一致性。</remarks>
|
||||||
|
[MaxLength(10)]
|
||||||
|
public string? JobCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 代表用户的职业名称。此属性用于存储用户的职业信息,最大长度为10个字符。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>该字段在UserRequest和UserReturn类中定义,并且在数据库实体UserModel中也有对应字段。通过UserInfoController中的NextInfo方法可以更新或创建包含此职业名称在内的用户信息。</remarks>
|
||||||
|
[MaxLength(10)]
|
||||||
|
public string? JobName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户的生日。此属性用于存储用户的出生日期,格式为字符串。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>最大长度为20个字符。在数据传输对象(DTO)和实体模型中使用。</remarks>
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string? Birthday { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示用户返回的数据模型。
|
||||||
|
/// 该类用于封装从服务端返回给客户端的用户信息。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 包含用户的唯一标识符、认证ID以及其他个人信息如性别、描述、配置、工作代码、工作名称、生日等。
|
||||||
|
/// 此外,还提供了用户的电子邮件、昵称和真实姓名。
|
||||||
|
/// </remarks>
|
||||||
|
public class UserReturn
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表示用户的唯一标识符。
|
||||||
|
/// </summary>
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用于标识用户的认证ID,最大长度为50个字符,是必需的字段。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(50)]
|
||||||
|
public required string AuthId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示用户的性别。此属性可以为空,最大长度为20个字符。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string? Sex { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户描述信息,最大长度为100个字符。
|
||||||
|
/// 该属性用于存储关于用户的简短描述或备注信息。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置信息,用于存储与用户相关的自定义配置数据。该属性支持最大长度为200个字符的字符串。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(200)]
|
||||||
|
public string? Config { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示用户的职位代码。该字段的最大长度为10个字符。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(10)]
|
||||||
|
public string? JobCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示用户的职位名称。该属性的值长度不能超过10个字符。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(10)]
|
||||||
|
public string? JobName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示用户的生日信息。此属性用于存储用户出生日期的字符串表示形式,最大长度为20个字符。
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string? Birthday { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 电子邮件地址,用于联系用户或作为账户标识。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>该属性应包含有效的电子邮件格式。</remarks>
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置用户的昵称。该属性用于存储用户在系统中的个性化名称,方便用户识别。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 该字段的长度应控制在合理范围内以确保数据的有效性和安全性。
|
||||||
|
/// </remarks>
|
||||||
|
public string NickName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示用户的名称。这是用户在系统中的主要标识符之一,用于显示和识别用户。
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 该属性值应为字符串类型,通常用于存储用户的全名或昵称。
|
||||||
|
/// </remarks>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
}
|
21
AGSS/Models/Entities/User.cs
Normal file
21
AGSS/Models/Entities/User.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
|
||||||
|
namespace AGSS.Models.Entities;
|
||||||
|
|
||||||
|
public class UserModel:IdentityUser
|
||||||
|
{
|
||||||
|
|
||||||
|
public string? Sex { get; set; }
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string? Description { get; set; }
|
||||||
|
[MaxLength(200)]
|
||||||
|
public string? Config { get; set; }
|
||||||
|
[MaxLength(10)]
|
||||||
|
public string? JobCode { get; set; }
|
||||||
|
[MaxLength(10)]
|
||||||
|
public string? JobName { get; set; }
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string? Birthday { get; set; }
|
||||||
|
|
||||||
|
}
|
3
AGSS/Models/Template/ReturnTemplate.cs
Normal file
3
AGSS/Models/Template/ReturnTemplate.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace AGSS.Models.Template;
|
||||||
|
|
||||||
|
public record ReturnTemplate(int Code, string Msg, object Data);
|
94
AGSS/Pages/Shared/_Layout.cshtml
Normal file
94
AGSS/Pages/Shared/_Layout.cshtml
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
@using Microsoft.AspNetCore.Hosting
|
||||||
|
@using Microsoft.AspNetCore.Mvc.ViewEngines
|
||||||
|
@inject IWebHostEnvironment Environment
|
||||||
|
@inject ICompositeViewEngine Engine
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>@ViewData["Title"] - AGSS</title>
|
||||||
|
|
||||||
|
<environment include="Development">
|
||||||
|
<link rel="stylesheet" href="~/Identity/lib/bootstrap/dist/css/bootstrap.css" />
|
||||||
|
<link rel="stylesheet" href="~/Identity/css/site.css" />
|
||||||
|
</environment>
|
||||||
|
<environment exclude="Development">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous"
|
||||||
|
asp-fallback-href="~/Identity/lib/bootstrap/dist/css/bootstrap.min.css"
|
||||||
|
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
|
||||||
|
<link rel="stylesheet" href="~/Identity/css/site.css" asp-append-version="true" />
|
||||||
|
</environment>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="~/">AGSS</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||||
|
aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
|
||||||
|
@{
|
||||||
|
var result = Engine.FindView(ViewContext, "_LoginPartial", isMainPage: false);
|
||||||
|
}
|
||||||
|
@if (result.Success)
|
||||||
|
{
|
||||||
|
await Html.RenderPartialAsync("_LoginPartial");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The default Identity UI layout requires a partial view '_LoginPartial' " +
|
||||||
|
"usually located at '/Pages/_LoginPartial' or at '/Views/Shared/_LoginPartial' to work. Based on your configuration " +
|
||||||
|
$"we have looked at it in the following locations: {System.Environment.NewLine}{string.Join(System.Environment.NewLine, result.SearchedLocations)}.");
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<partial name="_CookieConsentPartial" optional />
|
||||||
|
<main role="main" class="pb-1">
|
||||||
|
@RenderBody()
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<footer class="footer border-top pl-3 text-muted">
|
||||||
|
<div class="container">
|
||||||
|
© 2025 - AGSS
|
||||||
|
@{
|
||||||
|
var foundPrivacy = Url.Page("/Privacy", new { area = "" });
|
||||||
|
}
|
||||||
|
@if (foundPrivacy != null)
|
||||||
|
{
|
||||||
|
<a asp-area="" asp-page="/Privacy">Privacy</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<environment include="Development">
|
||||||
|
<script src="~/Identity/lib/jquery/dist/jquery.js"></script>
|
||||||
|
<script src="~/Identity/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
|
||||||
|
<script src="~/Identity/js/site.js" asp-append-version="true"></script>
|
||||||
|
</environment>
|
||||||
|
<environment exclude="Development">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"
|
||||||
|
asp-fallback-src="~/Identity/lib/jquery/dist/jquery.min.js"
|
||||||
|
asp-fallback-test="window.jQuery"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
integrity="sha384-ZvpUoO/+PpLXR1lu4jmpXWu80pZlYUAfxl5NsBMWOEPSjUn/6Z/hRTt8+pR6L4N2">
|
||||||
|
</script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js"
|
||||||
|
asp-fallback-src="~/Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js"
|
||||||
|
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj">
|
||||||
|
</script>
|
||||||
|
<script src="~/Identity/js/site.js" asp-append-version="true"></script>
|
||||||
|
</environment>
|
||||||
|
|
||||||
|
@await RenderSectionAsync("Scripts", required: false)
|
||||||
|
</body>
|
||||||
|
</html>
|
28
AGSS/Pages/Shared/_LoginPartial.cshtml
Normal file
28
AGSS/Pages/Shared/_LoginPartial.cshtml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
@using AGSS.Models.Entities
|
||||||
|
|
||||||
|
@inject SignInManager<UserModel> SignInManager
|
||||||
|
@inject UserManager<UserModel> UserManager
|
||||||
|
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
@if (SignInManager.IsSignedIn(User))
|
||||||
|
{
|
||||||
|
<li class="nav-item">
|
||||||
|
<a id="manage" class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<form id="logoutForm" class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
|
||||||
|
<button id="logout" type="submit" class="nav-link btn btn-link text-dark border-0">Logout</button>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-dark" id="register" asp-area="Identity" asp-page="/Account/Register">Register</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-dark" id="login" asp-area="Identity" asp-page="/Account/Login">Login</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
2
AGSS/Pages/Shared/_ValidationScriptsPartial.cshtml
Normal file
2
AGSS/Pages/Shared/_ValidationScriptsPartial.cshtml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
|
||||||
|
<script src="~/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
|
6
AGSS/Pages/_ViewImports.cshtml
Normal file
6
AGSS/Pages/_ViewImports.cshtml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
@using AGSS.Areas.Identity
|
||||||
|
|
||||||
|
|
||||||
|
AGSS.Pages
|
||||||
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user