C# MSGraph SDK and ipNamedLocation - c#

I've been working on C# app to amend the ipaddress/s of a Named Location in conditional access in AAD.
I can authenticate and return the request collection. For whatever reason I cant access the isTrusted property or the ipRanges odata.
I can see the properties and the vales when I run through in debug, but cant output them.
I think its something to do with the list type, I'm using Microsoft.Graph.NamedLocation, there is Microsoft.Graph.IpNamedLocation type available but it can be converted from Microsoft.Graph.NamedLocation, which the api call makes.
The image shows what's available during runtime.
Code Below:
private static async Task GetnamedLocations(IConfidentialClientApplication app, string[] scopes)
{
GraphServiceClient graphServiceClient = GetAuthenticatedGraphClient(app, scopes);
var namedlocationsList = new List<Microsoft.Graph.NamedLocation>();
var namedLocations = await graphServiceClient.Identity.ConditionalAccess.NamedLocations
.Request()
.Filter("isof('microsoft.graph.ipNamedLocation')")
.GetAsync();
// var ipNamedLocations = new List<Microsoft.Graph.IpNamedLocation>();
namedlocationsList.AddRange(namedLocations.CurrentPage);
foreach (var namedLocation in namedlocationsList)
{
Console.WriteLine(namedLocation.Id + namedLocation.DisplayName + namedLocation.ODataType + namedLocation);
if (namedLocation.ODataType == "#microsoft.graph.ipNamedLocation")
{
Console.WriteLine("Write out all the properties");
}
}
Console.WriteLine(($"Named location: {namedLocations}"));
}
Any pointers gratefully received, I'm not a C# developer so be gentle :-)

You need to cast namedLocation to IpNamedLocation type.
foreach (var namedLocation in namedlocationsList)
{
Console.WriteLine(namedLocation.Id + namedLocation.DisplayName + namedLocation.ODataType + namedLocation);
if (namedLocation is IpNamedLocation ipNamedLocation)
{
var isTrusted = ipNamedLocation.IsTrusted;
var ipRanges = ipNamedLocation.IpRanges;
if (ipRanges is IEnumerable<IPv4CidrRange> ipv4cidrRanges)
{
foreach(var ipv4cidrRange in ipv4cidrRanges)
{
Console.WriteLine($"{ipv4cidrRange.CidrAddress}");
}
}
Console.WriteLine("Write out all the properties");
}
}

I couldn't get the updated answer to work, it still didn't evaluate the if statement to true, after a bit of googling and trying different options, the following returns the IP address, not sure if its the right way to go about it but it works.
var ipv4CidrRanges = ipRanges.Cast<IPv4CidrRange>().ToList();
foreach (var ipv4CidrRange in ipv4CidrRanges)
{
Console.WriteLine(ipv4CidrRange.CidrAddress);
}
Many thanks to user2250152 who solved the first conundrum for me.

Related

How to update a field in document in a firestore

