mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-06-22 05:47:28 +02:00
Initial version.
This commit is contained in:
parent
193aaa1a56
commit
b72c67a53e
228 changed files with 25924 additions and 0 deletions
91
TINKLib/Model/User/Account/Account.cs
Normal file
91
TINKLib/Model/User/Account/Account.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TINK.Model.User.Account
|
||||
{
|
||||
/// <summary> Specifies extra user permissions. </summary>
|
||||
[Flags]
|
||||
public enum Permissions
|
||||
{
|
||||
None = 0, // No extra permissions.
|
||||
PickCopriServer = 2, // Allows user to switch COPRI server.
|
||||
ManageCopriCacheExpiration = 4, // Allows to manage the livetime of COPRI cache entries.
|
||||
ManagePolling = 8, // Turn polling off or on and set pollig frequency.
|
||||
PickLockServiceImplementation = 16, // Allows to pick the implementation which controls bluetooth lock mangement.
|
||||
PickLocationServiceImplementation = 32, // Allows to pick the implementation which gets location information.
|
||||
PickLoggingLevel = 64, // Allows to select the logging level.
|
||||
ShowDiagnostics = 128, // Turns on display of diagnostics.
|
||||
SwitchNoSiteCaching = 1024, // Allows to turn off/ on caching of sites displayed in app hosted by COPRI
|
||||
All = PickCopriServer +
|
||||
ManageCopriCacheExpiration +
|
||||
ManagePolling +
|
||||
PickLockServiceImplementation +
|
||||
PickLocationServiceImplementation +
|
||||
PickLoggingLevel +
|
||||
ShowDiagnostics +
|
||||
SwitchNoSiteCaching,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies parts of account data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Usage: Account can be valid (user and password set) partly valid or completely invalid.
|
||||
/// </remarks>
|
||||
[Flags]
|
||||
public enum Elements
|
||||
{
|
||||
None = 0,
|
||||
Mail = 1,
|
||||
Password = 2,
|
||||
Account = Mail + Password
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds account data.
|
||||
/// </summary>
|
||||
public class Account : IAccount
|
||||
{
|
||||
/// <summary> Constructs an account object.</summary>
|
||||
/// <param name="p_oMail">Mail addresss.</param>
|
||||
/// <param name="p_Pwd">Password.</param>
|
||||
/// <param name="p_oSessionCookie">Session cookie from copri.</param>
|
||||
/// <param name="p_strGroup">Group holdig info about Group (TINK, Konrad, ...)</param>
|
||||
/// <param name="p_iDebugLevel">Flag which controls display of debug settings.</param>
|
||||
public Account(
|
||||
string p_oMail,
|
||||
string p_Pwd,
|
||||
string p_oSessionCookie,
|
||||
IEnumerable<string> p_strGroup,
|
||||
Permissions debugLevel = Permissions.None)
|
||||
{
|
||||
Mail = p_oMail;
|
||||
Pwd = p_Pwd;
|
||||
SessionCookie = p_oSessionCookie;
|
||||
DebugLevel = debugLevel;
|
||||
Group = p_strGroup != null
|
||||
? new HashSet<string>(p_strGroup).ToList()
|
||||
: throw new ArgumentException("Can not instantiate account object. Reference to group list must not be empty.");
|
||||
}
|
||||
|
||||
public Account(IAccount p_oSource) : this(p_oSource?.Mail, p_oSource?.Pwd, p_oSource?.SessionCookie, p_oSource?.Group, p_oSource?.DebugLevel ?? Permissions.None)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Mail address.</summary>
|
||||
public string Mail { get; }
|
||||
|
||||
/// <summary>Password of the account.</summary>
|
||||
public string Pwd { get; }
|
||||
|
||||
/// <summary>Session cookie used to sign in to copri.</summary>
|
||||
public string SessionCookie { get; }
|
||||
|
||||
/// <summary>Debug level used to determine which features are available.</summary>
|
||||
public Permissions DebugLevel { get; }
|
||||
|
||||
/// <summary> Holds the group of the bike (TINK, Konrad, ...).</summary>
|
||||
public IEnumerable<string> Group { get; }
|
||||
}
|
||||
}
|
34
TINKLib/Model/User/Account/AccountExtensions.cs
Normal file
34
TINKLib/Model/User/Account/AccountExtensions.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using System.Collections.Generic;
|
||||
using TINK.Model.Connector.Filter;
|
||||
|
||||
namespace TINK.Model.User.Account
|
||||
{
|
||||
public static class AccountExtensions
|
||||
{
|
||||
/// <summary> Gets information whether user is logged in or not from account object. </summary>
|
||||
/// <param name="p_oAccount">Object to get information from.</param>
|
||||
/// <returns>True if user is logged in, false if not.</returns>
|
||||
public static bool GetIsLoggedIn(this IAccount p_oAccount)
|
||||
{
|
||||
return !string.IsNullOrEmpty(p_oAccount.Mail)
|
||||
&& !string.IsNullOrEmpty(p_oAccount.SessionCookie);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters bike groups depending on whether user has access to all groups of bikes.
|
||||
/// Some user may be "TINK"- user only, some "Konrad" and some may be "TINK" and "Konrad" users.
|
||||
/// </summary>
|
||||
/// <param name="account">Account to filter with.</param>
|
||||
/// <param name="filter">Groups to filter.</param>
|
||||
/// <returns>Filtered bike groups.</returns>
|
||||
public static IEnumerable<string> DoFilter(
|
||||
this IAccount account,
|
||||
IEnumerable<string> filter)
|
||||
{
|
||||
|
||||
return GetIsLoggedIn(account)
|
||||
? GroupFilterFactory.Create(account.Group).DoFilter(filter) // Filter if user is logged in.
|
||||
: new NullGroupFilter().DoFilter(filter); // Do not filter if no user is logged in.
|
||||
}
|
||||
}
|
||||
}
|
74
TINKLib/Model/User/Account/AccountMutable.cs
Normal file
74
TINKLib/Model/User/Account/AccountMutable.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace TINK.Model.User.Account
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds email address and password.
|
||||
/// </summary>
|
||||
public class AccountMutable : IAccount
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the account data.
|
||||
/// </summary>
|
||||
private Account m_oAccount;
|
||||
|
||||
/// <summary> Prevents an invalid instance to be created. </summary>
|
||||
private AccountMutable()
|
||||
{
|
||||
}
|
||||
|
||||
public AccountMutable(IAccount p_oSource)
|
||||
{
|
||||
m_oAccount = new Account(p_oSource);
|
||||
}
|
||||
|
||||
public void Copy(IAccount p_oSource)
|
||||
{
|
||||
m_oAccount = new Account(p_oSource);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mail address.
|
||||
/// </summary>
|
||||
public string Mail
|
||||
{
|
||||
get { return m_oAccount.Mail; }
|
||||
set { m_oAccount = new Account(value, m_oAccount.Pwd, m_oAccount.SessionCookie, m_oAccount.Group, m_oAccount.DebugLevel); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Password of the account.
|
||||
/// </summary>
|
||||
public string Pwd
|
||||
{
|
||||
get { return m_oAccount.Pwd; }
|
||||
set { m_oAccount = new Account(m_oAccount.Mail, value, m_oAccount.SessionCookie, m_oAccount.Group, m_oAccount.DebugLevel); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Session cookie used to sign in to copri.
|
||||
/// </summary>
|
||||
public string SessionCookie
|
||||
{
|
||||
get { return m_oAccount.SessionCookie; }
|
||||
set { m_oAccount = new Account(m_oAccount.Mail, m_oAccount.Pwd, value, m_oAccount.Group, m_oAccount.DebugLevel); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the group of the bike (TINK, Konrad, ...).
|
||||
/// </summary>
|
||||
public IEnumerable<string> Group
|
||||
{
|
||||
get { return m_oAccount.Group; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Debug level used to determine which features are available.
|
||||
/// </summary>
|
||||
public Permissions DebugLevel
|
||||
{
|
||||
get { return m_oAccount.DebugLevel; }
|
||||
set { m_oAccount = new Account(m_oAccount.Mail, m_oAccount.Pwd, m_oAccount.SessionCookie, m_oAccount.Group, value); }
|
||||
}
|
||||
}
|
||||
}
|
18
TINKLib/Model/User/Account/EmptyAccount.cs
Normal file
18
TINKLib/Model/User/Account/EmptyAccount.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace TINK.Model.User.Account
|
||||
{
|
||||
/// <summary> Represents an empty account.</summary>
|
||||
public class EmptyAccount : IAccount
|
||||
{
|
||||
public string Mail => null;
|
||||
|
||||
public string Pwd => null;
|
||||
|
||||
public string SessionCookie => null;
|
||||
|
||||
public Permissions DebugLevel => Permissions.None;
|
||||
|
||||
public IEnumerable<string> Group => new List<string>();
|
||||
}
|
||||
}
|
25
TINKLib/Model/User/Account/IAccount.cs
Normal file
25
TINKLib/Model/User/Account/IAccount.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace TINK.Model.User.Account
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds account data.
|
||||
/// </summary>
|
||||
public interface IAccount
|
||||
{
|
||||
/// <summary>Mail address.</summary>
|
||||
string Mail { get; }
|
||||
|
||||
/// <summary>Password of the account.</summary>
|
||||
string Pwd { get; }
|
||||
|
||||
/// <summary>Session cookie used to sign in to copri.</summary>
|
||||
string SessionCookie { get; }
|
||||
|
||||
/// <summary>Debug level used to determine which features are available.</summary>
|
||||
Permissions DebugLevel { get; }
|
||||
|
||||
/// <summary> Holds the group of the bike (TINK, Konrad, ...).</summary>
|
||||
IEnumerable<string> Group { get; }
|
||||
}
|
||||
}
|
26
TINKLib/Model/User/Account/IStore.cs
Normal file
26
TINKLib/Model/User/Account/IStore.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
namespace TINK.Model.User.Account
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface to manage an account store.
|
||||
/// </summary>
|
||||
public interface IStore
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads mail address and password from account store.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IAccount Load();
|
||||
|
||||
/// <summary>
|
||||
/// Writes mail address and password to account store.
|
||||
/// </summary>
|
||||
/// <param name="p_oMailAndPwd"></param>
|
||||
void Save(IAccount p_oMailAndPwd);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes mail address and password from account store.
|
||||
/// </summary>
|
||||
/// <returns> Empty account instance if deleting succeeded.</returns>
|
||||
IAccount Delete(IAccount p_oMailAndPwd);
|
||||
}
|
||||
}
|
167
TINKLib/Model/User/Account/Validator.cs
Normal file
167
TINKLib/Model/User/Account/Validator.cs
Normal file
|
@ -0,0 +1,167 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TINK.Model.User.Account
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the state of mail and password and information about some invalid parts if there are.
|
||||
/// </summary>
|
||||
public class State
|
||||
{
|
||||
/// <summary>
|
||||
/// Consider state to be invalid after construction.
|
||||
/// </summary>
|
||||
private Elements m_eElements = Elements.None;
|
||||
|
||||
private Dictionary<Elements, string> m_oDescription = new Dictionary<Elements, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs object to state all entries are valid.
|
||||
/// </summary>
|
||||
public State()
|
||||
{
|
||||
m_eElements = Elements.Account;
|
||||
|
||||
m_oDescription = new Dictionary<Elements, string>
|
||||
{
|
||||
{ Elements.None, string.Empty },
|
||||
{ Elements.Account, string.Empty }
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs object to state some/ all elements are invalid.
|
||||
/// </summary>
|
||||
/// <param name="p_oValidParts">Specifies the parts which are invalid.</param>
|
||||
/// <param name="p_oDescription">Description of invalid parts.</param>
|
||||
public State(Elements p_oValidParts, Dictionary<Elements, string> p_oDescription)
|
||||
{
|
||||
m_eElements = p_oValidParts;
|
||||
|
||||
m_oDescription = p_oDescription ?? new Dictionary<Elements, string>();
|
||||
|
||||
// Ensure consistency
|
||||
foreach (Elements l_oElement in Enum.GetValues(typeof(Elements)))
|
||||
{
|
||||
if (!m_oDescription.ContainsKey(l_oElement))
|
||||
{
|
||||
switch (l_oElement)
|
||||
{
|
||||
case Elements.Account:
|
||||
case Elements.None:
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
m_oDescription.Add(l_oElement, string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if account is valid.
|
||||
/// </summary>
|
||||
public bool IsValid { get { return ValidElement == Elements.Account; } }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies if both mail and password are valid, one of them or none.
|
||||
/// </summary>
|
||||
public Elements ValidElement
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_eElements;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the message about invalid elements.
|
||||
/// </summary>
|
||||
public Dictionary<Elements, string> Description
|
||||
{
|
||||
get
|
||||
{
|
||||
var l_oUserFriendlyDescription = new Dictionary<Elements, string>();
|
||||
foreach (Elements l_oElement in Enum.GetValues(typeof(Elements)))
|
||||
{
|
||||
switch (l_oElement)
|
||||
{
|
||||
case Elements.Account:
|
||||
case Elements.None:
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
l_oUserFriendlyDescription.Add(
|
||||
l_oElement,
|
||||
m_oDescription.ContainsKey(l_oElement) ? m_oDescription[l_oElement] : string.Empty);
|
||||
}
|
||||
|
||||
l_oUserFriendlyDescription.Add(
|
||||
Elements.Account,
|
||||
string.Join(";", l_oUserFriendlyDescription.Where(x => x.Value.Length > 0).Select(x => x.Value).ToArray()));
|
||||
|
||||
return l_oUserFriendlyDescription ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies if a password is valid or not.
|
||||
/// </summary>
|
||||
/// <param name="p_strMail"></param>
|
||||
/// <param name="p_strPassword"></param>
|
||||
/// <returns></returns>
|
||||
public delegate State PasswordValidator(string p_strMail, string p_strPassword);
|
||||
|
||||
public static class Validator
|
||||
{
|
||||
public static State ValidateMailAndPasswordDelegate(string p_strMail, string p_strPassword)
|
||||
{
|
||||
var l_oElements = Elements.None;
|
||||
var l_oDescription = new Dictionary<Elements, string>();
|
||||
|
||||
// Validate mail address.
|
||||
if (string.IsNullOrEmpty(p_strMail))
|
||||
{
|
||||
l_oDescription.Add(Elements.Mail, "Email Addresse darf nicht leer sein.");
|
||||
}
|
||||
else if (p_strMail.ToString().Split('@').Length < 2)
|
||||
{
|
||||
l_oDescription.Add(Elements.Mail, "Email Adresse mit Zeichen \"@\" enthalten.");
|
||||
}
|
||||
else if (p_strMail.ToString().Split('@')[0].Length <= 0)
|
||||
{
|
||||
l_oDescription.Add(Elements.Mail, "Benutzername in Email Adresse darf nicht leer sein.");
|
||||
}
|
||||
else if (p_strMail.ToString().Split('@')[1].Length <= 0)
|
||||
{
|
||||
// Data has been entered
|
||||
l_oDescription.Add(Elements.Mail, "Domain- Name in Email Adresse darf nicht leer sein.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Input mail address is ok
|
||||
l_oElements = Elements.Mail;
|
||||
l_oDescription.Add(Elements.Mail, string.Empty);
|
||||
}
|
||||
|
||||
// Validate password.
|
||||
if (string.IsNullOrEmpty(p_strPassword) || p_strPassword.Length < 8)
|
||||
{
|
||||
// Data has been entered
|
||||
l_oDescription.Add(Elements.Password, "Passwort is zu kurz.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Password is ok
|
||||
l_oElements |= Elements.Password;
|
||||
l_oDescription.Add(Elements.Password, string.Empty);
|
||||
}
|
||||
|
||||
return new State(l_oElements, l_oDescription);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue