IP-based registration implemented

main
Inga 🏳‍🌈 15 years ago
parent 18864be239
commit 0eaeaea909
  1. 2
      Builder/IISMainHandler/build.txt
  2. 1
      Common/Common.csproj
  3. 1
      Common/TableManager.cs
  4. 8
      Common/dataobjects/Account.cs
  5. 3
      Core/Core.csproj
  6. 12
      Core/Network/IPv4.cs
  7. 52
      Core/Network/IPv4Address.cs
  8. 29
      Core/Network/IPv4Subnet.cs
  9. 2
      IISMainHandler/HandlersFactory.cs
  10. 1
      IISMainHandler/IISMainHandler.csproj
  11. 6
      IISMainHandler/WebContext.cs
  12. 23
      IISMainHandler/handlers/request/RegisterHandler.cs
  13. 5
      IISMainHandler/handlers/response/LoginHandler.cs
  14. 3
      IISMainHandler/handlers/response/RobotsHandler.cs
  15. 64
      templates/Full/Login.xslt

@ -90,6 +90,7 @@
<Compile Include="dataobjects\Invite.cs" />
<Compile Include="dataobjects\IUserSettings.cs" />
<Compile Include="dataobjects\AnonymousUserSettings.cs" />
<Compile Include="dataobjects\LocalNetwork.cs" />
<Compile Include="dataobjects\PMConversation.cs" />
<Compile Include="dataobjects\PMMessage.cs" />
<Compile Include="dataobjects\Poll.cs" />

@ -14,6 +14,7 @@ namespace FLocal.Common {
dataobjects.Board.TableSpec.instance,
dataobjects.Category.TableSpec.instance,
dataobjects.Invite.TableSpec.instance,
dataobjects.LocalNetwork.TableSpec.instance,
dataobjects.PMConversation.TableSpec.instance,
dataobjects.PMMessage.TableSpec.instance,
dataobjects.Poll.TableSpec.instance,

@ -265,5 +265,13 @@ namespace FLocal.Common.dataobjects {
return account;
}
public static Account createAccount(string name, string password, string ip, string registrationEmail) {
var rawChanges = Account.getNewAccountChanges(name, password, ip, registrationEmail);
var accountInsert = rawChanges.Key;
var changes = rawChanges.Value;
ChangeSetUtil.ApplyChanges(changes);
return Account.LoadById(accountInsert.getId().Value);
}
}
}

@ -78,6 +78,9 @@
<Compile Include="extensions\Extensions.cs" />
<Compile Include="extensions\String.cs" />
<Compile Include="IDataObject.cs" />
<Compile Include="Network\IPv4.cs" />
<Compile Include="Network\IPv4Subnet.cs" />
<Compile Include="Network\IPv4Address.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Registry.cs" />
<Compile Include="RegistryCleaner.cs" />

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Core.Network {
class IPv4 {
public const ulong UNIT = 256;
}
}

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Core.Network {
public class IPv4Address {
private const ulong MAX = IPv4.UNIT * IPv4.UNIT * IPv4.UNIT * IPv4.UNIT;
private readonly ulong raw;
public IPv4Address(string ip) {
string[] parts = ip.Split('.');
if(parts.Length != 4) throw new ApplicationException("Malformed ip '" + ip + "'");
ulong result = 0;
for(int i=0; i<parts.Length; i++) {
ulong part = ulong.Parse(parts[i]);
if(part >= IPv4.UNIT) throw new ApplicationException("Malformed ip '" + ip + "'");
result = (result*IPv4.UNIT) + part;
}
this.raw = result;
}
public IPv4Address(ulong raw) {
if(raw >= MAX) throw new ApplicationException("Wrong raw representation " + raw);
this.raw = raw;
}
public override string ToString() {
string[] parts = new string[4];
ulong temp = this.raw;
for(int i=3; i>=0; i--) {
ulong part = temp % IPv4.UNIT;
parts[i] = part.ToString();
temp = (temp - part) / IPv4.UNIT;
}
return String.Join(".", parts);
}
public IEnumerable<IPv4Subnet> matchingSubnets {
get {
ulong divisor = 1;
for(int i=32; i>=0; i--) {
yield return new IPv4Subnet(new IPv4Address(this.raw - (this.raw % divisor)), (byte)i);
divisor *= 2;
}
}
}
}
}

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Core.Network {
public class IPv4Subnet {
private readonly IPv4Address prefix;
private readonly byte length;
public IPv4Subnet(IPv4Address prefix, byte length) {
if(length > 32) throw new CriticalException("Wrong length " + length);
this.prefix = prefix;
this.length = length;
}
public static IPv4Subnet FromString(string subnet) {
string[] parts = subnet.Split('/');
if(parts.Length != 2) throw new ApplicationException("Malformed subnet '" + subnet + "'");
return new IPv4Subnet(new IPv4Address(parts[0]), byte.Parse(parts[1]));
}
public override string ToString() {
return this.prefix.ToString() + "/" + this.length;
}
}
}

