feat: LeanEngine
parent
e5b9f29575
commit
aad4e7cc47
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
||||
public class LCEngineFunctionAttribute : Attribute {
|
||||
public string FunctionName {
|
||||
get;
|
||||
}
|
||||
|
||||
public LCEngineFunctionAttribute(string funcName) {
|
||||
if (string.IsNullOrEmpty(funcName)) {
|
||||
throw new ArgumentNullException(nameof(funcName));
|
||||
}
|
||||
FunctionName = funcName;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
|
||||
public class LCEngineFunctionParameterAttribute : Attribute {
|
||||
public string ParameterName {
|
||||
get;
|
||||
}
|
||||
|
||||
public LCEngineFunctionParameterAttribute(string paramName) {
|
||||
if (string.IsNullOrEmpty(paramName)) {
|
||||
throw new ArgumentNullException(nameof(paramName));
|
||||
}
|
||||
ParameterName = paramName;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public enum LCEngineObjectHookType {
|
||||
BeforeSave,
|
||||
AfterSave,
|
||||
BeforeUpdate,
|
||||
AfterUpdate,
|
||||
BeforeDelete,
|
||||
AfterDelete
|
||||
}
|
||||
|
||||
public class LCEngineObjectHookAttribute : Attribute {
|
||||
public string ClassName {
|
||||
get;
|
||||
}
|
||||
|
||||
public LCEngineObjectHookType HookType {
|
||||
get;
|
||||
}
|
||||
|
||||
public LCEngineObjectHookAttribute(string className, LCEngineObjectHookType hookType) {
|
||||
ClassName = className;
|
||||
HookType = hookType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public enum LCEngineRealtimeHookType {
|
||||
// 消息
|
||||
MessageReceived,
|
||||
MessageSent,
|
||||
MessageUpdate,
|
||||
ReceiversOffline,
|
||||
// 对话
|
||||
ConversationStart,
|
||||
ConversationStarted,
|
||||
ConversationAdd,
|
||||
ConversationAdded,
|
||||
ConversationRemove,
|
||||
ConversationRemoved,
|
||||
ConversationUpdate,
|
||||
// 客户端
|
||||
ClientOnline,
|
||||
ClientOffline,
|
||||
}
|
||||
|
||||
public class LCEngineRealtimeHookAttribute : Attribute {
|
||||
public LCEngineRealtimeHookType HookType {
|
||||
get;
|
||||
}
|
||||
|
||||
public LCEngineRealtimeHookAttribute(LCEngineRealtimeHookType hookType) {
|
||||
HookType = hookType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public enum LCEngineUserHookType {
|
||||
SMS,
|
||||
Email,
|
||||
OnLogin
|
||||
}
|
||||
|
||||
public class LCEngineUserHookAttribute : Attribute {
|
||||
public LCEngineUserHookType HookType {
|
||||
get;
|
||||
}
|
||||
|
||||
public LCEngineUserHookAttribute(LCEngineUserHookType hookType) {
|
||||
HookType = hookType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common\Common\Common.csproj" />
|
||||
<ProjectReference Include="..\Storage\Storage\Storage.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using LeanCloud.Storage.Internal.Object;
|
||||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public class LCClassHookHandler {
|
||||
private static Dictionary<string, MethodInfo> ClassHooks => LCEngine.ClassHooks;
|
||||
|
||||
public static void Hello() {
|
||||
|
||||
}
|
||||
|
||||
public static async Task<object> HandleClassHook(string className, string hookName, HttpRequest request, JsonElement body) {
|
||||
LCLogger.Debug($"Hook: {className}#{hookName}");
|
||||
LCLogger.Debug(body.ToString());
|
||||
|
||||
LCEngine.CheckHookKey(request);
|
||||
|
||||
string classHookName = GetClassHookName(className, hookName);
|
||||
if (ClassHooks.TryGetValue(classHookName, out MethodInfo mi)) {
|
||||
Dictionary<string, object> dict = LCEngine.Decode(body);
|
||||
|
||||
LCObjectData objectData = LCObjectData.Decode(dict["object"] as Dictionary<string, object>);
|
||||
objectData.ClassName = className;
|
||||
LCObject obj = LCObject.Create(className);
|
||||
obj.Merge(objectData);
|
||||
|
||||
LCUser user = null;
|
||||
if (dict.TryGetValue("user", out object userObj) &&
|
||||
userObj != null) {
|
||||
user = new LCUser();
|
||||
user.Merge(LCObjectData.Decode(userObj as Dictionary<string, object>));
|
||||
}
|
||||
|
||||
LCClassHookRequest req = new LCClassHookRequest {
|
||||
Object = obj,
|
||||
CurrentUser = user
|
||||
};
|
||||
|
||||
LCObject result = await LCEngine.Invoke(mi, req) as LCObject;
|
||||
if (result != null) {
|
||||
return LCCloud.Encode(result);
|
||||
}
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
private static string GetClassHookName(string className, string hookName) {
|
||||
switch (hookName) {
|
||||
case "beforeSave":
|
||||
return $"__before_save_for_{className}";
|
||||
case "afterSave":
|
||||
return $"__after_save_for_{className}";
|
||||
case "beforeUpdate":
|
||||
return $"__before_update_for_{className}";
|
||||
case "afterUpdate":
|
||||
return $"__after_update_for_{className}";
|
||||
case "beforeDelete":
|
||||
return $"__before_delete_for_{className}";
|
||||
case "afterDelete":
|
||||
return $"__after_delete_for_{className}";
|
||||
default:
|
||||
throw new Exception($"Error hook name: {hookName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using LeanCloud.Storage.Internal.Codec;
|
||||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public class LCFunctionHandler {
|
||||
private static Dictionary<string, MethodInfo> Functions => LCEngine.Functions;
|
||||
|
||||
/// <summary>
|
||||
/// 云函数
|
||||
/// </summary>
|
||||
/// <param name="funcName"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="body"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<object> HandleRun(string funcName, HttpRequest request, JsonElement body) {
|
||||
LCLogger.Debug($"Run: {funcName}");
|
||||
LCLogger.Debug(body.ToString());
|
||||
|
||||
if (Functions.TryGetValue(funcName, out MethodInfo mi)) {
|
||||
LCUser currentUser = null;
|
||||
if (request.Headers.TryGetValue("x-lc-session", out StringValues session)) {
|
||||
currentUser = await LCUser.BecomeWithSessionToken(session);
|
||||
}
|
||||
LCCloudFunctionRequest req = new LCCloudFunctionRequest {
|
||||
Meta = new LCCloudFunctionRequestMeta {
|
||||
RemoteAddress = LCEngine.GetIP(request)
|
||||
},
|
||||
Params = LCEngine.Decode(body),
|
||||
SessionToken = session.ToString(),
|
||||
User = currentUser
|
||||
};
|
||||
object result = await LCEngine.Invoke(mi, req);
|
||||
if (result != null) {
|
||||
return new Dictionary<string, object> {
|
||||
{ "result", result }
|
||||
};
|
||||
}
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RPC
|
||||
/// </summary>
|
||||
/// <param name="funcName"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="body"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<object> HandleRPC(string funcName, HttpRequest request, JsonElement body) {
|
||||
LCLogger.Debug($"RPC: {funcName}");
|
||||
LCLogger.Debug(body.ToString());
|
||||
|
||||
if (Functions.TryGetValue(funcName, out MethodInfo mi)) {
|
||||
LCUser currentUser = null;
|
||||
if (request.Headers.TryGetValue("x-lc-session", out StringValues session)) {
|
||||
currentUser = await LCUser.BecomeWithSessionToken(session);
|
||||
}
|
||||
LCCloudRPCRequest req = new LCCloudRPCRequest {
|
||||
Meta = new LCCloudFunctionRequestMeta {
|
||||
RemoteAddress = LCEngine.GetIP(request)
|
||||
},
|
||||
Params = LCDecoder.Decode(LCEngine.Decode(body)),
|
||||
SessionToken = session.ToString(),
|
||||
User = currentUser
|
||||
};
|
||||
object result = await LCEngine.Invoke(mi, req);
|
||||
if (result != null) {
|
||||
return new Dictionary<string, object> {
|
||||
{ "result", LCCloud.Encode(result) }
|
||||
};
|
||||
}
|
||||
}
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public class LCPingHandler {
|
||||
public static object HandlePing() {
|
||||
LCLogger.Debug("Ping ~~~");
|
||||
return new Dictionary<string, string> {
|
||||
{ "runtime", "dotnet" },
|
||||
{ "version", LCApplication.SDKVersion }
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using LeanCloud.Storage.Internal.Object;
|
||||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public class LCUserHookHandler {
|
||||
private static Dictionary<string, MethodInfo> UserHooks => LCEngine.UserHooks;
|
||||
|
||||
public static async Task<object> HandleVerifiedSMS(HttpRequest request, JsonElement body) {
|
||||
LCLogger.Debug(LCEngine.OnSMSVerified);
|
||||
LCLogger.Debug(body.ToString());
|
||||
|
||||
LCEngine.CheckHookKey(request);
|
||||
|
||||
if (UserHooks.TryGetValue(LCEngine.OnSMSVerified, out MethodInfo mi)) {
|
||||
Dictionary<string, object> dict = LCEngine.Decode(body);
|
||||
return await Invoke(mi, dict);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public static async Task<object> HandleVerifiedEmail(HttpRequest request, JsonElement body) {
|
||||
LCLogger.Debug(LCEngine.OnEmailVerified);
|
||||
LCLogger.Debug(body.ToString());
|
||||
|
||||
LCEngine.CheckHookKey(request);
|
||||
|
||||
if (UserHooks.TryGetValue(LCEngine.OnEmailVerified, out MethodInfo mi)) {
|
||||
Dictionary<string, object> dict = LCEngine.Decode(body);
|
||||
return await Invoke(mi, dict);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public static async Task<object> HandleLogin(HttpRequest request, JsonElement body) {
|
||||
LCLogger.Debug(LCEngine.OnLogin);
|
||||
LCLogger.Debug(body.ToString());
|
||||
|
||||
LCEngine.CheckHookKey(request);
|
||||
|
||||
if (UserHooks.TryGetValue(LCEngine.OnLogin, out MethodInfo mi)) {
|
||||
Dictionary<string, object> dict = LCEngine.Decode(body);
|
||||
return await Invoke(mi, dict);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
private static async Task<object> Invoke(MethodInfo mi, Dictionary<string, object> dict) {
|
||||
LCObjectData objectData = LCObjectData.Decode(dict["object"] as Dictionary<string, object>);
|
||||
objectData.ClassName = "_User";
|
||||
|
||||
LCObject obj = LCObject.Create("_User");
|
||||
obj.Merge(objectData);
|
||||
|
||||
LCUserHookRequest req = new LCUserHookRequest {
|
||||
CurrentUser = obj as LCUser
|
||||
};
|
||||
|
||||
return await LCEngine.Invoke(mi, req) as LCObject;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using LeanCloud.Common;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public class LCEngine {
|
||||
const string LCMasterKeyName = "x-avoscloud-master-key";
|
||||
const string LCHookKeyName = "x-lc-hook-key";
|
||||
|
||||
const string BeforeSave = "__before_save_for_";
|
||||
const string AfterSave = "__after_save_for_";
|
||||
const string BeforeUpdate = "__before_update_for_";
|
||||
const string AfterUpdate = "__after_update_for_";
|
||||
const string BeforeDelete = "__before_delete_for_";
|
||||
const string AfterDelete = "__after_delete_for_";
|
||||
|
||||
internal const string OnSMSVerified = "__on_verified_sms";
|
||||
internal const string OnEmailVerified = "__on_verified_email";
|
||||
internal const string OnLogin = "__on_login__User";
|
||||
|
||||
const string ClientOnline = "_clientOnline";
|
||||
const string ClientOffline = "_clientOffline";
|
||||
|
||||
const string MessageSent = "_messageSent";
|
||||
const string MessageReceived = "_messageReceived";
|
||||
const string ReceiversOffline = "_receiversOffline";
|
||||
const string MessageUpdate = "_messageUpdate";
|
||||
|
||||
const string ConversationStart = "_conversationStart";
|
||||
const string ConversationStarted = "_conversationStarted";
|
||||
const string ConversationAdd = "_conversationAdd";
|
||||
const string ConversationAdded = "_conversationAdded";
|
||||
const string ConversationRemove = "_conversationRemove";
|
||||
const string ConversationRemoved = "_conversationRemoved";
|
||||
const string ConversationUpdate = "_conversationUpdate";
|
||||
|
||||
public static Dictionary<string, MethodInfo> Functions = new Dictionary<string, MethodInfo>();
|
||||
public static Dictionary<string, MethodInfo> ClassHooks = new Dictionary<string, MethodInfo>();
|
||||
public static Dictionary<string, MethodInfo> UserHooks = new Dictionary<string, MethodInfo>();
|
||||
|
||||
public static void Initialize() {
|
||||
// 获取环境变量
|
||||
LCLogger.Debug("-------------------------------------------------");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_ID");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_KEY");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_MASTER_KEY");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_HOOK_KEY");
|
||||
PrintEnvironmentVar("LEANCLOUD_API_SERVER");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_PROD");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_ENV");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_INSTANCE");
|
||||
PrintEnvironmentVar("LEANCLOUD_REGION");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_ID");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_DOMAIN");
|
||||
PrintEnvironmentVar("LEANCLOUD_APP_PORT");
|
||||
LCLogger.Debug("-------------------------------------------------");
|
||||
|
||||
LCApplication.Initialize(Environment.GetEnvironmentVariable("LEANCLOUD_APP_ID"),
|
||||
Environment.GetEnvironmentVariable("LEANCLOUD_APP_KEY"),
|
||||
Environment.GetEnvironmentVariable("LEANCLOUD_API_SERVER"));
|
||||
|
||||
Assembly assembly = Assembly.GetCallingAssembly();
|
||||
ClassHooks = assembly.GetTypes()
|
||||
.SelectMany(t => t.GetMethods())
|
||||
.Where(m => m.GetCustomAttribute<LCEngineObjectHookAttribute>() != null)
|
||||
.ToDictionary(mi => {
|
||||
LCEngineObjectHookAttribute attr = mi.GetCustomAttribute<LCEngineObjectHookAttribute>();
|
||||
switch (attr.HookType) {
|
||||
case LCEngineObjectHookType.BeforeSave:
|
||||
return $"{BeforeSave}{attr.ClassName}";
|
||||
case LCEngineObjectHookType.AfterSave:
|
||||
return $"{AfterSave}{attr.ClassName}";
|
||||
case LCEngineObjectHookType.BeforeUpdate:
|
||||
return $"{BeforeUpdate}{attr.ClassName}";
|
||||
case LCEngineObjectHookType.AfterUpdate:
|
||||
return $"{AfterUpdate}{attr.ClassName}";
|
||||
case LCEngineObjectHookType.BeforeDelete:
|
||||
return $"{BeforeDelete}{attr.ClassName}";
|
||||
case LCEngineObjectHookType.AfterDelete:
|
||||
return $"{AfterDelete}{attr.ClassName}";
|
||||
default:
|
||||
throw new Exception($"Error hook type: {attr.HookType}");
|
||||
}
|
||||
});
|
||||
|
||||
UserHooks = assembly.GetTypes()
|
||||
.SelectMany(t => t.GetMethods())
|
||||
.Where(m => m.GetCustomAttribute<LCEngineUserHookAttribute>() != null)
|
||||
.ToDictionary(mi => {
|
||||
LCEngineUserHookAttribute attr = mi.GetCustomAttribute<LCEngineUserHookAttribute>();
|
||||
switch (attr.HookType) {
|
||||
case LCEngineUserHookType.SMS:
|
||||
return OnSMSVerified;
|
||||
case LCEngineUserHookType.Email:
|
||||
return OnEmailVerified;
|
||||
case LCEngineUserHookType.OnLogin:
|
||||
return OnLogin;
|
||||
default:
|
||||
throw new Exception($"Error hook type: {attr.HookType}");
|
||||
}
|
||||
});
|
||||
|
||||
Functions = assembly.GetTypes()
|
||||
.SelectMany(t => t.GetMethods())
|
||||
.Where(m => m.GetCustomAttribute<LCEngineFunctionAttribute>() != null)
|
||||
.ToDictionary(mi => mi.GetCustomAttribute<LCEngineFunctionAttribute>().FunctionName);
|
||||
|
||||
assembly.GetTypes()
|
||||
.SelectMany(t => t.GetMethods())
|
||||
.Where(m => m.GetCustomAttribute<LCEngineRealtimeHookAttribute>() != null)
|
||||
.ToDictionary(mi => {
|
||||
LCEngineRealtimeHookAttribute attr = mi.GetCustomAttribute<LCEngineRealtimeHookAttribute>();
|
||||
switch (attr.HookType) {
|
||||
case LCEngineRealtimeHookType.ClientOnline:
|
||||
return ClientOnline;
|
||||
case LCEngineRealtimeHookType.ClientOffline:
|
||||
return ClientOffline;
|
||||
case LCEngineRealtimeHookType.MessageSent:
|
||||
return MessageSent;
|
||||
case LCEngineRealtimeHookType.MessageReceived:
|
||||
return MessageReceived;
|
||||
case LCEngineRealtimeHookType.ReceiversOffline:
|
||||
return ReceiversOffline;
|
||||
case LCEngineRealtimeHookType.MessageUpdate:
|
||||
return MessageUpdate;
|
||||
case LCEngineRealtimeHookType.ConversationStart:
|
||||
return ConversationStart;
|
||||
case LCEngineRealtimeHookType.ConversationStarted:
|
||||
return ConversationStarted;
|
||||
case LCEngineRealtimeHookType.ConversationAdd:
|
||||
return ConversationAdd;
|
||||
case LCEngineRealtimeHookType.ConversationAdded:
|
||||
return ConversationAdded;
|
||||
case LCEngineRealtimeHookType.ConversationRemove:
|
||||
return ConversationRemove;
|
||||
case LCEngineRealtimeHookType.ConversationRemoved:
|
||||
return ConversationRemoved;
|
||||
case LCEngineRealtimeHookType.ConversationUpdate:
|
||||
return ConversationUpdate;
|
||||
default:
|
||||
throw new Exception($"Error hook type: {attr.HookType}");
|
||||
}
|
||||
})
|
||||
.ToList()
|
||||
.ForEach(item => {
|
||||
Functions.TryAdd(item.Key, item.Value);
|
||||
});
|
||||
}
|
||||
|
||||
public static void PrintEnvironmentVar(string key) {
|
||||
LCLogger.Debug($"{key} : {Environment.GetEnvironmentVariable(key)}");
|
||||
}
|
||||
|
||||
internal static async Task<object> Invoke(MethodInfo mi, object request) {
|
||||
try {
|
||||
object[] ps = new object[] { request };
|
||||
if (mi.ReturnType == typeof(Task) ||
|
||||
(mi.ReturnType.IsGenericType && mi.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))) {
|
||||
Task task = mi.Invoke(null, ps) as Task;
|
||||
await task;
|
||||
return task.GetType().GetProperty("Result")?.GetValue(task);
|
||||
}
|
||||
return mi.Invoke(null, ps);
|
||||
} catch (TargetInvocationException e) {
|
||||
throw e.InnerException;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Dictionary<string, object> Decode(JsonElement jsonElement) {
|
||||
string json = System.Text.Json.JsonSerializer.Serialize(jsonElement);
|
||||
Dictionary<string, object> dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(json,
|
||||
LCJsonConverter.Default);
|
||||
return dict;
|
||||
}
|
||||
|
||||
internal static string GetIP(HttpRequest request) {
|
||||
if (request.Headers.TryGetValue("x-real-ip", out StringValues ip)) {
|
||||
return ip.ToString();
|
||||
}
|
||||
if (request.Headers.TryGetValue("x-forwarded-for", out StringValues forward)) {
|
||||
return forward.ToString();
|
||||
}
|
||||
return request.HttpContext.Connection.RemoteIpAddress.ToString();
|
||||
}
|
||||
|
||||
internal static void CheckMasterKey(HttpRequest request) {
|
||||
if (!request.Headers.TryGetValue(LCMasterKeyName, out StringValues masterKey)) {
|
||||
throw new Exception("No master key");
|
||||
}
|
||||
if (!masterKey.Equals(Environment.GetEnvironmentVariable("LEANCLOUD_APP_MASTER_KEY"))) {
|
||||
throw new Exception("Mismatch master key");
|
||||
}
|
||||
}
|
||||
|
||||
internal static void CheckHookKey(HttpRequest request) {
|
||||
if (!request.Headers.TryGetValue(LCHookKeyName, out StringValues hookKey)) {
|
||||
throw new Exception("No hook key");
|
||||
}
|
||||
if (!hookKey.Equals(Environment.GetEnvironmentVariable("LEANCLOUD_APP_HOOK_KEY"))) {
|
||||
throw new Exception("Mismatch hook key");
|
||||
}
|
||||
}
|
||||
|
||||
public static object GetFunctions(HttpRequest request) {
|
||||
CheckMasterKey(request);
|
||||
|
||||
List<string> functions = new List<string>();
|
||||
functions.AddRange(Functions.Keys);
|
||||
functions.AddRange(ClassHooks.Keys);
|
||||
functions.AddRange(UserHooks.Keys);
|
||||
foreach (string func in functions) {
|
||||
LCLogger.Debug(func);
|
||||
}
|
||||
|
||||
return new Dictionary<string, List<string>> {
|
||||
{ "result", functions }
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public class LCClassHookRequest {
|
||||
public LCObject Object {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public LCUser CurrentUser {
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using System.Collections.Generic;
|
||||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public class LCCloudFunctionRequestMeta {
|
||||
public string RemoteAddress {
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
public class LCCloudFunctionRequest {
|
||||
public LCCloudFunctionRequestMeta Meta {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> Params {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public LCUser User {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string SessionToken {
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public class LCCloudRPCRequest {
|
||||
public LCCloudFunctionRequestMeta Meta {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public object Params {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public LCUser User {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string SessionToken {
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Engine {
|
||||
public class LCUserHookRequest {
|
||||
public LCUser CurrentUser {
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue