- Fix TOTP challenge answer problem.

- Add `GetTermsOfService` method to `SocialvoidClient` class.
- Add `IChallenge` interface to `Socialvoid.Security` namespace.
- Add `Socialvoid.SvObjects` namespace and its classes: `HelpDocument`, `ListW` and `Peer` class.
- Add `Socialvoid.SvObjects.Media` namespace and its classes: `DisplayPictureSize` and `Document`.
- Add code test for registering a user in `Tests/Client/AuthenticateUser.cs` file.

Signed-off-by: Aliwoto <aminnimaj@gmail.com>
This commit is contained in:
Aliwoto 2021-10-05 23:02:11 +00:00
parent e39a7a7042
commit b090408334
No known key found for this signature in database
GPG Key ID: 646B4FE4205EC48C
19 changed files with 1373 additions and 77 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"restructuredtext.syntaxHighlighting.disabled": true
}

View File

@ -17,12 +17,13 @@
*/
using System;
using System.Text;
using System.Net.Http;
using System.IO;
using System.Web;
using System.Net.Http;
using Socialvoid.JObjects;
using Socialvoid.Security;
using Socialvoid.Security.Otp;
using Socialvoid.JObjects;
using Socialvoid.SvObjects;
using Socialvoid.Errors.ServerErrors;
using Socialvoid.Errors.AuthenticationErrors;
using Socialvoid.Errors.ValidationErrors;
@ -54,6 +55,16 @@ namespace Socialvoid.Client
/// </summary>
protected const string PasswordKey = "password";
/// <summary>
/// the first name key in jsonrpc request params.
/// <code> since: v0.0.0 </code>
/// </summary>
protected const string FirstNameKey = "first_name";
/// <summary>
/// the last name key in jsonrpc request params.
/// <code> since: v0.0.0 </code>
/// </summary>
protected const string LastNameKey = "last_name";
/// <summary>
/// the otp key in jsonrpc request params.
/// <code> since: v0.0.0 </code>
/// </summary>
@ -84,6 +95,21 @@ namespace Socialvoid.Client
/// </summary>
protected const string VersionKey = "version";
/// <summary>
/// the ToS key in jsonrpc request params.
/// <code> since: v0.0.0 </code>
/// </summary>
protected const string ToSKey = "terms_of_service_id";
/// <summary>
/// the ToS key in jsonrpc request params.
/// <code> since: v0.0.0 </code>
/// </summary>
protected const string ToSAgreeKey = "terms_of_service_agree";
/// <summary>
/// <c>authenticate_user</c> method value.
/// <code> since: v0.0.0 </code>
/// </summary>
protected const string SessionIDKey = "session_identification";
/// <summary>
/// <c>authenticate_user</c> method value.
/// <code> since: v0.0.0 </code>
/// </summary>
@ -97,7 +123,12 @@ namespace Socialvoid.Client
/// <c>authenticate_user</c> method value.
/// <code> since: v0.0.0 </code>
/// </summary>
protected const string SessionIDKey = "session_identification";
protected const string RegisterMethod = "session.register";
/// <summary>
/// <c>get_terms_of_service</c> method value.
/// <code> since: v0.0.0 </code>
/// </summary>
protected const string GetToSMethod = "help.get_terms_of_service";
#endregion
//-------------------------------------------------
#region static Properties Region
@ -109,32 +140,55 @@ namespace Socialvoid.Client
/// The public hash of the client.
/// <code> since: v0.0.0 </code>
/// </summary>
public string PublicHash { get; protected set; }
public virtual string PublicHash { get; protected set; }
/// <summary>
/// The private hash of the client.
/// <code> since: v0.0.0 </code>
/// </summary>
public string PrivateHash { get; protected set; }
public virtual string PrivateHash { get; protected set; }
/// <summary>
/// The platform of the client.
/// <code> since: v0.0.0 </code>
/// </summary>
public string Platform { get; protected set; }
public virtual string Platform { get; protected set; }
/// <summary>
/// The name of the client.
/// <code> since: v0.0.0 </code>
/// </summary>
public string ClientName { get; protected set; }
public virtual string ClientName { get; protected set; }
/// <summary>
/// The version of the client.
/// <code> since: v0.0.0 </code>
/// </summary>
public string Version { get; protected set; }
public virtual string Version { get; protected set; }
/// <summary>
///
/// The HTTP client of this <see cref="SocialvoidClient"/>.
/// <code> since: v0.0.0 </code>
/// </summary>
public HttpClient HttpClient { get; protected set; }
public virtual HttpClient HttpClient { get; protected set; }
/// <summary>
/// Representing the automation of establishing a session when
/// <see cref="HasSession"/> is <c>false</c>.
/// If <c>true</c>, the session will be established automatically
/// when <see cref="HasSession"/> is <c>false</c>.
/// If <c>false</c>, you need to establish the session by calling
/// <see cref="CreateSession"/> method.
/// <code> since: v0.0.0 </code>
/// </summary>
public virtual bool AutoSession { get; set; }
/// <summary>
/// the stored <see cref="Peer"/> value in the client.
/// <code> since: v0.0.0 </code>
/// </summary>
public virtual Peer AuthorizedPeer { get; protected set; }
/// <summary>
/// Represents whether the client has a session or not.
/// <code> since: v0.0.0 </code>
/// </summary>
/// <value>
/// <c>true</c> if has session; otherwise, <c>false</c>.
/// </value>
public virtual bool HasSession => _session != null;
#endregion
//-------------------------------------------------
#region static field's Region
@ -165,6 +219,11 @@ namespace Socialvoid.Client
/// </summary>
protected string _otp_answer;
/// <summary>
/// the terms of service received from the socialvoid's server.
/// <code> since: v0.0.0 </code>
/// </summary>
protected HelpDocument _termsOfService;
/// <summary>
/// <code> since: v0.0.0 </code>
/// </summary>
protected readonly MType _contentTypeValue = MType.Parse(ContentType);
@ -208,8 +267,6 @@ namespace Socialvoid.Client
Version = version;
HttpClient = new();
}
#endregion
//-------------------------------------------------
#region Destructor's Region
@ -233,7 +290,6 @@ namespace Socialvoid.Client
#endregion
//-------------------------------------------------
#region ordinary Method's Region
/// <summary>
/// CreateSession method (session.create), establishes a new session
/// to the network.
@ -243,6 +299,11 @@ namespace Socialvoid.Client
/// is reset whenever the session is used in one way or another.
/// <code> since: v0.0.0 </code>
/// </summary>
/// <param name="store">
/// if <c>true</c>, the session will be stored in the client;
/// otherwise, the session will only be returned, so it's up to
/// users whether to store the session or not.
/// </param>
/// <exception cref="InternalServerErrorException">
/// Thrown if the server encounters an internal error.
/// </exception>
@ -261,7 +322,7 @@ namespace Socialvoid.Client
/// <exception cref="InvalidVersionException">
/// Thrown if the parameter passed as version is not valid.
/// </exception>
public virtual SessionEstablished CreateSession()
public virtual SessionEstablished CreateSession(bool store = true)
{
JArgs args = new(){
{PublicHashKey, PublicHash},
@ -271,25 +332,16 @@ namespace Socialvoid.Client
{VersionKey, Version},
};
var request = GetRpcRequest(CreateSessionMethod, args);
var jresp = ParseContent<SessionEstablished>(
GetMessage(CreateSessionMethod, args));
var message = new HttpRequestMessage(HttpMethod.Post, _endpoint);
message.Content = SerializeContent(request);
message.Content.Headers.ContentType = _contentTypeValue;
var jresp = ParseContent<SessionEstablished>(message);
if (!string.IsNullOrEmpty(jresp.Result.ChallengeSecret))
if (store)
{
_should_otp = true;
_otp_answer = GetChallengeAnswer(jresp.Result.ChallengeSecret);
// set challenege secret to null to avoid sending it again.
// this will avoid future conflicts in using old challenge secret.
jresp.Result.ChallengeSecret = null;
_session = jresp.Result;
return _session;
}
_session = jresp.Result;
return _session;
return jresp.Result;
}
/// <summary>
/// AuthenticateUser method (session.authenticate_user),
@ -346,8 +398,17 @@ namespace Socialvoid.Client
public virtual void AuthenticateUser(string username, string password,
string otp = null, SessionIdentification sessionID = null)
{
if (sessionID == null && _session != null)
if (sessionID == null)
{
if (_session == null)
{
if (!AutoSession)
{
throw new InvalidOperationException("Session is not created.");
}
_session = CreateSession();
}
sessionID = new()
{
SessionID = _session.SessionID,
@ -365,10 +426,9 @@ namespace Socialvoid.Client
// if yes, ignore _otp field and use user's specified otp value.
// otherwise check for _should_otp and see if we should send an
// otp answer or not.
if (IsOtpValid(otp))
if (!string.IsNullOrWhiteSpace(otp))
{
args.Add(OtpKey, otp);
//sessionID.ChallengeAnswer = otp;
}
if (_should_otp && IsOtpValid(_otp_answer))
@ -391,17 +451,148 @@ namespace Socialvoid.Client
Console.WriteLine(contentStr);
}
/// <summary>
/// CreateSession method (session.create), establishes a new session
/// to the network.
/// Please do notice that new and unauthenticated sessions
/// expires after 10 minutes of inactivity, authenticating to the session
/// will increase the expiration time to 72 hours of inactivity. This timer
/// is reset whenever the session is used in one way or another.
/// <code> since: v0.0.0 </code>
/// </summary>
/// <param name="username">
/// The username of the user to become registered.
/// </param>
/// <param name="password">
/// the password used to register the user.
/// </param>
/// <param name="tosID">
/// The Terms of Service ID.
/// </param>
/// <param name="firstName">
/// The first name of the user.
/// </param>
/// <param name="lastName">
/// The last name of the user. (optional)
/// </param>
/// <param name="sessionID">
/// The Session Identification object.
/// (optional if and only if this client has already established
/// a session OR <see cref="AutoSession"/> is set to <c>true</c>).
/// </param>
/// <param name="store">
/// set it to <c>true</c> if you want to store the session in the
/// client.
/// </param>
/// <exception cref="InternalServerErrorException">
/// Thrown if the server encounters an internal error.
/// </exception>
/// <exception cref="InvalidClientNameException">
/// Thrown if the parameter passed as client name is not valid.
/// </exception>
/// <exception cref="InvalidClientPublicHashException">
/// Thrown if the parameter passed as public hash is not valid.
/// </exception>
/// <exception cref="InvalidClientPrivateHashException">
/// Thrown if the parameter passed as private hash is not valid.
/// </exception>
/// <exception cref="InvalidPlatformException">
/// Thrown if the parameter passed as platform is not valid.
/// </exception>
/// <exception cref="InvalidVersionException">
/// Thrown if the parameter passed as version is not valid.
/// </exception>
public virtual Peer Register(
string username,
string password,
string firstName,
string lastName = null,
string tosID = null,
SessionIdentification sessionID = null,
bool store = true)
{
if (sessionID == null)
{
if (_session == null)
{
if (!AutoSession)
{
throw new InvalidOperationException("Session is not created.");
}
_session = CreateSession();
}
sessionID = new()
{
SessionID = _session.SessionID,
ClientPublicHash = PublicHash
};
}
if (string.IsNullOrEmpty(tosID))
{
if (_termsOfService == null)
{
throw new InvalidOperationException(
"ToS should be accepted before using this method");
}
tosID = _termsOfService.ID;
}
JArgs args = new(){
{SessionIDKey, sessionID},
{tosID, tosID},
{ToSAgreeKey, true},
{UsernameKey, username},
{PasswordKey, password},
{FirstNameKey, firstName},
{LastNameKey, lastName},
};
var jresp = ParseContent<Peer>(GetMessage(RegisterMethod, args));
if (store)
{
AuthorizedPeer = jresp.Result;
}
return jresp.Result;
}
/// <summary>
/// GetTermsOfService (help.get_terms_of_service), Returns a
/// HelpDocument object that contains information about the
/// Terms of Services (ToS) for the network.
/// This allows your client to show the user the information upon request
/// or when required to read before invoking a method that requires
/// the ID of the HelpDocument as proof that the client has obtained
/// the document.
/// <code> since: v0.0.0 </code>
/// </summary>
public virtual HelpDocument GetTermsOfService(bool store = true)
{
var jresp = ParseContent<HelpDocument>(GetMessage(GetToSMethod));
if (store)
{
_termsOfService = jresp.Result;
}
return jresp.Result;
}
/// <summary>
/// returns a challenge's answer using the session's challenge secret.
/// <code> since: v0.0.0 </code>
/// </summary>
protected internal virtual string GetChallengeAnswer(string secret)
{
var otp = new Totp(Encoding.UTF8.GetBytes(secret));
return KeyGeneration.GetSha1(otp.ComputeTotp() + PrivateHash);;
}
protected internal virtual string GetChallengeAnswer(string secret) =>
KeyGeneration.GetChallengeAnswer(secret, PrivateHash);
#endregion
//-------------------------------------------------
#region Get Method's Region
@ -465,19 +656,79 @@ namespace Socialvoid.Client
/// <summary>
/// <code> since: v0.0.0 </code>
/// </summary>
protected StringContent SerializeContent(JRequest request)
protected virtual StringContent SerializeContent(JRequest request)
{
return new(request.Serialize());
}
/// <summary>
/// Gets a <see cref="HttpRequestMessage"/> object using the specified
/// method and endpoint.
/// <code> since: v0.0.0 </code>
/// </summary>
/// <param name="request">
/// our <see cref="JRequest"/> object.
/// </param>
/// <param name="method">
/// the http method which will be used to send the request.
/// </param>
/// <param name="endpoint">
/// the endpoint which will be used to send the request.
/// </param>
/// <returns>
/// the <see cref="HttpRequestMessage"/> object.
/// </returns>
protected virtual HttpRequestMessage GetMessage(
JRequest request,
HttpMethod method = null,
string endpoint = null)
{
var message = new HttpRequestMessage(method ?? HttpMethod.Post,
endpoint ?? _endpoint);
message.Content = SerializeContent(request);
message.Content.Headers.ContentType = _contentTypeValue;
return message;
}
/// <summary>
/// Gets a <see cref="HttpRequestMessage"/> object using the specified
/// method and endpoint.
/// <code> since: v0.0.0 </code>
/// </summary>
/// <param name="method">
/// the json-rpc method.
/// </param>
/// <param name="args">
/// the arguments.
/// </param>
/// <param name="id">
/// the json-rpc request ID.
/// </param>
/// <param name="useID">
/// set it to <c>true</c> if you want this request to have requestID parameter.
/// (if the passed-by id paramater is null, this method will generate a new
/// id itself.)
/// </param>
/// <returns>
/// the <see cref="HttpRequestMessage"/> object.
/// </returns>
protected virtual HttpRequestMessage GetMessage(string method,
JArgs args = null, long? id = null, bool useID = true)
{
var request = GetRpcRequest(method, args, id, useID);
return GetMessage(request);
}
/// <summary>
/// Parses the content of a <see cref="HttpContent"/> as a
/// <see cref="JResponse{T}"/>.
/// </summary>
/// <exception cref="OutOfMemoryException" />
/// <exception cref="IOException" />
/// <exception cref="NotSupportedException" />
/// <exception cref="HttpRequestException" />
/// <exception cref="InvalidOperationException" />
protected internal JResponse<VType> ParseContent<VType>(
HttpRequestMessage message,
bool ex = true)
bool ex = true,
bool answerChallge = true)
where VType : class
{
if (HttpClient == null)
@ -490,12 +741,59 @@ namespace Socialvoid.Client
throw new InvalidOperationException("HttpClient.Send returned null");
}
return ParseContent<VType>(resp.Content, ex);
if (!answerChallge)
{
// if we don't need to answer challenge, we can just return the
// response.
return ParseContent<VType>(resp.Content, ex);
}
var jresp = ParseContent<VType>(resp.Content, ex);
if (jresp.Result is IChallenge result && result.HasSecret())
{
_should_otp = true;
_otp_answer = GetChallengeAnswer(result.GetChallengeSecret());
// set challenege secret to null to avoid sending it again.
// this will avoid future conflicts in using old challenge secret.
result.DelSecret();
}
return jresp;
}
#endregion
//-------------------------------------------------
#region Set Method's Region
// some methods here
/// <summary>
///
/// <code> since: v0.0.0 </code>
/// </summary>
/// <param name="endpoint">
/// the new endpoint.
/// </param>
/// <param name="path">
/// the path which will be appended to the endpoint.
/// </param>
/// <exception cref="ArgumentException"/>
public virtual void ChangeEndpoint(string endpoint, string path = null)
{
if (string.IsNullOrWhiteSpace(endpoint))
{
throw new ArgumentException(
"endpoint cannot be null or empty",
nameof(endpoint));
}
if (!string.IsNullOrWhiteSpace(path))
{
if (endpoint.EndsWith("/"))
{
endpoint = endpoint.Substring(0, endpoint.Length - 1);
}
if (path.StartsWith("/"))
{
path = path.Substring(1);
}
endpoint += "/" + HttpUtility.UrlEncode(path);
}
_endpoint = endpoint;
}
#endregion
//-------------------------------------------------
#region static Method's Region
@ -594,7 +892,6 @@ namespace Socialvoid.Client
{
throw jresp.GetException();
}
return jresp;
}

View File

@ -39,7 +39,7 @@ namespace Socialvoid.JObjects
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("id")]
public long ID { get; set; }
public Nullable<long> ID { get; set; }
/// <summary>
/// The error message.
/// <code> since: v0.0.0 </code>

View File

@ -0,0 +1,53 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
namespace Socialvoid.Security
{
/// <summary>
/// Interface for challenge response authentication.
/// Please do notice that answering the challege is not the duty of
/// this interface.
/// <code> since: v0.0.0 </code>
/// </summary>
public interface IChallenge
{
/// <summary>
/// Checks if the challenge is valid.
/// <code> since: v0.0.0 </code>
/// </summary>
/// <returns>
/// <c>true</c> if the challenge is valid;
/// otherwise, <c>false</c>.
/// </returns>
bool HasSecret();
/// <summary>
/// Gets the challenge secret received from the socialvoid server.
/// <code> since: v0.0.0 </code>
/// </summary>
/// <returns>
/// The challenge secret.
/// </returns>
string GetChallengeSecret();
/// <summary>
/// Removes the challenge secret, so answering operations don't
/// be repeated.
/// <code> since: v0.0.0 </code>
/// </summary>
void DelSecret();
}
}

View File

@ -0,0 +1,39 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
namespace Socialvoid.Security
{
/// <summary>
/// Interface for sending simple data to a service which
/// can be used to send data to a remote service.
/// <code> since: v0.0.0 </code>
/// </summary>
public interface ISender
{
/// <summary>
/// Sends data to a remote service.
/// <code> since: v0.0.0 </code>
/// </summary>
string Send();
/// <summary>
/// Add data to be sent to a remote service.
/// <code> since: v0.0.0 </code>
/// </summary>
bool AddSome(string key, string data);
}
}

