I'm using Mandrill to send emails, and I defined $m in itinializer:
$m = Mandrill::API.new 'XmylongkeygoeshereTg'
I need to test a function that send an email, so I need to stub the $m.messages.send method somehow on that existing object. I read that stub_chain is a messy way to achieve that, but even that didn't work. Another way I tried was with allow($m.messages).to like that:
it "sends emails to a group" do
# stub Mandril's email sending, so no actual emails will be sent.
allow($m.messages).to receive(:send) { nil }
expect(subject.my_sending_emails_method).to be_true
end
While there's no error, there's also no effect of stubbing - the emails are still being sent.
Please suggest how to stub it?
There might be more than one answer, but what I found working is:
allow($m).to receive_message_chain(:messages, :send) { nil }
Related
I know I can use a Request guard. However, if I have a REST API with hundreds of handlers, not only it would be annoying to have to add an extra function param to all of them, but it kinda scares me that it could be easy to miss adding such a param here or there and therefore create a security hole. That's why I'd like to know if there is a way to do such a validation globally.
The documentation on Fairings mentions they can be used for global security policies:
As a general rule of thumb, only globally applicable actions should be implemented via fairings. For instance, you should not use a fairing to implement authentication or authorization (preferring to use a request guard instead) unless the authentication or authorization applies to the entire application. On the other hand, you should use a fairing to record timing and/or usage statistics or to implement global security policies.
But at the same time the docs on the on_request() callback say this:
A request callback can modify the request at will and Data::peek() into the incoming data. It may not, however, abort or respond directly to the request; these issues are better handled via request guards or via response callbacks.
So how am I supposed to return an error to the user in the case of an invalid token for example?
OK, I think I found a way...
First we create a "dummy" handler like this:
#[put("/errHnd", format = "json")]
fn err_handler() -> ApiResult {
// Here simply return an error
}
Then we attach a fairing like this:
rocket::custom(cfg)
.attach(AdHoc::on_request("OnReq", |req, _| {
// Here we validate the token and if it's not OK,
// forward the request to our "dummy" handler:
let u = Origin::parse("/errHnd").unwrap();
req.set_uri(u);
req.set_method(Method::Put);
}))
.mount("/", routes![err_handler, ...
I'm not sure that's the best way to do it, but I tested it and it seems to work. I'm open to other suggestions.
P.S. It may also be worth mentioning that if we wanted to have an exception, so as to skip the validation in the fairing, say, based on the URL, we could simply add something like this in it:
if req.uri().path() == "/let-me-in-please" {
return;
}
I am trying to implement a pub/sub broker with ZeroMQ where it is possible to restrict clients from subscribing to prefixes they are not allowed to subscribe to. I found a tutorial that tries to achieve a similar thing using the ZMQ_XPUB_MANUAL option. With zeromq.js it is possible to set this option:
import * as zmq from "zeromq";
// ...
const socket = new zmq.XPublisher({ manual: true });
After setting this option I am able to receive the subscription messages by calling .receive() on this socket:
const [msg] = await socket.receive();
But I have no Idea how to accept this subscription. Usally this is done by calling setSockOpt with ZMQ_SUBSCRIBE but I don't know how to do this with zeromq.js.
Is there a way to call setSockOpt with zeromq.js or is there another way to accept a subscription?
Edit
I tried user3666197's suggestion to call setSockOpt directly, but I am not sure how to do this. Rather than doing that, I took another look in the sources and found this: https://github.com/zeromq/zeromq.js/blob/master/src/native.ts#L617
It seems like setSockOpt is exposed to the TypeScript side as protected methods of the Socket class. To try this out, I created my own class that inherits XPublisher and exposed an acceptSubscription message:
class CustomPublisher extends zmq.XPublisher {
constructor(options?: zmq.SocketOptions<zmq.XPublisher>) {
super(options);
}
public acceptSubscription(subscription: string | null): void {
// ZMQ_SUBSCRIBE has a value of 6
// reference:
// https://github.com/zeromq/libzmq/blob/master/include/zmq.h#L310
this.setStringOption(6, subscription);
}
}
This works like a charm! But do not forget to strip the first byte of the subscription messages, otherwise your client won't receive any messages since the prefix won't match.
Q : "Is there a way to call setSockOpt() with zeromq.js or is there another way to accept a subscription?"
So, let me first mention Somdoron to be, out of doubts & for ages, a master of the ZeroMQ tooling.
Next comes the issue. The GitHub-sources, I was able to review atm, seem to me, that permit the ZMQ_XPUB-Socket-archetypes to process the native API ZMQ_XPUB_MANUAL settings ( re-dressed into manual-property, an idiomatic shift ), yet present no method (so far visible for me) to actually permit user to meet the native API explicit protocol of:
ZMQ_XPUB_MANUAL: change the subscription handling to manual...with manual mode subscription requests are not added to the subscription list. To add subscription the user need to call setsockopt() with ZMQ_SUBSCRIBE on XPUB socket./__ from ZeroMQ native API v.4.3.2 documentation __/
Trying to blind-call the Socket-inherited .SetSockOpt() method may prove me wrong, yet if successful, it may be a way to inject the { ZMQ_SUBSCRIBE | ZMQ_UNSUBSCRIBE } subscription-management steps into the XPUB-instance currently having been switched into the ZMQ_XPUB_MANUAL-mode.
Please test it, and if it fails to work via this super-class inherited method, the shortest remedy would be to claim that collision/conceptual-shortcomings directly to the zeromq.js maintainers ( it might be a W.I.P. item, deeper in their actual v6+ refactoring backlog, so my fingers are crossed for either case ).
I have some general questions, I start of on page main.ts
Via onInit I am grabbing data from a mongoose database server, which I save in an array.
This array needs to be available in other components. The way I do this right now, which seems to work, by using a service.ts
In the service I have a lot BehaviorSubjects and Subjects. So whenever I get the array data from mongoose I send a message to the service, and the other components subscribe to that message.
I am sometimes using Subject instead of BehaviorSubject because it throws error messages as in HTML I am using *ngFor and it expects an array, not a string 'default message'.
I am just wondering if this is a correct setup to move data between pages.
Right now I am also using this message system for updates on my component.
So if someone makes a comment or post on my website I send a message to my service which in turn updates an observable and my component subscribes again to that.
Are there better ways to update my site for new data and is there an easy way to explain why sometimes I get this error message from *ngFor and in other cases it doesn't throw this error whilst still using *ngFor.
i.e. when I update an observable will the component receive the message straight away or will it receive onInit.
With that also the question if it is best practice to use the below in the constructor of the component or the onInit.
I unsubscribe OnDestroy.
this.newService.currentMessageComment
.takeWhile(() => this.alive)
.subscribe(message => {
service.ts
public messageSourceMarketCap = new BehaviorSubject<any>('default message');
currentMessageMarketCap = this.messageSourceMarketCap.asObservable();
public messageSourceHistory = new Subject<any>();
currentMessageHistory = this.messageSourceHistory.asObservable();
public messageSouceApi = new BehaviorSubject<any>('default message');
currentMessageApi = this.messageSouceApi.asObservable();
public messageSourceBody = new BehaviorSubject<any>('default message');
currentMessageBody = this.messageSourceBody.asObservable();
Why are you using BehaviouSubject. I think in your case Subject will be better. BehaviouSubject fits in case when you want to pass a initial value while creating observable.
You can also quick fix by emiting an empty array as ngFor expects an array. Change from "default message" to [].
Hope it will help
I am new to Kamailio 4.3.1 and I am trying to use it as described on this http://kb.asipto.com/kamailio:k43-async-sip-routing-nodejs page. Apparently it is a new approach to make asynchronous routing using NodeJS.
I've modified a little bit the example and adapted it with a REGISTER sip and it works quite good. But now I am looking for a way to make the things a little bit more complex.
In the example the NodeJS routine is called only when the REGISTER method has been received. I am trying to make a similar asynchronous call to NodeJS when the '200 OK' comes back from the REGISTERS's destination.
If we have:
Alice---REGISTER(Alice)---> Kamailio (async call to NodeJs)---REGISTER(Alice)-->Asterisk
Later when Asterisk accepts the REGISTER the I want to have this:
Alice<---200 OK---Kamailio(async call to NodeJS)<---200 OK---Asterisk
To catch the 200 OK, I configured Kamailio to execute an async call using EVAPI, like this:
request_route
{
....
route(REGISTRAR);
....
exit;
}
route[REGISTRAR]
{
...
t_on_reply("2OO_OK_RSP"); # Here I tell that I want to catch the "200 OK"
...
exit;
}
# When the 200 OK arrives, this code is called
onreply_route[2OO_OK_RSP]
{
# Here is my async call to NodeJS
evapi_async_relay("send message to NodeJS about 200 OK");
}
#When NodeJS returns
event_route[evapi:message-received]
{
if(200 OK)
{
t_countinue("..", "...", RSP_200OK)
}
}
route[RSP_200OK]
{
t_on_branch("MANAGE_BRANCH");
t_on_failure("MANAGE_FAILURE");
route(RELAY); # I am trying here to relay the 200 OK, which finishes by calling t_relay();
exit;
}
So this is my configuration which is treating the 200 OK. I would like to say that it works (because at the end the 200 Ok is relayed to Alice) BUT Kamailio logs this message:
tm [tm.c:1479]: _w_t_relay_to(): ERROR: w_t_relay_to: unsupported route type: 4
and I don't like this. I know that there is something wrong and when I am looking at the source code of Kamailio it is clear that this is not the right place to treat messages like "200 OK".
My question is, is there any other way (a good way) to relay/route the 200 OK, once the NodeJS has replied? I tried also with
t_reply("200","OK"); instead of t_relay();
But this generates a SIP message "200 OK" which does not contain everything that the messages received by Asterisk. Probably I can tell Kamailio to reply by exactly the same 200 OK, that it has just received?
Thank you in advance!
Best regards,
Anton
So finally I could find how to resolve partially my problem.
I discovered that the module EVAPI proposes a method called evapi_relay() which does not suspend the current transaction but sends a messages to the NodeJS application and relays the SIP messages immediately.
I says that this resolves my problem partially because however I am still not able to make the whole procedure with suspending the transaction (without the Kamailio error).
In my case, it is not so important, but I imagine that in some cases the problem will persist.
Anton
From EVAPI module documentation: After evapi_async_relay() returns true, no relaying should happen in request_route(), it should be followed by exit.
Relay the event data given as parameter to connected applications. Before evaluating the parameter, the request processing is suspended using tm module (using the t_suspend()/t_continue() framework). The routing of the SIP request can be continued once event_route[evapi:message-received] is triggered. After evapi_async_relay() returns true, no relaying should happen in request_route(), it should be followed by exit;.
I'm using ajax requests to get one of PartialViews in my project. I want to pass a message by INotifier.
Cuttently i'm using HttpStatusCodeResult return new HttpStatusCodeResult(204, "Message");to pass informations about the errors but is not satisfying solution.
$(this).load($(this).attr("href"), function (response, status, xhr) {
if (xhr.status == 204) {
// show message
}
});
I'm wondering that is possible by using standard INotifier.Error() in ActionResult.
Nope. The default notifier is not suitable for AJAX requests. What it does, it queues notifications inside a temporary collection. Queued notifications are then written to the client when request ends - pushed into Layout.Messages zone.
In your case it would be best to implement your own INotifier that would follow the required logic. It's a very simple interface to implement so it's not actually that much work.
I needn't to implement INotifier, i only placed in my PartialView this:
#Display(WorkContext.Layout.Zones["Messages"])
Now the message isn't rendered in main zone (in Layout.cshtml of used theme), but could be placed anywhere in your PartialView, for example under the affected table.