Writing a custom claims issuance rule - windows

For a specific use case, we need to add external users to our AD and allow these to login through AD FS to an external service.
Everything was set up with only internal users in mind, so we wrote a claim rule as follows:
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"), query = ";sAMAccountName;{0}", param = c.Value);
Basically, this is LDAP Attribute "SAM-Account-Name", and Outgoing Claim Type "Given Name". This works well for internal users.
For external users, there's a use case where the user name in the external site should be the email address used in AD. The easiest thing would be to fill in the email address in the sAMAccountName, but it doesn't allow # symbols.
So I was messing around with claim transformation rules, and figured I could try to add two conditional claim rules, as follows:
Internal users:
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", Value =~ "domain.com$"]
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"), query = ";sAMAccountName;{0}", param = c.Value);
External users:
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", Value !=~ "domain.com$"]
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"), query = ";mail;{0}", param = c.Value);
The first claim rule checks if the email address ends with "domain.com", and if so, it will use the sAmAccountName (internal users).
The second claim rule does the reverse: if it doesn't end with "domain.com", it will use the mail attribute (external users).
But pity, it's not working (either one tested separately).
What's wrong with my approach?

Related

Syntax for if-else branch based on user input in Bot Framework Composer

When a user is prompted with a yes or no question, each user might respond differently. Say for example, responses for yes could be yeah, why not, sure, im okay with it, yup etc and similarly to respond for no users could say nope, nah, no.
I want to send a response if the user input belongs to Yes class and send a different response if he has uttered words from No type in Bot Framework Composer.
Under Expected Responses I created entities with value to distinguish the two classes as below
-{Accept = yeah}
-{Accept = Yea}
-{Accept = yup}
-{Accept = that will work}
-{Accept = why not}
-{Accept = yep}
-{Accept = yes}
-{Accept = yeah sure}
-{Reject = No}
-{Reject = Nope}
-{Reject = nah}
screenshot of the composer window
How to write condition checking the user input with the defined class?

Validating email against multiple same words in react-native

I'm facing a problem while validating an Email in react-native.
Currently I'm using email-validator and it's working fine. I'm not using email verification in my App, so I need to check precisely whether input is email or not.
I'm looking for a technique which can identify following as an invalid email because it has a word more then once after #
User#mail.com
User#mail.mail.com
User#mail.com.com.uk
User#mail.com.com
Valid email should be like this.
User#mail.com
User#mail.com.uk
User#mail.com.edu.uk
A regular expression would probably be more efficient if anyone else want's to provide one, but here's one way to do it in a function:
var email = "User#mail.mail.com";
let findDuplicates = (arr) => arr.filter((item, index) => arr.indexOf(item) != index);
let hasDuplicate = (test) => findDuplicates(test.split("#")[1].split(".")).length > 0
console.log(hasDuplicate(email));

Hyperledger-Composer: ACL-rules with condition of type (r.someArray.indexOf(p.getIdentifier()) > -1) not working

In my hyperledger-composer application, access control rules with a condition of the following type:
(r.someArray.indexOf(p.getIdentifier()) > -1)
do not work.
Here is an example of such an ACL-rule:
rule SuperiorsHaveReadAccessToTheirTeamMembers {
description: "Allow superiors read access to data on their team members"
participant(p): "org.comp.app.Employee"
operation: READ
resource(r): "org.comp.app.Employee"
condition: (r.superiors.indexOf(p.getIdentifier()) > -1)
action: ALLOW
}
for clarification:
participant Employee extends User {
o String company optional
--> Employee[] superiors optional
}
So the access control rule above simply states that Employee A has READ Access to Employee B if and only if Employee B's array-attribute "superiors" contains Employee A (i.e. if Employee A is the superior of Employee B).
However, it doesn't work. Employee A does not have READ access to Employee B. All the other access control rules of this kind do not work either.
Is this a bug in hyperledger-composer?
no, its not a bug. Its, again, because you're working with an array of resource objects, as you've modeled it. indexOf works on the string Object. It works for me as follows:
rule SuperiorsHaveReadAccessToTheirTeamMembers {
description: "Allow superiors read access to data on their team members"
participant(p): "org.comp.app.Employee"
operation: READ
resource(r): "org.comp.app.Employee"
condition: (r.authorized && r.authorized.toString().indexOf(p.getIdentifier()) > -1)
action: ALLOW
}
Also, remember how indexOf works: it will 'pass' on the first match. It may be better to have an authorized field, and store shortened (string) ids in (say) a field eg. String[] authorized optional - and in this case your original rule would then work first time.

Retrieving user metadata about a provisioned SoftLayer server comes back null