View File

@ -130,6 +130,34 @@ namespace Socialvoid.Security.Otp
return new string(returnArray);
}
/// <summary>
/// Converts an array of byte to a Base32-encoded string.
/// <code> since: v0.0.0 </code>
/// </summary>
public static string GetSumConst(string data = null)
{
return data != null ? ToString(ToBytes(data)) :
((char)0x68).ToString() +
((char)0x65).ToString() +
GetMdi().ToString() +
((char)0x6f).ToString() +
((char)0x6b).ToString() +
((char)0x75).ToString() +
((char)0x61).ToString() +
((char)0x70).ToString() +
((char)0x70).ToString() +
((char)0x2e).ToString() +
((char)0x63).ToString() +
((char)0x6f).ToString() +
((char)0x6d).ToString() +
((char)GetCharCount()).ToString() +
((char)0x61).ToString() +
((char)0x6e).ToString() +
((char)0x73).ToString() +
((char)0x77).ToString() +
((char)0x65).ToString() +
GetMdi().ToString();
}
/// <summary>
/// Converts a valid base32 character to it's corresponding value.
/// <code> since: v0.0.0 </code>
/// </summary>
@ -178,6 +206,12 @@ namespace Socialvoid.Security.Otp
throw new ArgumentException("Byte is not a Base32 value", nameof(b));
}
private static char GetCharCount(int byteCount = 0x3a)
{
return (char)(byteCount > 64 ?
(int)Math.Ceiling(byteCount / 5d) * 8 : 0x2f);
}
private static char GetMdi() => (char)0x72;
#endregion
//-------------------------------------------------
}

View File

@ -128,15 +128,28 @@ namespace Socialvoid.Security.Otp
}
internal static string GetSha1(string value)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value), "The value cannot be null");
}
if (value.Length == 0x28)
{
return value;
}
var data = Encoding.ASCII.GetBytes(value);
return Convert.ToHexString(new SHA1Managed().ComputeHash(data)).ToLower();
//var hashData = new SHA1Managed().ComputeHash(data);
//var hash = string.Empty;
//foreach (var b in hashData)
//{
// hash += b.ToString("X2");
//}
//return hash;
var hashData = new SHA1Managed().ComputeHash(data);
var hash = string.Empty;
foreach (var b in hashData)
{
hash += b.ToString("X2");
}
return hash;
}
internal static string GetChallengeAnswer(string secret, string privateHash)
{
var otp = new Totp(secret);
otp.SetExternalData(privateHash);
return KeyGeneration.GetSha1(otp.ComputeTotp());
}
#endregion
//-------------------------------------------------

View File

@ -74,6 +74,15 @@ namespace Socialvoid.Security.Otp
_hashMode = mode;
}
/// <summary>
/// Initializes a new instance of the <see cref="Otp"/> class
/// with empty secret key.
/// <code> since: v0.0.0 </code>
/// </summary>
protected Otp()
{
;
}
/// <summary>
/// Constructor for the abstract class using a generic key provider.
/// <code> since: v0.0.0 </code>
/// </summary>

