Setup TeamCity with HTTPS

Posted: Monday, 02 July 2018 23:10 CEST in

At work we have recently moved our CI server and made it available without having to use VPN. As we did this switch we also made it accessible only thru HTTPS. Here are the steps we did to make that work.

First we copied out pfx file to the CI server, then we had to make a few adjustments to some of the config files.

In TeamCity/conf/server.xml we added this element, here you can see the path to the pfx file and the password for the file.

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
    SSLEnabled="true"
    scheme="https"
    secure="true"
    connectionTimeout="60000"
    redirectPort="8543"
    clientAuth="false"
    sslProtocol="TLS"
    useBodyEncodingForURI="true"
    keystoreFile="C:\TeamCity\conf\cert.pfx"
    keystorePass="password"
    socket.txBufSize="64000"
    socket.rxBufSize="64000"
    tcpNoDelay="1"
    /> 

After a restert of the TeamCity service it is now possible to reach the server on HTTPS.

The next step for us was to force the use of HTTPS, so we had to make a change to TeamCity/conf/web.xml. We added this XML to the file just before the web-app closing tag.

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Restricted URLs</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
</web-app>

After a restart we can still access TeamCity over HTTPS, but when using HTTP the redirect goes to HTTPS on port 8543. We open up TeamCity/conf/server.xml again and change one line in the HTTP connector. Here we change the redirectPort from 8543 to 443.

<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="60000"
               redirectPort="443"
               useBodyEncodingForURI="true"
               socket.txBufSize="64000"
               socket.rxBufSize="64000"
               tcpNoDelay="1"
    />

After another restart of the TeamCity service all is working as expected and our users is forced over on HTTPS.


Create an entity using the WebApi with lookup values

Posted: Friday, 27 October 2017 15:45 CEST in

When creating a new entity with the WebApi for Dynamics 365 the documentation looks pretty clear. It also looks straight forward when associating the new entity with an existing one. See here for a reference.

This example from the previous link creates an account and set the primary contact.

{
    "name":"Sample Account",
    "primarycontactid@odata.bind":"/contacts(e13072b3-81ba-e711-8108-5065f38ba391)"
}

When looking at the code one would think that it is the logicalname for the attribute that is in use here and we only need to append the @odata.bind part. But as soon we start to associate custom entities we will see that it is not the logicalname of the attribute but rather the associatednavigationproperty.

Here is the result querying the newly created account with prefer header set to odata.include-annotations=”*”

{
    "@odata.context": "https://someorg.api.crm4.dynamics.com/api/data/v8.2/$metadata#accounts(_primarycontactid_value)/$entity",
    "@odata.etag": "W/\"1434863\"",
    "_primarycontactid_value@OData.Community.Display.V1.FormattedValue": "Sebastian Holager",
    "_primarycontactid_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "primarycontactid",
    "_primarycontactid_value@Microsoft.Dynamics.CRM.lookuplogicalname": "contact",
    "_primarycontactid_value": "e13072b3-81ba-e711-8108-5065f38ba391",
    "accountid": "72bc7a32-82ba-e711-8108-5065f38ba391"
}

When querying with this prefer header we get to see the name of the associatednavigationproperty. In this example it’s not possible to conclude if it is the logicalname or the associatednavigationproperty that is used.

When setting a lookup on a custom attribute the associatednavigationproperty is set to the same as the schemaname, this is confusing because this is not the case on the standard lookup attributes as we saw on the primarycontactid example above. Schemaname for primarycontactid is PrimaryContactId.

Here is a example on a custom entity, notice the case-sensitivity. Here the associatednavigationproperty is equal to the schemaname of the attribute.

{
    "new_Testentitet@odata.bind": "/new_testentitets(0FB7A14C-8DBA-E711-810A-5065F38BD3C1)"
}

Now let’s look at a custom activity, then things really starts to be interesting.

In this example I will create a custom activity. Here is the body of the POST.

{
    "regardingobjectid_incident@odata.bind": "/incidents(5CD45010-6752-E711-80FA-5065F38BA391)",
    "crmntime_Case_crmntime_TimeEntry@odata.bind": "/incidents(5CD45010-6752-E711-80FA-5065F38BA391)",
    "crmntime_HourTypeMain_crmntime_TimeEntry@odata.bind": "/crmntime_hourtypes(2b645ea3-7352-e711-80fa-5065f38ba391)"
}

We associate the same incident in the custom crmntime_case attribute and the standard regardingobjectid attribute of an activity. We also associate an crmntime_hourtype that is a custom attribute referencing a custom entity.

This is the result when querying the newly created recored.

