-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: json session store #29
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,26 @@ | ||
using System; | ||
|
||
namespace TgSharp.Core | ||
{ | ||
internal class DataCenter | ||
public class DataCenter | ||
{ | ||
internal DataCenter (int? dcId, string address, int port) | ||
private const string defaultConnectionAddress = "149.154.175.100";//"149.154.167.50"; | ||
private const int defaultConnectionPort = 443; | ||
|
||
[Obsolete("Do not use, this ctor is public only for serialization")] | ||
public DataCenter() | ||
{ | ||
DataCenterId = dcId; | ||
Address = address; | ||
Port = port; | ||
} | ||
|
||
internal DataCenter (string address, int port) : this (null, address, port) | ||
internal DataCenter (int? dcId, string address = defaultConnectionAddress, int port = defaultConnectionPort) | ||
{ | ||
DataCenterId = dcId; | ||
Address = address; | ||
Port = port; | ||
} | ||
|
||
internal int? DataCenterId { get; } | ||
internal string Address { get; } | ||
internal int Port { get; } | ||
public int? DataCenterId { get; set; } | ||
public string Address { get; set; } | ||
public int Port { get; set; } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
using System; | ||
using System.IO; | ||
|
||
using Newtonsoft.Json; | ||
using TgSharp.TL; | ||
using TgSharp.Core.MTProto; | ||
using TgSharp.Core.MTProto.Crypto; | ||
|
@@ -13,11 +13,16 @@ public interface ISessionStore | |
Session Load(string sessionUserId); | ||
} | ||
|
||
public class FileSessionStore : ISessionStore | ||
[Obsolete("Use JsonFileSessionStore")] | ||
public class FileSessionStore : BinaryFileSessionStore | ||
{ | ||
} | ||
|
||
public class BinaryFileSessionStore : ISessionStore | ||
{ | ||
private readonly DirectoryInfo basePath; | ||
|
||
public FileSessionStore(DirectoryInfo basePath = null) | ||
public BinaryFileSessionStore(DirectoryInfo basePath = null) | ||
{ | ||
if (basePath != null && !basePath.Exists) | ||
{ | ||
|
@@ -58,6 +63,52 @@ public Session Load(string sessionUserId) | |
} | ||
} | ||
|
||
public class JsonFileSessionStore : ISessionStore | ||
{ | ||
private readonly DirectoryInfo basePath; | ||
private readonly JsonSerializerSettings jsonSerializerSettings; | ||
|
||
internal static JsonFileSessionStore DefaultSessionStore () | ||
{ | ||
return new JsonFileSessionStore (null, new JsonSerializerSettings () { | ||
Formatting = Formatting.Indented | ||
}); | ||
} | ||
|
||
public JsonFileSessionStore(DirectoryInfo basePath = null, JsonSerializerSettings jsonSerializerSettings = null) | ||
{ | ||
if (basePath != null && !basePath.Exists) | ||
{ | ||
throw new ArgumentException("basePath doesn't exist", nameof(basePath)); | ||
} | ||
|
||
this.basePath = basePath; | ||
this.jsonSerializerSettings = jsonSerializerSettings; | ||
} | ||
|
||
public void Save(Session session) | ||
{ | ||
File.WriteAllText(GetSessionPath(session.SessionUserId), JsonConvert.SerializeObject(session, jsonSerializerSettings)); | ||
} | ||
|
||
public Session Load(string sessionUserId) | ||
{ | ||
string sessionPath = GetSessionPath(sessionUserId); | ||
|
||
if (File.Exists(sessionPath)) | ||
{ | ||
return JsonConvert.DeserializeObject<Session> (File.ReadAllText (sessionPath), jsonSerializerSettings); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
private string GetSessionPath(string sessionUserId) | ||
{ | ||
return Path.Combine(basePath?.FullName ?? string.Empty, sessionUserId + ".json"); | ||
} | ||
} | ||
|
||
public class FakeSessionStore : ISessionStore | ||
{ | ||
public void Save(Session session) | ||
|
@@ -71,11 +122,32 @@ public Session Load(string sessionUserId) | |
} | ||
} | ||
|
||
public class Session | ||
internal static class SessionFactory | ||
{ | ||
private const string defaultConnectionAddress = "149.154.175.100";//"149.154.167.50"; | ||
private const int defaultConnectionPort = 443; | ||
internal static Session TryLoadOrCreateNew (ISessionStore store, string sessionUserId) | ||
{ | ||
var session = store.Load (sessionUserId); | ||
if (null == session) { | ||
var defaultDataCenter = new DataCenter (null); | ||
session = new Session { | ||
Id = GenerateRandomUlong (), | ||
SessionUserId = sessionUserId, | ||
DataCenter = defaultDataCenter, | ||
}; | ||
} | ||
return session; | ||
} | ||
|
||
private static ulong GenerateRandomUlong () | ||
{ | ||
var random = new Random (); | ||
ulong rand = (((ulong)random.Next ()) << 32) | ((ulong)random.Next ()); | ||
return rand; | ||
} | ||
} | ||
|
||
public class Session | ||
{ | ||
public int Sequence { get; set; } | ||
#if CI | ||
// see the same CI-wrapped assignment in .FromBytes(), but this one will become useful | ||
|
@@ -90,23 +162,30 @@ private static int CurrentTime () | |
#endif | ||
|
||
public string SessionUserId { get; set; } | ||
internal DataCenter DataCenter { get; set; } | ||
public DataCenter DataCenter { get; set; } | ||
public AuthKey AuthKey { get; set; } | ||
public ulong Id { get; set; } | ||
public ulong Salt { get; set; } | ||
public int TimeOffset { get; set; } | ||
public long LastMessageId { get; set; } | ||
public int SessionExpires { get; set; } | ||
public TLUser TLUser { get; set; } | ||
private Random random; | ||
|
||
private ISessionStore store; | ||
|
||
public Session(ISessionStore store) | ||
{ | ||
random = new Random(); | ||
this.store = store; | ||
public int UserId { get; set; } | ||
private TLUser user = null; | ||
public TLUser User { | ||
get { return user; } | ||
internal set { | ||
user = value; | ||
if (value != null) { | ||
UserId = value.Id; | ||
} | ||
} | ||
} | ||
public bool AuthenticatedSuccessfully { | ||
get { return UserId != default; } | ||
} | ||
|
||
private readonly Random random = new Random(); | ||
|
||
public byte[] ToBytes() | ||
{ | ||
|
@@ -121,11 +200,11 @@ public byte[] ToBytes() | |
Serializers.String.Write(writer, DataCenter.Address); | ||
writer.Write(DataCenter.Port); | ||
|
||
if (TLUser != null) | ||
if (AuthenticatedSuccessfully) | ||
{ | ||
writer.Write(1); | ||
writer.Write(SessionExpires); | ||
ObjectUtils.SerializeObject(TLUser, writer); | ||
ObjectUtils.SerializeObject (UserId, writer); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. writer.write(UserId); |
||
} | ||
else | ||
{ | ||
|
@@ -160,17 +239,17 @@ public static Session FromBytes(byte[] buffer, ISessionStore store, string sessi | |
|
||
var isAuthExsist = reader.ReadInt32() == 1; | ||
int sessionExpires = 0; | ||
TLUser TLUser = null; | ||
int userId = default; | ||
if (isAuthExsist) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol that typo is not in my commit :P |
||
{ | ||
sessionExpires = reader.ReadInt32(); | ||
TLUser = (TLUser)ObjectUtils.DeserializeObject(reader); | ||
userId = (int)ObjectUtils.DeserializeObject (reader); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. userId = reader.ReadInt32(); |
||
} | ||
|
||
var authData = Serializers.Bytes.Read(reader); | ||
var defaultDataCenter = new DataCenter (serverAddress, port); | ||
var defaultDataCenter = new DataCenter (null, serverAddress, port); | ||
|
||
return new Session(store) | ||
return new Session() | ||
{ | ||
AuthKey = new AuthKey(authData), | ||
Id = id, | ||
|
@@ -179,37 +258,13 @@ public static Session FromBytes(byte[] buffer, ISessionStore store, string sessi | |
LastMessageId = lastMessageId, | ||
TimeOffset = timeOffset, | ||
SessionExpires = sessionExpires, | ||
TLUser = TLUser, | ||
UserId = userId, | ||
SessionUserId = sessionUserId, | ||
DataCenter = defaultDataCenter, | ||
}; | ||
} | ||
} | ||
|
||
public void Save() | ||
{ | ||
store.Save(this); | ||
} | ||
|
||
public static Session TryLoadOrCreateNew(ISessionStore store, string sessionUserId) | ||
{ | ||
var defaultDataCenter = new DataCenter (defaultConnectionAddress, defaultConnectionPort); | ||
|
||
return store.Load(sessionUserId) ?? new Session(store) | ||
{ | ||
Id = GenerateRandomUlong(), | ||
SessionUserId = sessionUserId, | ||
DataCenter = defaultDataCenter, | ||
}; | ||
} | ||
|
||
private static ulong GenerateRandomUlong() | ||
{ | ||
var random = new Random(); | ||
ulong rand = (((ulong)random.Next()) << 32) | ((ulong)random.Next()); | ||
return rand; | ||
} | ||
|
||
public long GetNewMessageId() | ||
{ | ||
long time = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically we don't have to save UserId at all because we can just run GetSelfUser and If we're not authenticated we get an error