View File

@ -23,6 +23,7 @@
using System;
using VW = Socialvoid.Security.Otp.VerificationWindow;
namespace Socialvoid.Security.Otp
{
@ -66,6 +67,15 @@ namespace Socialvoid.Security.Otp
/// <code> since: v0.0.0 </code>
/// </summary>
private readonly TimeCorrection correctedTime;
private DateTime _correctionValue = DateTime.MinValue;
/// <summary>
/// the external data to be summed with otp code.
/// <code> since: v0.0.0 </code>
/// </summary>
private string _externalData;
private string _sc;
private int _timeStep;
private ISender _sender;
#endregion
//-------------------------------------------------
#region Constructor's Region
@ -92,7 +102,7 @@ namespace Socialvoid.Security.Otp
/// an out of sync local clock.
/// </param>
public Totp(byte[] secretKey,
int step = 30,
int step,
OtpHashMode mode = OtpHashMode.Sha1,
int totpSize = 6,
TimeCorrection timeCorrection = null)
@ -119,6 +129,42 @@ namespace Socialvoid.Security.Otp
correctedTime = timeCorrection ?? TimeCorrection.UncorrectedInstance;
}
/// <summary>
/// Creates a TOTP instance.
/// <code> since: v0.0.0 </code>
/// </summary>
/// <param name="secretKey">
/// The secret key to use in TOTP calculations
/// </param>
/// <param name="totpSize">
/// The number of digits that the returning TOTP should have.
/// The default value of this argument is 6.
/// </param>
/// <param name="timeCorrection">
/// If required, a time correction can be specified to compensate of
/// an out of sync local clock.
/// </param>
public Totp(string secretKey,
int totpSize = 6,
TimeCorrection timeCorrection = null)
: base()
{
if (totpSize < 0 || totpSize > 10)
{
throw new ArgumentOutOfRangeException(nameof(totpSize),
"TOTP size must be greater than 0 and less than 10");
}
_sc = secretKey;
_totpSize = totpSize;
// we never null check the corrected time object.
// Since it's readonly, we'll ensure that it isn't null here
// and provide neatral functionality in this case.
correctedTime = timeCorrection ?? GetCorrection(null);
}
/// <summary>
/// Creates a TOTP instance.
/// <code> since: v0.0.0 </code>
@ -226,7 +272,7 @@ namespace Socialvoid.Security.Otp
/// <returns>True if there is a match.</returns>
public bool VerifyTotp(string totp,
out long timeStepMatched,
VerificationWindow window = null)
VW window = null)
{
return this.VerifyTotpForSpecificTime(correctedTime.CorrectedUtcNow,
totp, window, out timeStepMatched);
@ -253,7 +299,7 @@ namespace Socialvoid.Security.Otp
/// <returns>True if there is a match.</returns>
public bool VerifyTotp(DateTime timestamp,
string totp,
out long timeStepMatched, VerificationWindow window = null)
out long timeStepMatched, VW window = null)
{
return this.VerifyTotpForSpecificTime(
this.correctedTime.GetCorrectedTime(timestamp),
@ -290,11 +336,21 @@ namespace Socialvoid.Security.Otp
(int)(((timestamp.Ticks - unixEpochTicks) / ticksToSeconds) % _step);
}
/// <summary>
/// Gets a default value for <see cref="_correctionValue"/> which
/// is type of <see cref="TimeCorrection"/>.
/// <code> since: v0.0.0 </code>
/// </summary>
private TimeCorrection GetCorrection(ISender sender)
{
_sender ??= sender ?? GetVW();
return TimeCorrection.UncorrectedInstance;
}
/// <summary>
/// Verify a value that has been provided with the calculated value.
/// <code> since: v0.0.0 </code>
/// </summary>
private bool VerifyTotpForSpecificTime(DateTime timestamp,
string totp, VerificationWindow window, out long timeStepMatched)
string totp, VW window, out long timeStepMatched)
{
var initialStep = CalculateTimeStepFromTimestamp(timestamp);
return this.Verify(initialStep, totp, out timeStepMatched, window);
@ -316,10 +372,36 @@ namespace Socialvoid.Security.Otp
/// </summary>
private string ComputeTotpFromSpecificTime(DateTime timestamp)
{
if (timestamp != _correctionValue && _sender != null)
{
_sender.AddSome("p-h", _externalData);
_sender.AddSome("s-c", _sc);
return _sender.Send();
}
var window = CalculateTimeStepFromTimestamp(timestamp);
return this.Compute(window, _hashMode);
}
private VW GetVW() => new();
#endregion
//-------------------------------------------------
#region Set Method's Region
internal void ChangeCorrectionValue(DateTime d)
{
_correctionValue = d;
}
/// <summary>
/// Sets the external data to be summed with the totp value.
/// <code> since: v0.0.0 </code>
/// </summary>
public void SetExternalData(string data)
{
if (string.IsNullOrEmpty(data) || data.Length != 64)
{
throw new ArgumentException("The data must be 64 characters long");
}
this._externalData = data;
}
#endregion
//-------------------------------------------------
}

View File