@ -167,6 +167,8 @@ namespace FLocal.IISHandler {
return new handlers.request.LogoutHandler();
case "migrateaccount":
return new handlers.request.MigrateAccountHandler();
case "register":
return new handlers.request.RegisterHandler();
case "registerbyinvite":
return new handlers.request.RegisterByInviteHandler();
case "edit":

@ -72,6 +72,7 @@
<Compile Include="handlers\request\MarkThreadAsReadHandler.cs" />
<Compile Include="handlers\request\MigrateAccountHandler.cs" />
<Compile Include="handlers\request\RegisterByInviteHandler.cs" />
<Compile Include="handlers\request\RegisterHandler.cs" />
<Compile Include="handlers\request\ReturnPostHandler.cs" />
<Compile Include="handlers\request\ReplyHandler.cs" />
<Compile Include="handlers\request\SendPMHandler.cs" />

@ -144,5 +144,11 @@ namespace FLocal.IISHandler {
return result;
}
public Core.Network.IPv4Address remoteHost {
get {
return new Core.Network.IPv4Address(this.httprequest.UserHostAddress);
}
}
}
}

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using FLocal.Common.dataobjects;
using FLocal.Importer;
using System.Text.RegularExpressions;
using FLocal.Core;
using FLocal.Common;
using FLocal.Common.actions;
namespace FLocal.IISHandler.handlers.request {
class RegisterHandler : AbstractNewAccountHandler {
protected override Account DoCreateAccount(WebContext context) {
if(!LocalNetwork.IsLocalNetwork(context.remoteHost)) throw new FLocalException("IP '" + context.remoteHost.ToString() + "' is not allowed");
if(context.httprequest.Form["password"] != context.httprequest.Form["password2"]) throw new FLocalException("Passwords mismatch");
return Account.createAccount(context.httprequest.Form["login"], context.httprequest.Form["password"], context.httprequest.UserHostAddress, context.httprequest.Form["registrationEmail"]);
}
}
}

@ -17,7 +17,10 @@ namespace FLocal.IISHandler.handlers.response {
}
protected override IEnumerable<XElement> getSpecificData(WebContext context) {
return new XElement[0];
return new XElement[] {
new XElement("isLocalNetwork", LocalNetwork.IsLocalNetwork(context.remoteHost).ToPlainString()),
new XElement("ip", context.remoteHost.ToString()),
};
}
}

@ -17,6 +17,9 @@ namespace FLocal.IISHandler.handlers.response {
context.httpresponse.ContentType = "text/plain";
context.httpresponse.WriteLine("User-agent: *");
context.httpresponse.WriteLine("Disallow: /");
foreach(var subnet in context.remoteHost.matchingSubnets) {
context.httpresponse.WriteLine(subnet.ToString());
}
}
}

