how to pass 2 or more arguments to Hubot - coffeescript

I'm trying to make hubot work with powershell.
Hubot listens to the command (get service 'servicename' in this example), parces input and sends it to powershell.
module.exports = (robot) ->
robot.respond /get service (.*)$/i, (msg) ->
serviceName = msg.match[1]
psObject = {
serviceName: serviceName
}
callPowerShell = (psObject, msg)
This code works fine with one argument, but I don't know how to pass two arguments to hubot, for example, servicename and compname (get service 'servicename' 'compname').

You should add one more brackets (.*) in respond or listen command.
You can add as many as you wish, and also you can add brackets inside brackets.
Just count them from the left and count them as 1st, 2nd ... and so on.
module.exports = (robot) ->
robot.respond /get service (.*) (.*)$/i, (msg) ->
serviceName = msg.match[1]
paramTwo = msg.match[2]

Related

How to redirect requests to another host using ZAP?

I'm new to ZAP and I don't know much about it's js/ecma scripting.
Basically, I was trying to redirect request to another host.
Say an application that is connected to the ZAP proxy makes a request in a URL:
http://www.somesite.com/path/to/a/file
but I want to change the hostname in the URL to:
another.site.com
so it will actually request to: http://www.anothersite.com/path/to/a/file
Here's the code that I was trying to work but the URL remains unchanged in the request.
function proxyRequest(msg) {
// Debugging can be done using println like this
var uri = msg.getRequestHeader().getURI().toString()
var host = msg.getRequestHeader().getURI().getHost().toString()
print('proxyResponse called for url=' + uri)
if (host == 'download.qt.io') {
uri = uri.replace('download.qt.io/online/', 'mirrors.ocf.berkeley.edu/qt/online/')
msg.getRequestHeader().setHeader('Location', uri)
print('proxyRequest changed to url=' + uri)
}
if (host == 'ftp.jaist.ac.jp') {
uri = uri.replace('ftp.jaist.ac.jp/pub/qtproject/online/', 'mirrors.ocf.berkeley.edu/qt/online/')
msg.getRequestHeader().setHeader('Location', uri)
print('proxyRequest changed to url=' + uri)
}
if (host == 'qtproject.mirror.liquidtelecom.com') {
uri = uri.replace('qtproject.mirror.liquidtelecom.com/online/', 'mirrors.ocf.berkeley.edu/qt/online/')
msg.getRequestHeader().setHeader('Location', uri)
print('proxyRequest changed to url=' + uri)
}
return true
}
Option 1: Replacer Rule
Install the Replacer addon, from the marketplace:
Goto the Tools menu and select 'Replacer Options'.
Setup a rule as shown in the following screenshot.
Save/Okay as appropriate.
Now when your browse etc all your traffic will be redirected/rewritten.
Option 2: HttpSender Script
Create a new HttpSender script, similar to the following example:
function sendingRequest(msg, initiator, helper) {
var host = msg.getRequestHeader().getURI().getHost();
if (host.equals("www.somesite.com")) {
uri = msg.getRequestHeader().getURI();
uri.setEscapedAuthority("www.anothersite.com");
msg.getRequestHeader().setURI(uri);
}
return msg;
}
function responseReceived(msg, initiator, helper) {}
Option 3: Hosts File Entry
Goto a command prompt and nslookup www.somesite.com, note the IP address (w.x.y.z).
In your hosts file, add an entry associating the noted IP (w.x.y.z) with www.anothersite.com.
(You may need to restart ZAP/browsers for this change to take effect. On linux you'll likely need to sudo to edit the file, on Windows you'll need to edit it as an admin user.)
(Further details WRT editing your hosts file: https://www.howtogeek.com/howto/27350/beginner-geek-how-to-edit-your-hosts-file/)

ejabberd - custom iq handlers

I have created simple module. here is the code
-module(mod_conversations).
-behaviour(gen_mod).
-export([start/2, stop/1, process_local_iq/3]).
-include("ejabberd.hrl").
-include("logger.hrl").
-include("jlib.hrl").
-define(IQ_CUSTOM, <<"jabber:iq:conversations">>).
start(Host, _) ->
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?IQ_CUSTOM, ?MODULE, process_local_iq, one_queue),
ok.
stop(Host) ->
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?IQ_CUSTOM),
ok.
process_local_iq(From,_ ,IQ) ->
IQ#iq{type = result, sub_el = [{xmlelement, <<"value">>, [], [{xmlcdata, <<"Testing...">>}]}]}.
When i make request with strophe.js var iq = $iq({type: 'get', to: 'some host'}).c('query', {xmlns: 'jabber:iq:conversations'}); connection.sendIQ(iq);
server disconnects me.I have tried to find simillar issues but some of them was more problematic. please help me to solve this issue
You must not use xmlelement tuples in recent ejabberd versions, the correct code should look like this:
IQ#iq{type = result,
sub_el = [#xmlel{name = <<"value">>,
children = [{xmlcdata, <<"Testing...">>}]}]}.