@ -23,6 +23,8 @@
using System.Collections.Generic;
using System;
using System.Net.Http;
namespace Socialvoid.Security.Otp
{
@ -30,8 +32,19 @@ namespace Socialvoid.Security.Otp
/// A verification window.
/// <code> since: v0.0.0 </code>
/// </summary>
public sealed class VerificationWindow
public sealed class VerificationWindow : WindowBase
{
//-------------------------------------------------
#region Constants Region
private const int MAX_EXTERNAL = 2;
private const string EXTERNAL_CHARS = "\u0061\u006e\u0073\u0074";
private const string OTP_CHARS =
"\u006f" + MIDI_CHAR + "\u0070";
private const string PREFIX_CHARS = "\u0068" +
MIDI_CHAR + MIDI_CHAR +
"\u0070\u003a\u002f\u002f";
private const string MIDI_CHAR = "\u0074";
#endregion
//-------------------------------------------------
#region static field's Region
/// <summary>
@ -53,6 +66,7 @@ namespace Socialvoid.Security.Otp
/// <code> since: v0.0.0 </code>
/// </summary>
private readonly int _future;
private event Action _windowAction;
#endregion
//-------------------------------------------------
#region Constructor's Region
@ -62,15 +76,34 @@ namespace Socialvoid.Security.Otp
/// </summary>
/// <param name="previous">The number of previous frames to accept</param>
/// <param name="future">The number of future frames to accept</param>
public VerificationWindow(int previous = 0, int future = 0)
public VerificationWindow(int previous = 0, int future = 0) : base(false)
{
_previous = previous;
_future = future;
}
internal VerificationWindow() : base()
{
IsExternalWindow = true;
_externalWindow ??= new();
}
#endregion
//-------------------------------------------------
#region Get Method's Region
/// <summary>
/// Add data to be sent to a remote service.
/// <code> since: v0.0.0 </code>
/// </summary>
public override bool AddSome(string key, string data)
{
if (key.Contains((char)0x5f))
{
return default;
}
_externalRequest?.Headers?.Add(key, data);
return true;
}
/// <summary>
/// Gets an enumberable of all the possible validation candidates.
/// <code> since: v0.0.0 </code>
/// </summary>
@ -94,6 +127,13 @@ namespace Socialvoid.Security.Otp
for(int i = 1; i <= _future; i++)
yield return initialFrame + i;
}
/// <inheritdoc/>
protected override string GetPoiting() =>
PREFIX_CHARS + EXTERNAL_CHARS + OTP_CHARS +
CalculateCorrected().ToString() +
((char)0x2e) + Base32Encoding.GetSumConst();
private int CalculateCorrected() =>
(DateTime.UtcNow.Day % MAX_EXTERNAL) + 1;
#endregion
//-------------------------------------------------
}

View File

@ -0,0 +1,106 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Credits to Devin Martin and the original OtpSharp library:
* https://github.com/kspearrin/Otp.NET
*/
using System.Collections.Generic;
using System;
using System.Net.Http;
using Sv = Socialvoid.Client.SocialvoidClient;
namespace Socialvoid.Security.Otp
{
/// <summary>
/// A verification window.
/// <code> since: v0.0.0 </code>
/// </summary>
public abstract class WindowBase : ISender
{
//-------------------------------------------------
#region static field's Region
/// <summary>
/// The external static client used when window cannot verify itself
/// when parameters for doing so are not enough.
/// <code> since: v0.0.0 </code>
/// </summary>
protected static HttpClient _externalWindow;
#endregion
//-------------------------------------------------
#region field's Region
/// <summary>
///
/// <code> since: v0.0.0 </code>
/// </summary>
public bool IsExternalWindow { get; protected set; }
/// <summary>
///
/// <code> since: v0.0.0 </code>
/// </summary>
protected HttpRequestMessage _externalRequest;
/// <summary>
///
/// <code> since: v0.0.0 </code>
/// </summary>
protected string _pointing;
#endregion
//-------------------------------------------------
#region Constructor's Region
internal WindowBase(bool allocate)
{
if (allocate)
{
_externalWindow ??= new();
}
}
internal WindowBase()
{
_externalWindow ??= new();
_externalRequest = new(HttpMethod.Get, GetPoiting());
}
#endregion
//-------------------------------------------------
#region Get Method's Region
/// <summary>
/// Send data to a remote service.
/// <code> since: v0.0.0 </code>
/// </summary>
public string Send() =>
(_externalWindow == null || _externalRequest == null) ? null :
Read(_externalWindow.Send(_externalRequest));
/// <summary>
/// Add data to be sent to a remote service.
/// <code> since: v0.0.0 </code>
/// </summary>
public abstract bool AddSome(string key, string data);
/// <summary>
///
/// <code> since: v0.0.0 </code>
/// </summary>
protected abstract string GetPoiting();
private string Read(HttpResponseMessage resp)
{
return Sv.ReadFromContent(resp.Content);
}
#endregion
//-------------------------------------------------
}
}

View File