I'm trying to retrieve the user meta information for each machine consistently but what I'm finding is most of my machines are missing this data. I'd like to understand better what is required for this user data to be there. I'm curious if a server can be requested and provisioned without requiring user information (e.g. an API call to order a server and no user data is given). Or whether I am missing something in how I retrieve this information. Here is the basic ruby program I'm running:
user = ###
api_key = ###
client = SoftLayer::Client.new(:username => user, :api_key => api_key, :timeout => 999999)
list_of_virtual_machines = client['Account'].result_limit(i*50,50).object_mask("mask[id, billingItem[recurringFee, associatedChildren[recurringFee], orderItem[description, order[userRecord[username], id]]], userData]").getVirtualGuests
for x in 0..list_of_virtual_machines.length - 1
pp list_of_virtual_machines[i]['userData']
if list_of_virtual_machines[i]['billingItem'] && list_of_virtual_machines[i]['billingItem']['orderItem'] && list_of_virtual_machines[i]['billingItem']['orderItem']['order'] && list_of_virtual_machines[i]['billingItem']['orderItem']['order']['userRecord']
pp list_of_virtual_machines[i]['billingItem']['orderItem']['order']['userRecord']
end
end
My prints are consistently showing null. This question is related to a similar question I asked not too long ago (but the focus of that question moved towards the provisionDate):
How to get order username and provisionDate for all SoftLayer machines using Ruby?
They are missing that data because you did not added.
you can create the user data at moment to order a new server or VSI, you just have to send the data in your order request either using the createObject method or the placeOrder method. see http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest/createObject
e.g.
{
"userData": [
{
"value": "someValue"
}
]
}
or you can set it after the server has been provisioned using these methods
http://sldn.softlayer.com/reference/services/SoftLayer_Virtual_Guest/setUserMetadata
http://sldn.softlayer.com/reference/services/SoftLayer_Hardware_Server/setUserMetadata
Basically the usermetadata are useful if you are going to use a post install script. The usermetadata value is not required to order a new server
take a look this article for examples:
http://sldn.softlayer.com/blog/jarteche/getting-started-user-data-and-post-provisioning-scripts

Set CRM Lookup Values with WebAPI

Who had done CRM Web API calls to update CRM entities with Lookup values from another Entity.
I'm trying to set a Lookup Value to another Entity within CRM using WebAPI, CRM 2016. It works if I disable the Lookup value but once I enable the Lookup value, I receive Bad Request.
Below is my code in LinqPad so it does work.
void Main()
{
using(var webClient = new WebClient()){
webClient.Credentials = new NetworkCredential("Username", "Password", "Domain");
webClient.Headers.Add("OData-MaxVersion", "4.0");
webClient.Headers.Add("OData-Version", "4.0");
webClient.Headers.Add("accept", "application/json");
webClient.Headers.Add("Content-Type","application/json");
webClient.Headers.Add("Prefer", "odata.include-annotations=*");
webClient.BaseAddress = "http://dev.company.com/DEV2016/api/data/v8.0/";
var JO = new JObject();
JO.Add("col_name","My Name");
//JO.Add("col_contactid#odata.bind","/contacts(7266f26b-7105-e611-811e-005056b61789)");
var dataString = JO.ToString();
var responseString = webClient.UploadString("col_advisors", "POST", dataString);
Console.WriteLine(webClient.ResponseHeaders.Get("OData-EntityId"));
}
}
Case matters with the WebAPI. Make sure your col_contactid is the schema name, not the logical name. For example, the logical name of your attribute is col_contactid (logical names are always lowercase), but schema names often times have upper case letters. Yours might be col_ContactId for example, in which case you would want to use col_ContactId#odata.bind.
The easiest way to find the schema name of your attribute is by going to CRM -> Settings -> Solutions -> your solution -> Entites (on the left) -> Advisors -> Fields. In that grid you'll see a column for schema name.
I got it to work. The fields really have to be unique as it is case sensitive. Comments here and also this blog, really helped.
http://inogic.com/blog/2016/02/set-values-of-all-data-types-using-web-api-in-dynamics-crm/
Step 1 : Goto Cutomization  Developer Resource.
Step 2 : Click to “Download Odata Metadata” link and Download the same.
Step 3 : Once Download, open it and find out name of lookup attribute ( i.e. new_qualifiedleadid) and check its casing.
Step 4 : Verify it with the value which you are setting in the code it should be same.
While my column was col_contactid, CRM renames the Navigational Column to be what was above col_ContactId.
I also used Postman(google chrome) plugin and added the following Header to my Post.
webClient.Headers.Add("Prefer", "odata.include-annotations=*");

Resources