{
    "_regardingobjectid_value@OData.Community.Display.V1.FormattedValue": "Test",
    "_regardingobjectid_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "regardingobjectid_incident_crmntime_timeentry",
    "_regardingobjectid_value@Microsoft.Dynamics.CRM.lookuplogicalname": "incident",
    "_regardingobjectid_value": "5cd45010-6752-e711-80fa-5065f38ba391",
    "_crmntime_case_value@OData.Community.Display.V1.FormattedValue": "Test",
    "_crmntime_case_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "crmntime_Case_crmntime_TimeEntry",
    "_crmntime_case_value@Microsoft.Dynamics.CRM.lookuplogicalname": "incident",
    "_crmntime_case_value": "5cd45010-6752-e711-80fa-5065f38ba391",
    "_crmntime_hourtypemain_value@OData.Community.Display.V1.FormattedValue": "Test type",
    "_crmntime_hourtypemain_value@Microsoft.Dynamics.CRM.associatednavigationproperty": "crmntime_HourTypeMain_crmntime_TimeEntry",
    "_crmntime_hourtypemain_value@Microsoft.Dynamics.CRM.lookuplogicalname": "crmntime_hourtype",
    "_crmntime_hourtypemain_value": "2b645ea3-7352-e711-80fa-5065f38ba391"
}

When looking at this result we can see that regardingobjectid_incident is not the associatednavigationproperty, but using regardingobjectid_incident_crmntime_timeentry@odata.bind also work.

Notice that the associatednavigationproperty is case-sensitive and on custom relationships on custom activities it looks like it take the form of attribute schema name_entity schema name. In this example for the hourtypemain lookup the attribute schema name is crmntime_HourTypeMain and this lookup attribute exist on enity with schema name crmntime_TimeEntry so the associatednavigationproperty becomes crmntime_HourTypeMain_crmntime_TimeEntry. This is different from other custom lookup attributes on custom entities where the form of associatednavigationproperty is equal to schemaname of the attribute.

I hope these examples can help you out when exploring the Web Api and associating entities when creating and updating entities.


Building C# 7 with TeamCity

Posted: Thursday, 19 October 2017 14:30 CEST in

We have started using some new language features from C# 7 lately and then some builds on Team City started failing. Luckily I remembered my post from the time we started using C# 6 features. You can find that post here

error CS1003: Syntax error, ',' expected

The builds were using the Visual Studio sln build configuration and was set to Visual Studio 2015. I changed this to Visual Studio 2017, but then there was no compatible agent. I then installed the Build Tools for Visual Stuido 2017 and restarted the agents, now everything is working as expected.

You find the Build Tools for Visual Studio 2017 here. Scroll all the way to the bottom and you find the download link or just search for Build tools.


Accessing Dynamics 365 from Ubuntu

Posted: Sunday, 22 January 2017 13:00 CET in

From home when using Dynamics 365 on a Ubuntu machine I’m quite regularly getting the mobile forms when accessing Dynamics 365. So today I wanted to investigate this some more.

I start with Firefox and logged in to http://portal.office.com. When I click on the Dynamics 365 tile, I get an error on the new app page. Error message when using Firefox

When I close this dialog there is a blank page with portal menu on the top. Refreshing the page or pressing the sync button does not help.

I then try to go directly to my instance of Dynamics 365 with the url https://{organization}.crm4.dynamics.com. Then we are logged in to the mobile site.

So no luck with Firefox, let’s try Chrome.

When logging in to the portal with Chrome and clicking on the Dynamics 365 tile there is no error and I can see all my apps. Clicking on one of them I get to my organization.

If I type in the address to the organization as I tried with Firefox, I get the mobile site as I did with Firefox.

So to summarize I have to use Chrome and log in through portal.office.com or home.dynamics.com to avoid getting the mobile site of Dynamics 365 on a Ubuntu machine.


Setting up Pidgin for Skype for business

Posted: Sunday, 27 September 2015 17:49 CEST in

At work we use Skype for business, formerly known as Lync, for IM. That works fine at work where I use a Windows 10 machine. But sometimes I want to use Skype for business to chat with some colleagues from home. So I wanted to get a Skype for business client on my home machine running Ubuntu.

After a little bit of googling I found that there was a plugin for Pidgin called pidgin-sipe. So I install Pidgin and Pidgin-sipe with apt-get.

sudo apt-get install pidgin pidgin-sipe

Then I open Pidgin and add an account. On the basic tab I used these settings:

  • Protocol: Office Communicator
  • Username: My email
  • Password: My Password

On the advanced tab:

  • Connection type: Auto
  • Authentication scheme: TLS-DSK

When I’m connecting now, I get an error, saying unable to validate certificate. To fix this I go to this domain, download the certificate and put it in ~/.purple/certificates/x509/tls_peers/ It seems like it is important to name the certificate file the same as the domain, so I name the certificate file webext01.phonectuc.net Messagebox with error

Now I get the same error with another domain, I can see in the certificate’s alternative names section in the downloaded certificate, that this domain is listed there. So I only make a copy of the already downloaded certificate and rename it to the domain name.

And now I am able to login and chat with my colleagues. As of this writing I am using Pidgin 2.10.9 and Sipe 1.18.2


About Sebastian

Sebastian Holager

Sebastian Holager is a developer working at a CRM Norge in Oslo, Norway. At day time hacking away on Dynamcs CRM, C# and JavaScript. While at night playing around with other programming languages, reading and watching football.

Follow me on twitter