I can't seem to find how to connect to the TFS EventService SOAP, I think I should make a service which gets called by TFS with stuff as parameters with which I can work with...
But I'm not finding anything like that on the internet.
The only thing I've found is this: http://msdn.microsoft.com/en-us/magazine/cc507647.aspx
Which seems old and deprecated.
I'm using tfs2012 and vs2012.
#Edit: The idea is to hook up to the WorkItemStatusChange and to the CheckIn events.
I use an interface for my services (same for TFS2010 and TFS2012)
using System.ServiceModel;
using System.ServiceModel.Web;
namespace TFS_Event_Services
{
[ServiceContract(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
public interface ITFS_Event_Services
{
[OperationContract(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify")]
[XmlSerializerFormat(Style = OperationFormatStyle.Document)]
[WebInvoke(Method="Notify")]
void Notify(string eventXml, string tfsIdentityXml);
}
}
So my .svc looks like this:
namespace TFS_Event_Services
{
public class TFS_Event_Services_2012 : ITFS_Event_Services
{
public void Notify(string eventXml, string tfsIdentityXml)
{
//do something with the Event
}
}
}
The .svc markup:
<%# ServiceHost Language="C#" Debug="true" Service="TFS_Event_Services.TFS_Event_Services_2012" CodeBehind="TFS_Event_Services_2012.svc.cs" %>
After creating your web service you need to publish it on some IIS which is the target of TFS alert soap call, of course.
Related
I'm trying to use Sustainsys.Saml2 and Sustainsys.Saml2.AspNetCore2 library provided by this saml2 library to implement both IDP initiated and SP initiated scenarios.
After referring sample appliation things I did so far:
1. Refer latest Sustainsys.Saml2.AspNetCore2 and Sustainsys.Saml2 via nuget
2. Modified Startup.cs to add new options
3. Created MVC controller with ACS end point
Things I'm trying to understand:
1. Do I need to Initiated Saml2Handler so that I can hit HandleRequestAsync() end point of library.
2. How to retrive principal/claims
3. For sp initiated case when end point identifies request is not authenticated how to redirect request to IDP?
ConfigureServices method in startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication()
.AddSaml2(options =>
{
options.SPOptions.EntityId = new EntityId("https://localhost:3131/Saml2");
options.IdentityProviders.Add(
new IdentityProvider(
new EntityId("http://localhost:52071/Metadata"), options.SPOptions)
{
LoadMetadata = true
});
options.SPOptions.ServiceCertificates.Add(new X509Certificate2("Sustainsys.Saml2.Tests.pfx"));
});
}
**SSO Controller**
[Authorize(AuthenticationSchemes = "Saml2")]
public class SsoController : Controller
{
public SingleSignOnController(ILogger logger)
{
}
[Route("saml2/ACS")]
[HttpPost]
public ActionResult ACS()
{
try
{
// Is request authenticated here by library?
// I tried hitting this end point from stud idp portal, but it is
throwing " MVC Exception Handler: The method or operation is not implemented. at Sustainsys.Saml2.AspNetCore2.Saml2Handler.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService"
}
catch (Exception e)
{
}
}
}
Do I need to create/implement Custom Saml2Handler and inject it in SSo controller? I could not find exact end point in this ASPNETSAMPLE project for saml2/ACS?
What I'm missing ?
The Acs endpoint is built into the handler. Remove your SsoController.
Check the asp.net core sample applications in the repo for an example on how to configure. The AspNetCore2 package contains a handler that works the same as any other external authentication handler for Asp.NET Core. You initiate the sign in sequence by an authentication challenge.
I'm currently trying out ServiceStack Logging with Slack, and altough it seems to work, I can't change the channels and name of the bot. I think it might have something to do with my Slack configuration, but since I didn't really use Slack before, I'm not sure how to set it up.
My logging config looks like this:
public override void Configure(Funq.Container container)
{
LogManager.LogFactory = new SlackLogFactory("https://hooks.slack.com/services/[...]", debugEnabled: true)
{
DefaultChannel = "logs",
ErrorChannel = "errorlogs",
BotUsername = "ServiceStack Logger"
};
SetConfig(new HostConfig
{
DefaultContentType = MimeTypes.Json
});
}
So, the logging works, but the username is not set correctly (instead, it's the apps name) and it only posts to the channel I specified when creating the WebHook. What do I need to adjust?
Edit: I access the logger like this:
public static ILog Log = LogManager.GetLogger(typeof(BroadcastService));
public object Get(ConnectionTest request) {
Log.Info(String.Format("Info Logged: {0}", DateTime.Now.ToShortTimeString()));
// ...
}
When using the ServiceStack Slack logger, to enable channel overrides, it needs to be used with an Incoming Web Hook.
https://api.slack.com/incoming-webhooks
As Slack API docs state, if the integration is trying to work with a Slack App, these overrides will be ignored.
I want a custom attribute to be fired automatically without writing that on the web api method.
What is the way I can achieve that?
Let us say for example you have an action filter attribute
public class MyApiActionFilterAttribute : FilterAttribute {
//...
}
With that you can assign it to the class or action depending on how you want it to be used
public class MyApiController : ApiController {
[MyApiActionFilter]
public IHttpActionResult MyAction() {
return Ok();
}
}
This applies to this action only.
But, if you wanted it to be applied on all actions (globally) within the web API, you would need to add it to the configuration.
GlobalConfiguration.Configuration.Filters.Add(new MyApiActionFilterAttribute ());
This is normally done at startup web configuring the web API.
Note that in doing the above, the filter will be applied to all requests.
I would like to configure my project to not allow http requests with the following restrictions:
It must be a global restriction for all APIs (via web.config, script in the installer, etc.)
It must be hard coded(not pressing "Require SSL" on the APP in the IIS)
No "redirect"- just return error (403)
my ideal option would be to configure "Require SSL" by a script which runs in the installer.
This can be accomplished by writing a simple ActionFilter that inspects the request and responds when the scheme is not set to ssl. A very minimal implementation may look something like:
public class RequireHttpsAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
}
}
To make this apply everywhere, you'll likely want to register it as a global filter in the WebAPI configuration when your application is bootstrapping. That would look something like:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new RequireHttpsAttribute());
// ... More configuration ...
}
}
If you search the web a bit, you can find many examples of similar filters with more robust logic that may better meet your needs.
I'm trying to have signalR hub as part of a plugin using MEF. But after calling ImportMany on a List<> object and then adding the catalog/container/ComposeParts part in the Application_Start() method of the Global.asax file, all I get is :
Uncaught TypeError: Cannot read property 'server' of undefined.
I've got no clue if the problem comes from my interface, the plugin, the global.asax file, or the javascript.
The interface:
public interface IPlugin
{
}
the plugin:
[Export(typeof(IPlugin))]
[HubName("testHub")]
public class TestHub : Hub, IPlugin
{
public string Message()
{
return "Hello World!";
}
}
in the Global.asax file:
[ImportMany(typeof (IPlugin))]
private IEnumerable<IPlugin> _plugins { get; set; }
protected void Application_Start()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(#"./Plugins"));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
RouteTable.Routes.MapHubs();
//log4net
log4net.Config.XmlConfigurator.Configure();
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
and finally the javascript:
$(document).ready(function () {
$.connection.hub.url = 'http://127.0.0.1/signalr/';
var proxy = $.connection.testHub;
$.connection.hub.start({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] })
.done(function () {
proxy.invoke('Message').done(function(res) {
alert(res);
});
})
.fail(function () { alert("Could not Connect!"); });
});
the only information I've found was this post but I could not make it work. everything works fine when I add the reference manually, but when I have a look at "signalr/hubs" after loading the plugin, then there is not reference to my hub's method.
Thanks a lot for your help.
Your problem is that SignalR caches the generated "signalr/hubs" proxy script the first time it is requested. SignalR provides the cached script in response every subsequent request to "signalr/hubs".
SignalR not only caches the script itself, but it also caches the collection of Hubs it finds at the start of the process.
You can work around the cached proxy script issue by simply not using the proxy script, but that still won't enable you to actually connect to Hubs defined in assemblies that are loaded after the process starts.
If you want to be able to connect to such Hubs, you will need to implement your own IHubDescriptorProvider that is aware of Hubs defined in plugins loaded at runtime.
You can register your provider with SignalR's DependencyResolver which can be passed into SignalR via the Resolver property of the HubConfiguration object you pass into MapSignalR.
That said, it would probably be easier to restart the app pool/server process whenever a plugin is added to the "./Plugins" directory.