Spring cloud eureka client to multiple eureka servers

I am able to get the eureka server to operate in a peer to peer mode. But one thing I am curious about is how do I get a service discovery client to register to multiple eureka servers.
My use case is this:
Say I have a service registering to one of the eureka servers (e.g. server A) and that registration is replicated to its peer. The service is actually pointing at server A. If server A goes down, and the client expects to renew with server A, how do the renewal work if server A is no longer present.
Do I need to register with both and if not then how does the renewal happen if the client cannot communicate with server A. Does it have some knowledge of server B (from its initial and/or subsequent comms with A) and fail over to do its registration renewal there? That is not clear in any of the docs and I need to verify
So based on the answer, I added the following to my application.yml
eureka:
# these are settings for the client that gets services
client:
# enable these two settings if you want discovery to work
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://localhost:8762/eureka/, http://localhost:8761/eureka/
It only registers to the first in the comma separated list. If I switch them around the registration flips between eureka servers.
I can see that it does separate these based on comma but my guess is that Eureka does not use this underneath (from EurekaClientConfigBean.java)
#Override
public List<String> getEurekaServerServiceUrls(String myZone) {
String serviceUrls = this.serviceUrl.get(myZone);
if (serviceUrls == null || serviceUrls.isEmpty()) {
serviceUrls = this.serviceUrl.get(DEFAULT_ZONE);
}
if (serviceUrls != null) {
return Arrays.asList(serviceUrls.split(","));
}
return new ArrayList<>();
}
I just reviewed the source code for Eureka 1.1.147. It works differently that i expected but at least I know now.
You can put multiple service urls in the set
serviceUrl:
defaultZone: http://localhost:8762/eureka/, http://localhost:8761/eureka/
But the register action only uses the first one to register. There remaining are used only if attempting to contact the first fails.
from (DiscoveryClient.java)
/**
* Register with the eureka service by making the appropriate REST call.
*/
void register() {
logger.info(PREFIX + appPathIdentifier + ": registering service...");
ClientResponse response = null;
try {
response = makeRemoteCall(Action.Register);
isRegisteredWithDiscovery = true;
logger.info(PREFIX + appPathIdentifier + " - registration status: "
+ (response != null ? response.getStatus() : "not sent"));
} catch (Throwable e) {
logger.error(PREFIX + appPathIdentifier + " - registration failed"
+ e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
}
}
which calls
private ClientResponse makeRemoteCall(Action action) throws Throwable {
return makeRemoteCall(action, 0);
}
It only calls the backup when an exception is thrown in the above makeRemoteCall(action, 0) call
} catch (Throwable t) {
closeResponse(response);
String msg = "Can't get a response from " + serviceUrl + urlPath;
if (eurekaServiceUrls.get().size() > (++serviceUrlIndex)) {
logger.warn(msg, t);
logger.warn("Trying backup: " + eurekaServiceUrls.get().get(serviceUrlIndex));
SERVER_RETRY_COUNTER.increment();
return makeRemoteCall(action, serviceUrlIndex);
} else {
ALL_SERVER_FAILURE_COUNT.increment();
logger.error(
msg
+ "\nCan't contact any eureka nodes - possibly a security group issue?",
t);
throw t;
}
So you can't really register to two eureka servers simultaneously from this code. Unless I missed something.
Your client application should be provided a list of Eureka URLs. The URLs are comma separated.
Yes, as per the documentation, the flow is:
client registers to the first available eureka server
registrant information is replicated between eureka server nodes.
So multiple registration is not only not needed but should be avioded.
Please add below property in application.property or application.yml file
eureka.client.service-url.defaultZone = http://localhost:8761/eureka,http://localhost:8762/eureka
Services will be registered with both eureka server.If one eureka server is down then request will be served from other eureka server.
If you want to a workaround to register on multiple eureka servers.
please review my answer on similar question: https://stackoverflow.com/a/60714917/7982168

Get Domain from URL in PowerShell

I'm looking to strip out the domain in this scenario using PowerShell. What is the most effective method to get example.com out of the following variable?
$URL = "http://www.example.com/folder/"
(some sort of regex command here to convert/strip $URL into $DOMAIN using PowerShell)
$DOMAIN = "example.com" #<-- taken from $URL
I've searched and I've found results for finding the IP address from a domain but I need to establish what the domain is first using regex (or another method).
Try the URI class:
PS> [System.Uri]"http://www.example.com/folder/"
AbsolutePath : /folder/
AbsoluteUri : http://www.example.com/folder/
LocalPath : /folder/
Authority : www.example.com
HostNameType : Dns
IsDefaultPort : True
IsFile : False
IsLoopback : False
PathAndQuery : /folder/
Segments : {/, folder/}
IsUnc : False
Host : www.example.com
Port : 80
Query :
Fragment :
Scheme : http
OriginalString : http://www.example.com/folder/
DnsSafeHost : www.example.com
IsAbsoluteUri : True
UserEscaped : False
UserInfo :
And remove the www prefix:
PS> ([System.Uri]"http://www.example.com/folder/").Host -replace '^www\.'
example.com
Like this:
PS C:\ps> [uri]$URL = "http://www.example.com/folder/"
PS C:\ps> $domain = $url.Authority -replace '^www\.'
PS C:\ps> $domain
example.com
For properly calculating the sub-domain, the trick is you need to know the second to last period. Then you take a substring of that second to last period (or none if it is only one .) to the final position by subtracting the location of second period (or 0) from total length of domain. This will return the proper domain-only and will work regardless of how many sub-domains are nested under the TLD:
$domain.substring((($domain.substring(0,$domain.lastindexof("."))).lastindexof(".")+1),$domain.length-(($domain.substring(0,$domain.lastindexof("."))).lastindexof(".")+1))
Also note that System URI itself is valid 99% of the time but I'm parsing my IIS logs and finding that with VERY long (often invalid/malicious requests) URIs it does not properly parse and fails those.
I have this in function form as:
Function Get-DomainFromURL {
<#
.SYNOPSIS
Takes string URL and returns domain only
.DESCRIPTION
Takes string URL and returns domain only
.PARAMETER URL
URL to parse for domain
.NOTES
Author: Dane Kantner 9/16/2016
#>
[CmdletBinding()]
param(
[Alias("URI")][parameter(Mandatory=$True,ValueFromPipeline=$True)][string] $URL
)
try { $URL=([System.URI]$URL).host }
catch { write-error "Error parsing URL"}
return $URL.substring((($URL.substring(0,$URL.lastindexof("."))).lastindexof(".")+1),$URL.length-(($URL.substring(0,$URL.lastindexof("."))).lastindexof(".")+1))
}

How to test a Controller which relies on an ngResource Service

I have a controller which relies on a service built through ngResource. I am having trouble testing this(although both appear to work like a charm in the actual application). The following is the (sanitized) Controller
MyApp.Controller.MyCarsController = (scope, http, typeService) ->
if scope.context==undefined
scope.ferrari_or_porshe =""
scope.id = ""
else if scope.context=="ferrari"
scope.country_or_pi ="Ferrari"
else if scope.context=="porshe"
scope.country_or_pi ="Porshe"
typeService.index
ferrari_or_porshe: scope.ferrari_or_porshe
id: scope.id
, (response) ->
scope.type = response
scope.loading = false
MyApp.Controller.MyCarsController.$inject = ['$scope', '$http', 'Type']
And this is the Service:
MyApp.MyModule.factory 'Type', ['$resource', ($resource) ->
TypeResource = $resource("/api/types/:ferrari_or_porshe/:id", {},
index:
method: "GET"
isArray: true
)
return TypeResource
]
Finally, some test code:
describe 'MyApp.Controller.MyCarsController', ->
beforeEach module('MyModule')
beforeEach inject ($rootScope, $http, $controller, Type) ->
#scope = $rootScope.$new()
#typeService = Type
#scope.context = undefined
$controller 'MyApp.Controller.MyCarsController', $scope: #scope
describe '#home-page', ->
it 'contains a list of types', ->
expect(#scope.types.length).toBeGreaterThan 0
it "sets instance variables correctly", ->
expect(#scope.ferrari_or_porshe).toBe ""
expect(#scope.id).toBe ""
Which fails with:
No more request expected in helpers/angular-mocks.js on line 889
TypeError: 'undefined' is not an object (evaluating 'this.scope.types.length') in controllers/my_cars_controller_spec.js
By judicious application of console.logs, I have discovered that the issue is that the final callback on response is never reached. TypeResource comes back as [Function].
My questions is:
How do I drive the Jasmine Tests to correctly enter the Service and fetch a response? And is there any way to create direct Unit Tests for Services?
Any and all help is appreciated
The Solution is as follows: for the Service, use $httpBackend which is bundled as part of ngMock:
http://code.google.com/p/google-drive-sdk-samples/source/browse/ruby/app/lib/angular-1.0.0/angular-mocks-1.0.0.js?r=c43c943e32be395b7abca8150deb301d3cbc0dbe
Use this to mock the Rest responses. Since in my case I only cared about verifying that a GET request goes out:
describe 'Type', ->
describe '#index', ->
beforeEach module('MyModule')
beforeEach inject(($httpBackend) ->
$httpBackend.whenGET('/api/types/ferrari/1').respond([])
)
it 'for a ferrari scope', inject((Type) ->
ferrari_or_porsche = 'ferrari'
id = '1'
expect( Type.index('ferrari_or_porsche': ferrari_or_porsche, 'id': id) ).toEqual([ ])
)
And then for the controller, mock the service using jasmine spies and use jasmine.any(Function) to warn of the callback.
describe 'MyApp.Controller.MyCarsController', ->
beforeEach module('myModule')
beforeEach inject ($rootScope, $http, $controller, Type) ->
#scope = $rootScope.$new()
#typeService = Type
#scope.context = undefined
spyOn(#typeService, 'index')
describe '#home-page', ->
beforeEach inject ($controller) ->
$controller 'MyApp.Controller.MyCarsController', $scope: #scope
it 'contains a list of types', ->
expect(#typeService.index).toHaveBeenCalledWith({ ferrari_or_porsche : '', id : '' }, jasmine.any(Function))
it "sets instance variables correctly", ->
expect(#scope.ferrari_or_porsche).toBe ""
expect(#scope.id).toBe ""
Note: I make no claims as to the "canonicalness" of this solution. But it works.
Note: The API endpoints are of course tested extensively elsewhere.