Im trying to update a string field in specific document using Firebase Firestore for my android app but every method I see is while knowing the document refernce which I find difficult to find in my program.
Would like for some help for another method or help in finding the document refernce using a specific field value.
Thanks in advance.
(using C# btw)
private async Task<string> GetDocRefAsync(string userId)
{
Object obj = await FirestoreData.GetFirestore().Collection(DBConstants.FS_COLLECTION_USERS).
WhereEqualTo(DBConstants.FS_COLLECTION_USERS_USER_ID, userId).Get();
QuerySnapshot snapshot = (QuerySnapshot)obj;
if (snapshot.IsEmpty)
{
Log.Debug("UpdateGroupAsync", "userId: " + userId + " not found");
return null;
}
string docRef = "";
foreach (DocumentSnapshot item in snapshot.Documents)
{
//docRef = item.;
}
return docRef;
}
Firstly ive tried to find the document ref using this code but dont have a function to get the ref even after getting the correct document.
the fourth line from the bottom is where I couldnt find it.
database pic
this.groupCode = code;
string strUserRef = GetDocRefAsync(userRef).ToString();
DocumentReference docReference = database.Collection(DBConstants.FS_COLLECTION_USERS_GROUPS_CODE).Document(strUserRef);
docReference.Update(DBConstants.FS_COLLECTION_USERS_GROUPS_CODE, groupCode);
If you want to get the documents where a field has a given value, you can use a query. Then once the query returns, you can get documents IDs with the .Id field on each DocumentShapshot in the returned documents.
You will also need to add await for the returned value since it is an async method returning a Task<string> not returning a string.
private async Task<string> GetDocRefAsync(string userId) {
CollectionReference usersRef = FirestoreData.GetFirestore().Collection(DBConstants.FS_COLLECTION_USERS);
Query query = usersRef.WhereEqualTo(DBConstants.FS_COLLECTION_USERS_USER_ID, userId);
// or GetSnapshotAsync depending on the version of firebase
QuerySnapshot querySnapshot = await query.Get();
// Note: if it matches multiple documents this will just return
// the ID of the first match
foreach (DocumentSnapshot item in snapshot.Documents)
{
return item.Id;
}
Log.Debug("UpdateGroupAsync", "userId: " + userId + " not found");
return null;
}
And you can use it like this to update a document (note that you were using a different collection here - probably by mistake).
string userDocId = await GetDocRefAsync(userId);
CollectionReference userCollection = database.Collection(DBConstants.FS_COLLECTION_USERS);
DocumentReference docReference = userCollection.Document(userDocId);
// or UpdateAsync depending on your version of firebase
docReference.Update(DBConstants.FS_COLLECTION_USERS_GROUPS_CODE, groupCode);

Getting multiple documents in firebase functions

I am trying to figure out how to loop through multiple documents, fetched in a firebase cloud function, in Unity, but not sure how?
Here is my cloud script:
exports.getUserData = functions.https.onCall(async(data, context) => {
if (!context.auth) {
throw new functions.HttpsError(
'unauthenticated',
'only autehnticated users can make requests!'
);
}
const userData = await admin.firestore().collection('users').get(data.userid);
const myGroupMemberships = await admin.firestore().collection('groupMembers').where("playerId", "==", data.userid).get();
var myGroups = [];
myGroupMemberships.forEach(group => {
const thisGroup = admin.firestore().collection('groups').get(group.groupId);
myGroups.push(thisGroup);
})
return { "groups": myGroups };
});
As you can see, I first have to find the memberships for the user in "groupMembers", then loop through the records to get the group documents. I am not sure I am sending them correct, but thought that putting them in an array would be easies!?! Not sure thats the case.
In my Unity script I try to get them like this:
var func = FirebaseManager.instance.functions.GetHttpsCallable("getUserData");
var data = new Dictionary<string, object>();
data["userid"] = userId;
var task = func.CallAsync(data).ContinueWithOnMainThread((callTask) => {
if (callTask.IsFaulted)
{
// The function unexpectedly failed.
GA.Log("FAILED!");
GA.Log(string.Format(" Error: {0}", callTask.Exception));
return;
}
var result = (IDictionary)callTask.Result.Data;
// The function succeeded.
GA.Log(string.Format("Whats in the groups: {0}", result["groups"]));
List<Group> theGroups = result["groups"] as List<Group>;
foreach (Group thisGroup in theGroups)
{
GA.Log("GroupName: " + thisGroup.groupName);
}
});
yield return new WaitUntil(() => task.IsCompleted);
The log: Whats in the groups returns this: System.Collections.Generic.List`1[System.Object]
I do not get any logs on the "Groupname" inside the foreach loop!
Where am going wrong and how should I accomplish this?
Any help is appreciated and thanks in advance :-)

C# Google API throws exception

I am using Google API for the first time and I want to use Natural Language API.
But I don't know how.
So I search the internet and found an example code.
But when it uses APIs, the program throws an exception.
problem source code and thrown exception:
using Google.Cloud.Language.V1;
using System;
namespace GoogleCloudSamples
{
public class QuickStart
{
public static void Main(string[] args)
{
// The text to analyze.
string text = "Hello World!";
try
{
var client = LanguageServiceClient.Create();
var response = client.AnalyzeSentiment(new Document()
{
Content = text,
Type = Document.Types.Type.PlainText
});
var sentiment = response.DocumentSentiment;
Console.WriteLine($"Score: {sentiment.Score}");
Console.WriteLine($"Magnitude: {sentiment.Magnitude}");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
The console output:
The Application Default Credentials are not available.
They are available if running on Google Compute Engine.
Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials.
See https://developers.google.com/accounts/docs/application-default-credentials for more information.
What should I do?
I had used NLP a year ago for entity analysis. I had used Google.Apis.CloudNaturalLanguage.v1. I put together my code with what you have written for sentiment analysis. You will need the API key for this:
var service = new CloudNaturalLanguageService(new CloudNaturalLanguageService.Initializer { ApiKey = ApiKey });
var req = new AnalyzeSentimentRequest {
Document = new Document()
{
Content = text,
Type = Document.Types.Type.PlainText
},
EncodingType = "UTF8"
};
var output = service.Documents.AnalyzeSentiment(req);
var exe = output.Execute();
Hope this works.

Xamarin HTTPClient suddenly not GET/POSTing

Long time lurker, first time asker
So I've got some code which has been working fine for a long, long time (it's core functionality, so I know it's been fine). I've recently formatted my PC, which has understandably reset all my custom configs over time. Now suddenly, my HTTPClient code doesn't GET or POST at all, unless I break the Async functionality - and even that breaks other things. I've let it run, and the client ends up timing out.
The code is dying at the hClient.GetStringAsync() and hClient.PostAsync() lines below - as I mentioned, it's been fine for almost 2 years, just suddenly decided to die following the format. All help appreciated!
Background: This is a Xamarin PCL project, targetting all platforms - currently testing against UWP. Have had the same issue on both VS2015 and VS2017. Was previously using VS2015.
The code in question:
public async Task<string> Getter(string uriToPass, string propertyToParse = "", string parent = "", int index = 0)
{
var uri = new Uri(uriToPass);
var response = await hClient.GetStringAsync(uri);
string valToReturn = propertyToParse == "" ? response : JsonVal(response, propertyToParse, parent);
dbg(propertyToParse + ": " + valToReturn);
return valToReturn;
}
public async Task<string> Poster(string uriToPass, Dictionary<string, string> valsToPass, string propertyToParse = "", string parent = "", int index = 0)
{
var response = await hClient.PostAsync(uriToPass, new FormUrlEncodedContent(valsToPass)).ConfigureAwait(false);
string valToReturn;
if (propertyToParse == "")
{
valToReturn = await response.Content.ReadAsStringAsync();
}
else
{
valToReturn = JsonVal(response.Content.ReadAsStringAsync().ToString(), propertyToParse, parent);
}
dbg(propertyToParse + ": " + valToReturn);
return valToReturn;
}
Example code to call both functions above is:
this.authToken = await this.sM.Getter(this.MethodBuilder("auth.gettoken"), "token");
string response = await this.sM.Poster(this.MethodBuilder("auth.getMobileSession", true, vP, true), vP);
So I've now used ConfigureAwait(false); for my Getter function - and the HTTP call is now being made correctly. However it's still not progressing from my first authToken line above to the response line
EDIT: Turns out I had a blocker in my code after all - one of my top level functions was relying on this.VARIABLE = sM.Getter().Result(). Removing that ended up fixing my issue. Thanks all for the help!
Turns out I had a blocker in my code after all - one of my top level functions was relying on this.VARIABLE = sM.Getter().Result();. Removing that ended up fixing my issue. Thanks all for the help!

TFS API - How to get a Team's Adminstrator?

I'm trying to programmatically retrieve a Team's Administrator Users.
For example in a setup like in the picture how can I get 'Billy' as being the Administrator of Team 'QC Manager'?
I already have the code that gets all users in a Team via IIdentityManagementService's ListApplicationGroups, getting the group using FirstOrDefault ... and then getting its users via ReadIdentities.
I've done some poking around in the Team Web Access assemblies, and this seems to be only available on the server side at the moment (no Rest or Client Object Model option available). The code looks like this:
TeamFoundationIdentity identity;
string token = service.GetSecurableToken(requestContext, teamIdentity.Descriptor, out identity);
AccessControlList list = requestContext.GetService<SecurityService>().QueryAccessControlLists(requestContext, FrameworkSecurity.IdentitiesNamespaceId, token, null, false, false).FirstOrDefault<AccessControlList>();
List<IdentityDescriptor> list2 = new List<IdentityDescriptor>();
if (list != null)
{
foreach (AccessControlEntry entry in list.AccessControlEntries)
{
if ((entry.Allow & 8) == 8)
{
list2.Add(entry.Descriptor);
}
}
}
return service.ReadIdentities(requestContext, list2.ToArray());
Where GetSecurableToken looks like:
internal static string CreateSecurityToken(TeamFoundationIdentity group)
{
return (group.GetAttribute(IdentityAttributeTags.LocalScopeId, string.Empty) + FrameworkSecurity.IdentitySecurityPathSeparator + group.TeamFoundationId.ToString());
}
From here you should be able to piece together the code to read and writes these lists. To go poking around yourself, look for the Microsoft.TeamFoundation.Server.Core.dll, Class Microsoft.TeamFoundation.Server.Core.TeamFoundationTeamService to be specific.
If you're able to rewrite it into something useful I'd be grateful and might stick it into the TfsTeamTools, at the moment I don't have much time on my hands to pick this up.
Found this post TFS11 API: Managing Team Administrators; I duplicate code for easy reference, see original post for complete info.
static void Main(string[] args)
{
// Connect to the TFS server and get the team project URI.
var collection = GetServer("server_uri");
var projectUri = GetProjectUri(collection, "project_name");
// Retrieve the default team.
TfsTeamService teamService = collection.GetService<TfsTeamService>();
TeamFoundationTeam defaultTeam = teamService.GetDefaultTeam(projectUri, null);
// Get security namespace for the project collection.
ISecurityService securityService = collection.GetService<ISecurityService>();
SecurityNamespace securityNamespace = securityService.GetSecurityNamespace(FrameworkSecurity.IdentitiesNamespaceId);
// Use reflection to retrieve a security token for the team.
MethodInfo mi = typeof(IdentityHelper).GetMethod("CreateSecurityToken", BindingFlags.Static | BindingFlags.NonPublic);
string token = mi.Invoke(null, new object[] { defaultTeam.Identity }) as string;
// Retrieve an ACL object for all the team members.
var allMembers = defaultTeam.GetMembers(collection, MembershipQuery.Expanded).Where(m => !m.IsContainer);
AccessControlList acl = securityNamespace.QueryAccessControlList(token, allMembers.Select(m => m.Descriptor), true);
// Retrieve the team administrator SIDs by querying the ACL entries.
var entries = acl.AccessControlEntries;
var admins = entries.Where(e => (e.Allow & 15) == 15).Select(e => e.Descriptor.Identifier);
// Finally, retrieve the actual TeamFoundationIdentity objects from the SIDs.
var adminIdentities = allMembers.Where(m => admins.Contains(m.Descriptor.Identifier));
}

Categories

Resources