YouTrackSharp: can't get it to work - c#

Trying to open an issue from a C# app.
Few issues:
1) UPDATE: I realize it only supports .NET Standard 1.3 = Framework 4.6; So no issue here.
2) I install version 2.0.31 (and less) - When I try to set up a connection, it says "Method not allowed":
var connection = new Connection("xxxx.myjetbrains.com", 80, false, "youtrack");
connection.Authenticate("xxxxx", "xxxxxx");
var issueManagement = new IssueManagement(connection);
dynamic issue = new Issue();
issue.Assignee = "xxxxx";
issue.ProjectShortName = "CV";
issue.Type = "Bug";
issue.Summary = "Test";
issue.Description = "Testing 1 2 3 ...";
issueManagement.CreateIssue(issue);
connection.Authenticate throws the error.
3) If I don't specify other parameters in Connection and leave only the basic url, I get the following error (again in connection.Authenticate):
For security reasons DTD is prohibited in this XML document. To enable
DTD processing set the DtdProcessing property on XmlReaderSettings to
Parse and pass the settings into XmlReader.Create method.
Can't seem to find much info on this online. Anyone has any idea what to do?

the 1.3 refers to .NETStandard - NOT .Net Framework. These are not the same thing.
You need .Net Framework 4.6 or up for .Net Standard 1.3 compatibility.
See here:
https://learn.microsoft.com/en-us/dotnet/standard/net-standard
I'd go directly to jetbrains for the other parts...

For anyone else getting stuck:
my YouTrack account was like this:
https://mycompanyname.myjetbrains.com/youtrack
Since it uses SSL (i.e. https) I had to mark the SSL parameter true instead of false, and mark port 443 instead of 80. Also I had to add the "youtrack" as a parameter. So the end result looks like this:
var connection = new Connection("xxxx.myjetbrains.com", 443, true, "youtrack");
connection.Authenticate("xxxx#xxxx.xxx", "xxxx");
I only had to do this in v.2, as I mentioned, v.3.0.0+ has working examples in their blog.

Related

Why is my gremlin.net gremlin client not working with azure cosmos graph db

I've set up a serverless azure cosmos graph db account and now I'm trying to connect to it using the following code:
.AddSingleton(s =>
{
var connectionPool = new ConnectionPoolSettings
{
MaxInProcessPerConnection = 32,
PoolSize = 4,
ReconnectionAttempts = 4,
ReconnectionBaseDelay = TimeSpan.FromSeconds(1)
};
var server = new GremlinServer("<project-name>.documents.azure.com", 443, true, "/dbs/<DatabaseName>/colls/<GraphName>", "<primary key>");
return new GremlinClient(server, connectionPoolSettings: connectionPool);
})
The GremlinClient throws an Exception with the message
The server returned status code '200' when status code '101' was expected.
I'm using Gremlin.Net 3.6.0 with NET 6
Any ideas?
If you were connecting well with earlier versions of Gremlin.Net you might want to revert. According to their website their supported version is 3.4.6. While later versions along 3.4.x might work, it might require more configuration (like, I think you might have to switch the serializer as I dont think CosmosDB supports the GraphBinary serializer) and you'd have to take care to not use certain features that newer versions of TinkerPop have that 3.4.6 did not.
The issue was resolved by changing the uri from
<project-name>.documents.azure.com
to
<project-name>.gremlin.cosmosdb.azure.com
https://learn.microsoft.com/en-us/azure/cosmos-db/graph/gremlin-api-faq#why-am-i-getting-the--websocketexception--the-server-returned-status-code--200--when-status-code--101--was-expected--error-

Convert a Kerberos based WindowsIdentity into a Base64 string

