forked from SoDOff-Project/sodoff
Get/Set pairs
This commit is contained in:
parent
da7c7e526f
commit
2a4edfffef
@ -3,7 +3,7 @@ import mitmproxy.http
|
||||
|
||||
|
||||
def routable(path):
|
||||
methods = ['GetRules', 'LoginParent', 'RegisterParent', 'GetSubscriptionInfo', 'GetUserInfoByApiToken', 'IsValidApiToken_V2', 'ValidateName', 'GetDefaultNameSuggestion', 'RegisterChild', 'GetProfileByUserId', 'LoginChild', 'GetUserProfileByUserID']
|
||||
methods = ['GetRules', 'LoginParent', 'RegisterParent', 'GetSubscriptionInfo', 'GetUserInfoByApiToken', 'IsValidApiToken_V2', 'ValidateName', 'GetDefaultNameSuggestion', 'RegisterChild', 'GetProfileByUserId', 'LoginChild', 'GetUserProfileByUserID', 'GetKeyValuePair', 'SetKeyValuePair']
|
||||
for method in methods:
|
||||
if method in path:
|
||||
return True
|
||||
|
@ -1,15 +1,19 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using sodoff.Attributes;
|
||||
using sodoff.Model;
|
||||
using sodoff.Schema;
|
||||
using sodoff.Services;
|
||||
using sodoff.Util;
|
||||
|
||||
namespace sodoff.Controllers.Common;
|
||||
public class ContentController : Controller {
|
||||
|
||||
private readonly DBContext ctx;
|
||||
public ContentController(DBContext ctx) {
|
||||
private KeyValueService keyValueService;
|
||||
public ContentController(DBContext ctx, KeyValueService keyValueService) {
|
||||
this.ctx = ctx;
|
||||
this.keyValueService = keyValueService;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
@ -50,4 +54,72 @@ public class ContentController : Controller {
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/GetKeyValuePair")]
|
||||
public Schema.PairData? GetKeyValuePair([FromForm] string apiToken, [FromForm] int pairId) {
|
||||
// Find session by apiToken
|
||||
Session? session = ctx.Sessions.FirstOrDefault(s => s.ApiToken == apiToken);
|
||||
if (session is null)
|
||||
return null;
|
||||
|
||||
// Get the pair
|
||||
Model.PairData? pair = keyValueService.GetPairData(session, pairId);
|
||||
|
||||
return keyValueService.ModelToSchema(pair);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/SetKeyValuePair")]
|
||||
public IActionResult SetKeyValuePair([FromForm] string apiToken, [FromForm] int pairId, [FromForm] string contentXML) {
|
||||
Schema.PairData schemaData = XmlUtil.DeserializeXml<Schema.PairData>(contentXML);
|
||||
|
||||
// Get the session
|
||||
Session? session = ctx.Sessions.FirstOrDefault(s => s.ApiToken == apiToken);
|
||||
if (session is null)
|
||||
return Ok(false);
|
||||
|
||||
bool result = keyValueService.SetPairData(session, pairId, schemaData);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/GetKeyValuePairByUserID")]
|
||||
public Schema.PairData? GetKeyValuePairByUserID([FromForm] string apiToken, [FromForm] int pairId, [FromForm] string userId) {
|
||||
Session? session = ctx.Sessions.FirstOrDefault(s => s.ApiToken == apiToken);
|
||||
if (session is null)
|
||||
return null;
|
||||
|
||||
ctx.Entry(session).State = EntityState.Detached; // Don't update the entity
|
||||
session.VikingId = null;
|
||||
session.UserId = userId;
|
||||
|
||||
Model.PairData? pair = keyValueService.GetPairData(session, pairId);
|
||||
|
||||
return keyValueService.ModelToSchema(pair);
|
||||
}
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/SetKeyValuePairByUserID")]
|
||||
public IActionResult SetKeyValuePairByUserID([FromForm] string apiToken, [FromForm] int pairId, [FromForm] string userId, [FromForm] string contentXML) {
|
||||
Schema.PairData schemaData = XmlUtil.DeserializeXml<Schema.PairData>(contentXML);
|
||||
|
||||
// Get the session
|
||||
Session? session = ctx.Sessions.FirstOrDefault(s => s.ApiToken == apiToken);
|
||||
if (session is null || string.IsNullOrEmpty(userId))
|
||||
return Ok(false);
|
||||
|
||||
ctx.Entry(session).State = EntityState.Detached; // Don't update the entity
|
||||
session.VikingId = null;
|
||||
session.UserId = userId;
|
||||
|
||||
bool result = keyValueService.SetPairData(session, pairId, schemaData);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ public class DBContext : DbContext {
|
||||
public DbSet<User> Users { get; set; } = null!;
|
||||
public DbSet<Viking> Vikings { get; set; } = null!;
|
||||
public DbSet<Session> Sessions { get; set; } = null!;
|
||||
public DbSet<Pair> Pairs { get; set; } = null!;
|
||||
public DbSet<PairData> PairData { get; set; } = null!;
|
||||
public string DbPath { get; }
|
||||
|
||||
public DBContext() {
|
||||
@ -29,5 +31,16 @@ public class DBContext : DbContext {
|
||||
builder.Entity<Viking>().HasMany(u => u.Sessions)
|
||||
.WithOne(e => e.Viking);
|
||||
|
||||
builder.Entity<PairData>()
|
||||
.HasKey(e => e.Id);
|
||||
|
||||
builder.Entity<PairData>().HasMany(p => p.Pairs)
|
||||
.WithOne(e => e.PairData);
|
||||
|
||||
builder.Entity<Pair>()
|
||||
.HasOne(p => p.PairData)
|
||||
.WithMany(pd => pd.Pairs)
|
||||
.HasForeignKey(p => p.MasterId)
|
||||
.HasPrincipalKey(e => e.Id);
|
||||
}
|
||||
}
|
||||
|
18
src/Model/Pair.cs
Normal file
18
src/Model/Pair.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace sodoff.Model;
|
||||
|
||||
public class Pair {
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Key { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public int MasterId { get; set; }
|
||||
|
||||
public virtual PairData PairData { get; set; }
|
||||
}
|
21
src/Model/PairData.cs
Normal file
21
src/Model/PairData.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace sodoff.Model;
|
||||
|
||||
[Index(nameof(UserId))]
|
||||
[Index(nameof(VikingId))]
|
||||
public class PairData {
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
|
||||
public int PairId { get; set; }
|
||||
|
||||
public string? UserId { get; set; }
|
||||
|
||||
public string? VikingId { get; set; }
|
||||
|
||||
public virtual ICollection<Pair> Pairs { get; set; }
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using sodoff.Model;
|
||||
using sodoff.Services;
|
||||
using System.Xml;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
@ -8,8 +9,10 @@ var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.AddControllers(options => {
|
||||
options.OutputFormatters.Add(new XmlSerializerOutputFormatter(new XmlWriterSettings() { OmitXmlDeclaration = false }));
|
||||
options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
|
||||
});
|
||||
builder.Services.AddDbContext<DBContext>();
|
||||
builder.Services.AddScoped<KeyValueService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
16
src/Schema/Pair.cs
Normal file
16
src/Schema/Pair.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema;
|
||||
|
||||
[XmlRoot(ElementName = "Pair", Namespace = "")]
|
||||
[Serializable]
|
||||
public class Pair {
|
||||
[XmlElement(ElementName = "PairKey")]
|
||||
public string PairKey;
|
||||
|
||||
[XmlElement(ElementName = "PairValue")]
|
||||
public string PairValue;
|
||||
|
||||
[XmlElement(ElementName = "UpdateDate")]
|
||||
public DateTime UpdateDate;
|
||||
}
|
12
src/Schema/PairData.cs
Normal file
12
src/Schema/PairData.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema;
|
||||
|
||||
[XmlRoot(ElementName = "Pairs", Namespace = "", IsNullable = true)]
|
||||
[Serializable]
|
||||
public class PairData {
|
||||
[XmlElement("Pair", IsNullable = true)]
|
||||
public Pair[] Pairs { get; set; }
|
||||
}
|
||||
|
||||
|
79
src/Services/KeyValueService.cs
Normal file
79
src/Services/KeyValueService.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using sodoff.Model;
|
||||
using sodoff.Schema;
|
||||
|
||||
namespace sodoff.Services;
|
||||
public class KeyValueService {
|
||||
|
||||
private readonly DBContext ctx;
|
||||
|
||||
public KeyValueService(DBContext ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public Model.PairData? GetPairData(Session session, int pairId) {
|
||||
Model.PairData? pair = null;
|
||||
if (session.VikingId != null)
|
||||
pair = ctx.PairData.FirstOrDefault(e => e.PairId == pairId && e.VikingId == session.VikingId);
|
||||
else if (session.UserId != null)
|
||||
pair = ctx.PairData.FirstOrDefault(e => e.PairId == pairId && e.UserId == session.UserId);
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
public bool SetPairData(Session session, int pairId, Schema.PairData schemaData) {
|
||||
// Get the pair
|
||||
Model.PairData? pair = GetPairData(session, pairId);
|
||||
|
||||
// Create the pair if it doesn't exist
|
||||
bool exists = true;
|
||||
if (pair is null) {
|
||||
pair = new Model.PairData {
|
||||
PairId = pairId,
|
||||
UserId = session.UserId,
|
||||
VikingId = session.VikingId,
|
||||
Pairs = new List<Model.Pair>()
|
||||
};
|
||||
exists = false;
|
||||
}
|
||||
|
||||
// Update or create the key-value pairs
|
||||
foreach (var p in schemaData.Pairs) {
|
||||
if (string.IsNullOrEmpty(p.PairValue))
|
||||
return false; // NOTE: The real server doesn't update anything if one value is empty
|
||||
var pairItem = pair.Pairs.FirstOrDefault(e => e.Key == p.PairKey);
|
||||
if (pairItem != null)
|
||||
pairItem.Value = p.PairValue;
|
||||
else {
|
||||
pairItem = new Model.Pair {
|
||||
Key = p.PairKey,
|
||||
Value = p.PairValue
|
||||
};
|
||||
pair.Pairs.Add(pairItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (exists)
|
||||
ctx.PairData.Update(pair);
|
||||
else
|
||||
ctx.PairData.Add(pair);
|
||||
ctx.SaveChanges();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Schema.PairData? ModelToSchema(Model.PairData? model) {
|
||||
if (model is null) return null;
|
||||
|
||||
// Convert to schema class
|
||||
List<Schema.Pair> pairs = new List<Schema.Pair>();
|
||||
foreach (var p in model.Pairs) {
|
||||
pairs.Add(new Schema.Pair {
|
||||
PairKey = p.Key,
|
||||
PairValue = p.Value
|
||||
});
|
||||
}
|
||||
|
||||
return new Schema.PairData { Pairs = pairs.ToArray() };
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user