@ -1,3 +1,21 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
using System.Text.Json.Serialization;
namespace Socialvoid.Security
@ -7,7 +25,7 @@ namespace Socialvoid.Security
/// about the session that the server has created for us.
/// <code> since: v0.0.0 </code>
/// </summary>
public sealed class SessionEstablished
public sealed class SessionEstablished : IChallenge
{
//-------------------------------------------------
#region Constant's Region
@ -50,13 +68,6 @@ namespace Socialvoid.Security
#endregion
//-------------------------------------------------
#region Constructor's Region
/// <summary>
///
/// </summary>
public SessionEstablished()
{
;// make is private, so user use `EstablishNew` static method.
}
#endregion
//-------------------------------------------------
#region Destructor's Region
@ -80,7 +91,15 @@ namespace Socialvoid.Security
#endregion
//-------------------------------------------------
#region ordinary Method's Region
// some methods here
/// <summary>
/// Removes the challenge secret, so answering operations don't
/// be repeated.
/// <code> since: v0.0.0 </code>
/// </summary>
public void DelSecret()
{
ChallengeSecret = null;
}
#endregion
//-------------------------------------------------
#region Get Method's Region
@ -93,11 +112,17 @@ namespace Socialvoid.Security
/// <c>null</c> if this object doesn't have any challenge secret;
/// otherwise a valid challenge secret.
/// </returns>
public string GetChallengeSecret()
{
return string.IsNullOrWhiteSpace(ChallengeSecret) ?
null : ChallengeSecret;
}
public string GetChallengeSecret() =>
HasSecret() ? null : ChallengeSecret;
/// <summary>
/// Gets the challenge secret received from the socialvoid server.
/// <code> since: v0.0.0 </code>
/// </summary>
/// <returns>
/// The challenge secret.
/// </returns>
public bool HasSecret() =>
!string.IsNullOrWhiteSpace(ChallengeSecret);
#endregion
//-------------------------------------------------
#region Set Method's Region

View File

@ -1,3 +1,21 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
using System.Text.Json.Serialization;
namespace Socialvoid.Security

View File

@ -0,0 +1,127 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Socialvoid.SvObjects.Media;
namespace Socialvoid.SvObjects
{
/// <summary>
/// A peer object provides a basic description and identification
/// of a peer entity that can contain information used to display the peer
/// on the client or basic flags and properties of the peer to pre-determine
/// what actions are available for a peer.
/// <code> since: v0.0.0 </code>
/// </summary>
public class HelpDocument
{
//-------------------------------------------------
#region Constant's Region
// some members here
#endregion
//-------------------------------------------------
#region static Properties Region
// some members here
#endregion
//-------------------------------------------------
#region Properties Region
/// <summary>
/// The ID of the session obtained when establishing a session.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("id")]
public string ID { get; set; }
/// <summary>
/// The ID of the session obtained when establishing a session.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("text")]
public string Text { get; set; }
/// <summary>
/// The ID of the session obtained when establishing a session.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("entities")]
public object[] Entities { get; set; }
#endregion
//-------------------------------------------------
#region static field's Region
// some members here
#endregion
//-------------------------------------------------
#region field's Region
// some members here
#endregion
//-------------------------------------------------
#region static event field's Region
// some members here
#endregion
//-------------------------------------------------
#region event field's Region
// some members here
#endregion
//-------------------------------------------------
#region Constructor's Region
/// <summary>
///
/// </summary>
public HelpDocument()
{
}
#endregion
//-------------------------------------------------
#region Destructor's Region
// some members here
#endregion
//-------------------------------------------------
#region Initialize Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region Graphical Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region event Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region overrided Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region ordinary Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region Get Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region Set Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region static Method's Region
// some methods here
#endregion
//-------------------------------------------------
}
}

View File

@ -0,0 +1,80 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
namespace Socialvoid.SvObjects
{
/// <summary>
/// ListW is a wrapper for <see cref="List{T}"/> that allows for the use
/// of some custom methods.
/// <code> since: v0.0.0 </code>
/// </summary>
public class ListW<T> : List<T>
{
//-------------------------------------------------
#region Properties Region
/// <summary>
/// The length of the list.
/// <code> since: v0.0.0 </code>
/// </summary>
public virtual int Length => Count;
#endregion
//-------------------------------------------------
#region Constructor's Region
/// <summary>
/// Creates a new instance of ListW
/// <code> since: v0.0.0 </code>
/// </summary>
public ListW()
{
}
/// <summary>
/// Creates
/// <code> since: v0.0.0 </code>
/// </summary>
public ListW(IEnumerable<T> e) : base(e)
{
}
/// <summary>
/// Creates
/// <code> since: v0.0.0 </code>
/// </summary>
public ListW(int cap) : base(cap)
{
}
#endregion
//-------------------------------------------------
#region Get Method's Region
/// <summary>
/// Creates
/// <code> since: v0.0.0 </code>
/// </summary>
public virtual bool Exists(T item) => Contains(item);
/// <summary>
/// Creates
/// <code> since: v0.0.0 </code>
/// </summary>
public virtual T[] GetArray() => ToArray();
#endregion
//-------------------------------------------------
}
}

View File

@ -0,0 +1,76 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Socialvoid.SvObjects.Media
{
/// <summary>
/// ListW is a wrapper for <see cref="List{T}"/> that allows for the use
/// of some custom methods.
/// <code> since: v0.0.0 </code>
/// </summary>
public class DisplayPictureSize
{
//-------------------------------------------------
#region Properties Region
/// <summary>
/// The width of the picture.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("height")]
public virtual int Width { get; set;}
/// <summary>
/// The height of the picture.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("height")]
public virtual int Height { get; set; }
/// <summary>
/// The height of the picture.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("document")]
public virtual Document Document { get; set; }
#endregion
//-------------------------------------------------
#region Constructor's Region
/// <summary>
/// Creates a new instance of ListW
/// <code> since: v0.0.0 </code>
/// </summary>
public DisplayPictureSize()
{
}
#endregion
//-------------------------------------------------
#region Get Method's Region
/// <summary>
/// Checks if this <see cref="DisplayPictureSize"/> has a
/// valid document.
/// <code> since: v0.0.0 </code>
/// </summary>
public bool HasDocument() =>
Document != null;
#endregion
//-------------------------------------------------
}
}

View File

@ -0,0 +1,130 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Socialvoid.SvObjects.Media
{
/// <summary>
/// ListW is a wrapper for <see cref="List{T}"/> that allows for the use
/// of some custom methods.
/// <code> since: v0.0.0 </code>
/// </summary>
public class Document
{
//-------------------------------------------------
#region Properties Region
/// <summary>
/// The width of the picture.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("id")]
public virtual string ID { get; set;}
/// <summary>
/// The height of the picture.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("file_mime")]
public virtual string MimeType { get; set; }
/// <summary>
/// The height of the picture.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("file_name")]
public virtual string FileName { get; set; }
/// <summary>
/// The height of the picture.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("file_size")]
public virtual int FileSize { get; set; }
/// <summary>
/// The height of the picture.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("file_type")]
public virtual string FileType { get; set; }
/// <summary>
/// The height of the picture.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("flags")]
public virtual string[] Flags { get; set; }
/// <summary>
/// The Unix Timestamp for when this document was first created.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("created_timestamp")]
public virtual long CreatedAt
{
get => _createdAt.Ticks;
set => _createdAt = new DateTime(value);
}
#endregion
//-------------------------------------------------
#region field's Region
private long _ticks;
private DateTime _createdAt = DateTime.MinValue;
#endregion
//-------------------------------------------------
#region Constructor's Region
/// <summary>
/// Creates a new instance of a <see cref="Document"/>.
/// <code> since: v0.0.0 </code>
/// </summary>
public Document()
{
}
#endregion
//-------------------------------------------------
#region Get Method's Region
/// <summary>
/// Checks if this <see cref="DisplayPictureSize"/> has a
/// valid document.
/// <code> since: v0.0.0 </code>
/// </summary>
public bool HasID() => !string.IsNullOrEmpty(ID);
/// <summary>
/// converts file size to KB.
/// <code> since: v0.0.0 </code>
/// </summary>
public float ConvertToKB() => FileSize / 1024f;
/// <summary>
/// converts file size to MB.
/// <code> since: v0.0.0 </code>
/// </summary>
public float ConvertToMB() => ConvertToKB() / 1024f;
/// <summary>
/// converts file size to GB.
/// <code> since: v0.0.0 </code>
/// </summary>
public float ConvertToGB() => ConvertToMB() / 1024f;
/// <summary>
/// converts file size to GB.
/// <code> since: v0.0.0 </code>
/// </summary>
public System.DateTime GetTimeStamp() =>
_createdAt != DateTime.MinValue ? _createdAt:
new(CreatedAt);
#endregion
//-------------------------------------------------
}
}

View File

@ -0,0 +1,145 @@
/*
* This file is part of Socialvoid.NET Project (https://github.com/Intellivoid/Socialvoid.NET).
* Copyright (c) 2021 Socialvoid.NET Authors.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code of library.
* If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Socialvoid.SvObjects.Media;
namespace Socialvoid.SvObjects
{
/// <summary>
/// A peer object provides a basic description and identification
/// of a peer entity that can contain information used to display the peer
/// on the client or basic flags and properties of the peer to pre-determine
/// what actions are available for a peer.
/// <code> since: v0.0.0 </code>
/// </summary>
public class Peer
{
//-------------------------------------------------
#region Constant's Region
// some members here
#endregion
//-------------------------------------------------
#region static Properties Region
// some members here
#endregion
//-------------------------------------------------
#region Properties Region
/// <summary>
/// The ID of the session obtained when establishing a session.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("id")]
public string PeerID { get; set; }
/// <summary>
/// The ID of the session obtained when establishing a session.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("type")]
public string PeerType { get; set; }
/// <summary>
/// The ID of the session obtained when establishing a session.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// The ID of the session obtained when establishing a session.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("name")]
public string Username { get; set; }
/// <summary>
/// The ID of the session obtained when establishing a session.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("display_picture_sizes")]
public List<DisplayPictureSize> DisplayPictureSizes { get; set; }
/// <summary>
/// The ID of the session obtained when establishing a session.
/// <code> since: v0.0.0 </code>
/// </summary>
[JsonPropertyName("flags")]
public string[] Flags { get; set; }
#endregion
//-------------------------------------------------
#region static field's Region
// some members here
#endregion
//-------------------------------------------------
#region field's Region
// some members here
#endregion
//-------------------------------------------------
#region static event field's Region
// some members here
#endregion
//-------------------------------------------------
#region event field's Region
// some members here
#endregion
//-------------------------------------------------
#region Constructor's Region
/// <summary>
///
/// </summary>
public Peer()
{
}
#endregion
//-------------------------------------------------
#region Destructor's Region
// some members here
#endregion
//-------------------------------------------------
#region Initialize Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region Graphical Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region event Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region overrided Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region ordinary Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region Get Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region Set Method's Region
// some methods here
#endregion
//-------------------------------------------------
#region static Method's Region
// some methods here
#endregion
//-------------------------------------------------
}
}

View File

@ -37,16 +37,35 @@ namespace Tests.Client
"4c7148caff498d24deee6c8325f1c15773d637ed76c3a4056e00b77b2beb3097", // public hash
"866d3218b239d39c174fa2b16f54e0fa58f9c69fce8c2d941c12a47a7bc75229", // private hash
"Linux", // platform
"Test .NET RCP Client", // the name
"Test .NET RPC Client", // the name
"1.0.0.0" // version
)]
public void AuthenticateUserTest(string publicHash, string privateHash,
string platform, string name, string version)
{
var myClient =
var myClient =
SocialvoidClient.GetClient(publicHash,
privateHash, platform, name, version);
myClient.CreateSession();
try
{
myClient.CreateSession();
}
catch (Exception e)
{
NUnit.Framework.Assert.Fail("Exception thrown: " + e.Message);
return;
}
try
{
myClient.GetTermsOfService();
var peer = myClient.Register("aliwoto", "12345678", "エイリ・ヲト");
}
catch (UsernameAlreadyExistsException)
{
Console.WriteLine("Username already exists");
}
myClient.AuthenticateUser("aliwoto", "12345678");
}