public static JObject CSharpTest(RPCRequestInfo c, JObject p) { Thread.Sleep ((int)p ["ms"].AsNumber (0.0)); return new JObject { { "hello", "world" } }; }
protected virtual void CheckPermissions(RPCRequestInfo ri, ActionInvokeDetails d) { string[] demand = d.PermissionDemand; if (info.Sector == "main" && (ri.ActionInfo.Flags & RPCActionFlags.NoAuth) == 0) { // non-noauth actions in the main sector get permission demands from DB demand = Ticket.GetActionPrivilegeDemand (ri.ActionInfo.Name); if (demand == null) throw new RPCException ("authz", "action not configured: {0}", ri.ActionInfo.Name); } ri.EffectiveTicket = Ticket.Verify (ri.RequestHeader ["ticket"].AsString (null)); if (demand != null) { if (ri.EffectiveTicket == null) throw new RPCException ("authn", "valid authn ticket required for accessing core services"); foreach (string p in demand) if (!ri.EffectiveTicket.HasPrivilege (p)) throw new RPCException ("authz", "access denied: need priv {0} for {1}", p, ri.ActionInfo.Name); } ri.TerminalToken = ri.RequestHeader ["terminal"].AsString (null); ri.RealTicket = Ticket.Verify (ri.RequestHeader ["identifying_token"].AsString (null)) ?? ri.EffectiveTicket; uint cid; if (ri.RealTicket != null && ri.RealTicket.ClientID != 0) { ri.ClientID = ri.RealTicket.ClientID; } else if ((cid = (uint)ri.RequestHeader["client_id"].AsNumber(0)) != 0) { ri.ClientID = cid; } }
protected virtual void OnMessage(Message req, Action <Message> rpy) { req.Consume(1000000, (header, data, dlen, error) => { RPCRequestInfo ri = new RPCRequestInfo { RequestHeader = header, RequestData = data, RequestDataLength = dlen, RequestError = error, ResponseHeader = new JObject(), ResponseData = new byte[0], }; wq.Enqueue(() => { try { Execute(ri); } catch (Exception ex) { Logger.LogError("{0} Exception: {1}", ri.ActionInfo == null ? "(action not yet determined)" : ri.ActionInfo.Name.ToString(), ex); var rpcex = RPCException.Wrap(ex); ri.ResponseHeader ["error_code"] = rpcex.ErrorCode; ri.ResponseHeader ["error"] = rpcex.ErrorMessage; ri.ResponseHeader ["error_data"] = rpcex.ErrorData; } Message.StreamToCallback(rpy, ri.ResponseHeader, ri.ResponseData); }); }); }
protected virtual void Execute(RPCRequestInfo ri) { if (ri.RequestError != null) { throw new RPCException("transport", "Failed to receive request body: {0}", ri.RequestError); } string q = info.Sector + ':' + ri.RequestHeader["action"].AsString("") + '~' + ri.RequestHeader["version"].AsString("1"); ActionName acname; ActionName.TryParse(q, out acname); if (acname == null) { throw new RPCException("transport", "No valid action name in request"); } ActionInfo ai = info.LookupAction(acname); if (ai == null || ai.Name != acname) { throw new RPCException("transport", "No such action"); } ri.ActionInfo = ai; ActionInvokeDetails d = (ActionInvokeDetails)ai.Handler; JObject reqData = null; try { reqData = JSON.Parse(Encoding.UTF8.GetString(ri.RequestData, 0, ri.RequestDataLength)).AsObject(); } catch (Exception) { } if (reqData == null) { throw new RPCException("transport", "Failed to parse JSON request body"); } CheckPermissions(ri, d); Logger.LogInfo("Request {0}", ri.ActionInfo); JObject resData = d.Handler(ri, reqData); ri.ResponseData = Encoding.UTF8.GetBytes(JSON.Stringify(resData)); }
protected virtual void CheckPermissions(RPCRequestInfo ri, ActionInvokeDetails d) { string[] demand = d.PermissionDemand; if (info.Sector == "main" && (ri.ActionInfo.Flags & RPCActionFlags.NoAuth) == 0) { // non-noauth actions in the main sector get permission demands from DB demand = Ticket.GetActionPrivilegeDemand(ri.ActionInfo.Name); if (demand == null) { throw new RPCException("authz", "action not configured: {0}", ri.ActionInfo.Name); } } ri.EffectiveTicket = Ticket.Verify(ri.RequestHeader ["ticket"].AsString(null)); if (demand != null) { if (ri.EffectiveTicket == null) { throw new RPCException("authn", "valid authn ticket required for accessing core services"); } foreach (string p in demand) { if (!ri.EffectiveTicket.HasPrivilege(p)) { throw new RPCException("authz", "access denied: need priv {0} for {1}", p, ri.ActionInfo.Name); } } } ri.TerminalToken = ri.RequestHeader ["terminal"].AsString(null); ri.RealTicket = Ticket.Verify(ri.RequestHeader ["identifying_token"].AsString(null)) ?? ri.EffectiveTicket; uint cid; if (ri.RealTicket != null && ri.RealTicket.ClientID != 0) { ri.ClientID = ri.RealTicket.ClientID; } else if ((cid = (uint)ri.RequestHeader["client_id"].AsNumber(0)) != 0) { ri.ClientID = cid; } }
protected virtual void Execute(RPCRequestInfo ri) { if (ri.RequestError != null) throw new RPCException ("transport", "Failed to receive request body: {0}", ri.RequestError); string q = info.Sector + ':' + ri.RequestHeader["action"].AsString("") + '~' + ri.RequestHeader["version"].AsString("1"); ActionName acname; ActionName.TryParse (q, out acname); if (acname == null) throw new RPCException ("transport", "No valid action name in request"); ActionInfo ai = info.LookupAction (acname); if (ai == null || ai.Name != acname) throw new RPCException ("transport", "No such action"); ri.ActionInfo = ai; ActionInvokeDetails d = (ActionInvokeDetails)ai.Handler; JObject reqData = null; try { reqData = JSON.Parse (Encoding.UTF8.GetString (ri.RequestData, 0, ri.RequestDataLength)).AsObject(); } catch (Exception) { } if (reqData == null) throw new RPCException ("transport", "Failed to parse JSON request body"); CheckPermissions (ri, d); Logger.LogInfo ("Request {0}", ri.ActionInfo); JObject resData = d.Handler (ri, reqData); ri.ResponseData = Encoding.UTF8.GetBytes (JSON.Stringify (resData)); }
protected virtual void OnMessage(Message req, Action<Message> rpy) { req.Consume (1000000, (header, data, dlen, error) => { RPCRequestInfo ri = new RPCRequestInfo { RequestHeader = header, RequestData = data, RequestDataLength = dlen, RequestError = error, ResponseHeader = new JObject (), ResponseData = new byte[0], }; wq.Enqueue (() => { try { Execute (ri); } catch (Exception ex) { Logger.LogError ("{0} Exception: {1}", ri.ActionInfo == null ? "(action not yet determined)" : ri.ActionInfo.Name.ToString (), ex); var rpcex = RPCException.Wrap (ex); ri.ResponseHeader ["error_code"] = rpcex.ErrorCode; ri.ResponseHeader ["error"] = rpcex.ErrorMessage; ri.ResponseHeader ["error_data"] = rpcex.ErrorData; } Message.StreamToCallback (rpy, ri.ResponseHeader, ri.ResponseData); }); }); }