If I have the following code:
var token = System.Security.Principal.WindowsIdentity.GetCurrent();
I get a WindowsIdentity that is Kerberos based. I need to make a call with a header like this:
Authorize: Negotiate <Kerberos Token Here>
Is there a way to convert that token object into a Base64 string?
As the maintainer of the Kerberos.NET as mentioned in the other answer, you can always go that route. However, if you want SSO using the currently signed in Windows identity you have to go through Windows' SSPI stack.
Many .NET clients already support this natively using Windows Integrated auth, its just a matter of finding the correct knobs. It's unclear what client you're using so I can't offer any suggestions beyond that.
However if this is a custom client you have to call into SSPI directly. There's a handful of really good answers for explaining how to do that such as: Client-server authentication - using SSPI?.
The aforementioned Kerberos.NET library does have a small wrapper around SSPI: https://github.com/dotnet/Kerberos.NET/blob/develop/Kerberos.NET/Win32/SspiContext.cs
It's pretty trivial:
using (var context = new SspiContext($"host/yourremoteserver.com", "Negotiate"))
{
var tokenBytes = context.RequestToken();
var header = "Negotiate " + Convert.ToBase64String(tokenBytes);
...
}
I could not get this to work, but I was able to get a token using the excellent Kerberos.NET NuGet package. With that I was able to get it like this:
var client = new KerberosClient();
var kerbCred = new KerberosPasswordCredential("UserName", "p#ssword", "domain");
await client.Authenticate(kerbCred);
Console.WriteLine(client.UserPrincipalName);
var ticket = await client.GetServiceTicket("http/ServerThatWantsTheKerberosTicket.domain.net");
return Convert.ToBase64String(ticket.EncodeGssApi().ToArray());
As an aside, I needed help figuring out what the SPN value was for the GetServiceTicket and the project maintainer was fantastically helpful (and fast!).

Cannot connect to Azure ServiceBus with Microsoft.Azure.ServiceBus

I have created a very simple console application that connects to Azure ServiceBus and sends one message. I tried the latest library from Microsoft (Microsoft.Azure.ServiceBus) but no matter what I do I just get this error:
No connection could be made because the target machine actively
refused it ErrorCode: ConnectionRefused
I have tried exactly the same connection string in Service Bus Explorer and it does work just fine. Moreover I connected without problems using the older library from Microsoft (WindowsAzure.ServiceBus).
var sender = new MessageSender("endpoint", "topicName");
sender.SendAsync(new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject("test"))));
I tried with .NET Framework 4.6.2 and Core, same exception. I suspect there may be some differences in the default protocol that these libraries use, but I could not figure out that for sure.
P.S. Have tried the example from Microsoft docs but result is still the same exception
The old client supported ConnectivityMode using TCP, HTTP, HTTPS, and AutoDetect. ServiceBus Explorer is using AutoDetect, trying TCP first and then failing over to HTTPS, regardless of the TransportMode you were using (SBMP or AMQP).
With the new client this has changed. TransportMode now combines both options and offers Amqp (AMQP over TCP) or AmqpWebSockets (AMQP over WebSockets). There's no AutoDetect mode. You will have to create your clients and specify TransportType as AmqpWebSockets to bypass blocked TCP port 5671 and instead use port 443.
It seems that the documentation is lacking a lot on how to connect using HTTPS (Amqp over WebSockets) but after some help from Sean Feldman in the accepted answer I managed to connect. Here is the code that I used if someone is interested:
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
"RootManageSharedAccessKey", // SharedAccessKeyName
"SomeToken");
var sender = new MessageSender(
"sb://mydomain.servicebus.windows.net/",
"topicName",
tokenProvider,
TransportType.AmqpWebSockets);
Or a variant that let's you have the whole connection string in one piece
var builder = new ServiceBusConnectionStringBuilder("YouConnectionString");
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
builder.SasKeyName,
builder.SasKey);
var sender = new MessageSender(
builder.Endpoint,
"TopicName",
tokenProvider,
TransportType.AmqpWebSockets);
It is actually possible to use ConnectionString directly but then it has to be augmented to use the right protocol.
var sender = new MessageSender("TransportType=AmqpWebSockets;Endpoint=...", "TopicName")
Or the version that allows to embed EntityPath into the ConnectionString
var connectionBuilder = new ServiceBusConnectionStringBuilder("EntityPath=MyTopic;TransportType=AmqpWebSockets;Endpoint=...")
var sender = new MessageSender(connectionBuilder);
I was having the same issue but his worked for me
var clientOptions = new ServiceBusClientOptions();
clientOptions.TransportType = ServiceBusTransportType.AmqpWebSockets;
client = new ServiceBusClient(connectionString, clientOptions);
sender = client.CreateSender(topicName);
// create a batch
using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

VersionOne: Getting message that VersionOneAPIConnector is obsolete and I should use V1Connector instead. But how?