@ -62,6 +62,70 @@
</td>
</tr>
</table>
<br/>
<table width="95%" align="center" cellpadding="1" cellspacing="1" class="tablesurround">
<tr>
<td>
<table cellpadding="3" cellspacing="1" width="100%" class="tableborders">
<tr>
<td class="tdheader">
<xsl:text>Ðåãèñòðàöèÿ</xsl:text>
</td>
</tr>
<tr class="darktable">
<td>
<xsl:choose>
<xsl:when test="isLocalNetwork='false'">
<xsl:text>Âàø IP </xsl:text>
<xsl:value-of select="ip"/>
<xsl:text> íå âõîäèò â ñïèñîê ðàçðåø¸ííûõ ïîäñåòåé.</xsl:text>
<br/>
<xsl:text>Åñëè âû ñ÷èòàåòå, ÷òî ýòî îøèáêà, ñîîáùèòå àäìèíèñòðàòîðó ñâîé IP-àäðåñ è îïèñàíèå ñåòè (îáùåæèòèå/ó÷åáíûé êîðïóñ, óíèâåðñèòåò è ïðî÷åå).</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Âàø IP </xsl:text>
<xsl:value-of select="ip"/>
<xsl:text> âõîäèò â ñïèñîê ðàçðåø¸ííûõ ïîäñåòåé.</xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
<xsl:if test="isLocalNetwork='true'">
<tr>
<td class="lighttable">
<form method="post" action="/do/Register/">
<xsl:text>Èìÿ ïîëüçîâàòåëÿ</xsl:text><br/>
<input type="text" name="login" class="formboxes" maxlength="16"/><br/>
<xsl:text>Íîâûé ïàðîëü</xsl:text><br />
<input type="password" name="password" class="formboxes" /><br/>
<xsl:text>Ïîâòîðèòå ïàðîëü</xsl:text><br/>
<input type="password" name="password2" class="formboxes" /><br/>
<xsl:text>e-mail äëÿ âîññòàíîâëåíèÿ ïàðîëÿ (íåîáÿçàòåëüíî)</xsl:text><br/>
<input type="text" name="registrationEmail" class="formboxes" />
<br/>
<input type="checkbox" name="constitution" value="constitution" id="constitution"/>
<label for="constitution"> Äà, ÿ ñîãëàñåí/ñîãëàñíà/ñîãëàñíî ñ òåì, ÷òî íà ýòîì ôîðóìå äåéñòâóåò </label>
<a href="/q/constitution/" style="text-decoration:underline">îïèñàííàÿ ïî ýòîé ññûëêå êîíñòèòóöèÿ</a>
<xsl:text>.</xsl:text>
<i> (îáÿçàòåëüíî)</i>
<br/>
<input type="checkbox" name="showPostsToAll" value="showPostsToAll" id="showPostsToAll"/>
<label for="showPostsToAll"> Äà, ÿ ñîãëàñåí/ñîãëàñíà/ñîãëàñíî ñ òåì, ÷òîáû ìîè ñîîáùåíèÿ, ðàçìåù¸ííûå íà ýòîì ôîðóìå, áûëè äîñòóïíû ïóáëè÷íî.</label>
<i> (îáÿçàòåëüíî)</i>
<br/>
<input type="checkbox" name="law" value="law" id="law"/>
<label for="law"> Äà, ÿ îáÿçóþñü ñîáëþäàòü çàêîíû Ðîññèéñêîé Ôåäåðàöèè è Ôåäåðàòèâíîé Ðåñïóáëèêè Ãåðìàíèÿ â îáùåíèè íà ýòîì ôîðóìå.</label>
<i> (îáÿçàòåëüíî)</i>
<br/>
<input type="submit" name="buttlogin" value="Çàðåãèñòðèðîâàòüñÿ!" class="buttons" />
</form>
</td>
</tr>
</xsl:if>
</table>
</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
Loading…
Cancel
Save