I am trying to upgrade my c# programs to VersionOne.SDK.API version 15.3.0.0. I am getting a message that VersionOneAPIConnector is obsolete and that I should use V1Connector instead. When the ObjectModel API was discontinued, I had changed to doing everything with VersionOneAPIConnector using query.v1 (using HttpPost) and rest-1.v1/Data(using SendData). After getting the new version, I figured out how to use V1Connector and pass it to Services and then to use ExecutePassThroughQuery() to pass what had been the 2nd argument to HttpPost for my query.v1 code like this:
Original code:
Stream resultStream = _cx.HttpPost("/query.v1", System.Text.Encoding.UTF8.GetBytes(GetQueryForMembers()));
using (StreamReader reader = new StreamReader(resultStream, Encoding.UTF8))
{
result = reader.ReadToEnd();
}
New Code:
result = _service.ExecutePassThroughQuery(GetQueryForMembers());
Where GetQueryforMembers() is:
public static string GetQueryForMembers()
{
return #"
from: Member
select:
- Email
where:
AssetState: Active";
}
But, I can't figure out how to use V1Connector/IServices for my rest/SendData code. All the Rest examples on the VersionOne site now show using it from the API Console, not from stand-alone code. It looks like at least some of the things I was doing with Rest can be done via Services.executeOperation() or Services.Meta, but the V1 employee that I was working with to get rid of my Object Model code a few years ago had recommended only using the API for the connection and to otherwise use Rest and Query, so that I didn't have to worry about compatibility with .NET versions. But, from looking at the examples currently provided and the functionality available on the V1Connector/IServices classes, it looks like maybe V1 wants us to use Meta API rather than REST now? Or is there a way to use REST directly that I am missing? From looking at the source, I see there is an internal UseDataAPI() on the V1Connector that IServices uses. But, it only uses it in Save, ExecuteOperation and Retrieve and it doesn't look like any of those do what I'm trying to do.
This is an example, if what I was doing before with REST (where _passed_cx is a VersionOneAPIConnector)
string newDefect = string.Concat("<Asset href=\"/MentorG01/rest-1.v1/New/Defect\">",
"<Attribute name=\"Name\" act=\"set\">", cdata_attribute_value, "</Attribute>",
"<Relation name=\"Scope\" act=\"set\">",
"<Asset href=\"/MentorG01/rest-1.v1/Data/Scope/", project_oid.Split(':')[1], "\" idref=\"", project_oid, "\" />",
"</Relation>",
"</Asset>");
string url = "rest-1.v1/Data/Defect";
Stream resultStream = _passed_cx.SendData(url, newDefect);
Anyone know how to use rest-1.v1 with V1Connector? If so, can you provide an example?

Retrieving Profiles and connections - Parameter missing?

I use Google's .NET people API (v.1.25) and follow the documentation (https://developers.google.com/people/v1/read-people).
Under
Retrieve Profiles and Connections
Get the user's connections
for .NET the documentation gives this example code snippet:
PeopleResource.ConnectionsResource.ListRequest peopleRequest =
peopleService.People.Connections.List("people/me");
peopleRequest.PersonFields = "names,emailAddresses";
ListConnectionsResponse connectionsResponse = peopleRequest.Execute();
IList<Person> connections = connectionsResponse.Connections;
But PersonFields do not exist in the class ListRequest - nor does it exist in GetRequest as the doc suggests in the next example.
Do I misunderstand something or is there a fault in the docs or in the API?
It seems like you are using an old version of the library. If you browse the .NET documentation from the Install Client Libraries page it shows the version is 1.5.1.
If you browse to the ConnectionsResource.ListRequest documentation it shows that PersonFields exists.
Just use .Fields instead of .PersonFields. Also I had to declare the entire package name (Google.Apis.People.v1.). Example below.
Google.Apis.People.v1.People.PeopleService peopleService;
Google.Apis.People.v1.PeopleResource.ConnectionsResource.ListRequest peopleRequest = peopleService.People.Connections.List("people/me");
peopleRequest.Fields = "names,emailAddresses";
ListConnectionsResponse connectionsResponse = peopleRequest.Execute();
IList<Google.Apis.People.v1.Data.Person> connections = connectionsResponse.Connections;
Hope this helps.

Categories