Is there any way to verify that a #Sign exists before trying to share a key with it? - at-sign

I am using the #protocol in a Flutter app and was wondering if there was a way to verify if another #sign exists before trying to share a key with it. For now I made a function that will try to share a key with the specified #sign. If there is an AtLookUpException, I consider the user non-existent:
/// Check if user exists in this namespace by trying to share a key with them
Future<bool> checkForUser(String atSign) async {
/// Do test send to see if # sign exists
AtKey testKey = AtKey();
testKey.key = 'test';
testKey.sharedWith = atSign;
try {
await atProtocolService.atClientImpl.put(testKey, 'Are you there?');
return true;
} on AtLookUpException catch (e){
print('AtLookUpException: '+ e.errorMessage);
return false;
}
}
For further verification, you could check the error message of the AtLookUpException which will look like this:
Secondary server not found: No secondary url found for atsign: #bob
Is this the best or quickest way to do this?

There is a library available to you that you can use:
https://github.com/atsign-foundation/at_libraries/tree/master/at_server_status
Feel free to adapt any part of the code as you like to fit your use case.
As always, your feedback is welcome.

Related

applicationinsights clickanalytics.js npm - add custom property

I am using https://www.npmjs.com/package/#microsoft/applicationinsights-clickanalytics-js to send click event as telemetry data to application insights.
What I need to do is to send for all the events a custom propery - for example a tenant id - that I can use in the provided visualizations/queries to do group bys.
Honestly I do not find a way on how to do this.
I found there are possiblities to use a TelemetryProcessor or something like
appInsights.defaultClient.commonProperties = {
environment: process.env.SOME_ENV_VARIABLE
};
But I find no way on how to achive this with the npm package.
Any hints, idea?
Basically I want to add a custom property that is written with every autogenerated or manual event.
For future generations stuck with the same issue ;)
I solved it like this
const telemetryInitializer = (envelope) => {
const user = getUserFromSomewhere();
if (!user) {
console.log("User is not set")
return false;
}
envelope.tags["ai.cloud.roleInstance"] = user?.tenant;
return true;
};
appInsights.addTelemetryInitializer(telemetryInitializer);

issue with creating role and channel automatically from private message with bot

Not sure how the create channel and create role isn't working inside the following code, towards the bottom. (EDIT: Nothing is sent to the console and nothing happens regardng the code. It is like it is entirely ignored.) This is a snippet from code that User A challenges User B. User B is messaged, alerting them that a challenge has been issued to them via a Private Message. If the challenge is accepted, I want the bot to 1)Make a role specifically for User A and User B named "User A vs User B" 2) take User A and User B and put them both into that new role and 3) Make a battlefield named "User A vs User B" inside a specific category inside the server the bot is on.
I am unsure if the problem lies in how the bot is trying to make the role and channel in a sever while the bot is talking to the user in a private message instead of on the server. I thought putting the "server" variable as the server ID would help but it doesn't seem to do anything after the accept message.
// Awaits reply from user
if (message.channel.id === '541736552582086656') return target.send("Do you accept the challenge? Please reply with 'accept' or 'deny'.")
.then((newmsg) => {
newmsg.channel.awaitMessages(response => response.content, {
max: 1,
time: 150000,
errors: ['time'],
}).then((collected) => {
// Grabs the first (and only) message from the collection.
const reply = collected.first();
if (reply.content === 'accept'){
reply.channel.send(`You have ***accepted *** the challenge from ${challenger}. Please wait while your battlefield is made...`);
message.author.send(`${target} has accepted your challenge! Please wait while the channel is made for your brawl...`)
/// Problems start here
function createChannel(message){
var server = "SERVER ID";
var name = `${target} vs ${challenger}`;
message.guild.createRole({
role: {
name: `${target} vs ${challenger}`,
color: "#00fffa",
permissions: [] }
}).then(role => {
target.addRole(role, name)
challenger.addRole(role, name)
.catch(error => client.catch(error))
}).catch(error => client.catch(error))
server.createChannel(Name, name).then(
(channel) => {
channel.setParent("CATEGORY ID")
})
} // problems end here
} else if (reply.content === 'deny') {
reply.channel.send("You have ***denied *** the challenge.")
} else {
reply.channel.send("Your response wasn't valid.");
}
})
})
}
I have been wondering if I need to go about making the channel and role in a different way since it is trying to be made from a private message and not inside the server..
Thanks for any and all help! I also apologize if I'm using stack overflow too much for problems like this... You guys are great at helping me see different ways to do things and what I'm doing wrong, so I am learning, but I don't want to feel like I'm abusing it too much.
I think the problem is the fact that you create a function called createChannel with the code to create a rol and channel, but you never call said function.
You can either call the function after you've declared it or (which is in my opinion better) you can remove the following lines
function createChannel(message){
} // problems end here

Transfer data from Zapier authentication to trigger

I am working on a Zapier app and there is a tenant id (integer) that is retrieved during authentication that I need to use in a trigger. What is the correct way to do this?
I have tried using global, bundle.authData and storing the data in a module, but nothing seems to work consistently. The best has been when I stored the data in global, but it is inconsistent, out of six calls to the trigger the tenant id may only be valid twice, the other four times it will be returned as undefined.
In the case of global I am writing the data during authentication:
const test = (z, bundle) => {
return z.request({
url: URL_PATH + ':' + URL_PORT + '/v1/auth',
params: {
username: bundle.authData.username,
password: bundle.authData.password
}
}).then((response) => {
if (response.status === 401) {
throw new Error('The username and/or password you supplied is incorrect.');
} else {
global.GLOBAL_tenant = response.json.tenant;
// ...
}
}
And then attempting to read the data back in the trigger:
const processTransactions = (z, bundle) => {
let jsonAll = [];
let tenant = global.GLOBAL_tenant;
return new Promise( (resolve, reject) => {
(function loop() {
// ...
I also tried adding the dat to 'bundle.authData', this was the recommendation that Zapier made when I contacted them, but the tenant id that I added during the authentication:
bundle.authData.tenant = response.json.tenant
Is not available when I try to retrieve it in the trigger. Only the 'username' and 'password' are present.
I am new to Zapier and node.js so any help will be greatly appreciated.
Instead of returning fully qualified name like bundle.authData.tenant = response.json.tenant, please use something like tenant = response.json.tenant and this statement should be enclosed in a return statement preferably. The bundle.authData qualifier is automatically applied by Zapier.
global variables should be avoided. Hope this helps.
David here, from the Zapier Platform team.
global isn't going to work because your code runs in multiple lambda executions and state isn't stored between them. Plus, global implies it would be the same for all users, which probably isn't what you want.
Instead, I'd check out session auth, which will let you store extra fields during your test by creating a computed field and returning values for it from sessionConfig.perform. Then it'll be stored in the auth object, next to the username and password.
Separately, you may want to consider whatever code is in processTransactions. Either you can return them all and they'll deduped on our end, or you're doing a bunch of extra computation that is better dehydrated. That's just a guess on my part though, so feel free to ignore this part.

DocumentDB: Delete a document by ID

I'm using a new database from Microsoft called DocumentDB. Now I want to delete a document by ID, but I cannot figure out, how to do this. Delete operation in DocumentDB requires self-links and they are different from my own ids.
using (var client = new DocumentClient(EndPoint, AuthKey))
{
await client.DeleteDocumentAsync("**self-link here**");
}
I can execute an additional query to find the self-link and then pass it, but this will require two operations instead one and that is what I'd like to avoid. Is there a better way to remove an entry by ID without using queries or stored procedures?
* UPDATE * This feature has now been implemented
* ORIGINAL ANSWER *
Not today, no. You can head to http://feedback.azure.com/forums/263030-documentdb and vote for the feature there.
Here is how I am deleting document
{
var docUri = UriFactory.CreateDocumentUri(_documentDataBaseId, _documentCollectionId, docId);
await _documentClient.DeleteDocumentAsync(docUri);
}
This features has now been implement (as of the 8/2015 - https://feedback.azure.com/forums/263030-documentdb/suggestions/6333050-it-should-be-possible-to-remove-a-document-by-id
as there's no solution for this case I'd recommend to retrieve all the documents in the existing collection to get access to the SelfLink and _rid values.
I just started a mini wrapper to get access to DocumentDB in Universal Apps and hopefully CrossPlatform using Xamarin: https://github.com/JorgeCupi/documentDB-Win10UAP-wrapper feel free to give me any feedback, participate or request some needed methods.
I have tried this code in nodejs to deletebyId and it works for me.
deleteDocumentById: function(params, callback) {
var self = this,
query= params.query,
collection = params.collection;
client.queryDocuments(collection._self, query, function(err, docs) {
if (err) {
return callback(err);
}
client.deleteDocument(docs[0]._self, docs[0], function(err, success) {
if (err) {
return callback(err);
}
callback(null, success);
});
});
}
I was continuously receiving this error: Microsoft.Azure.Documents.DocumentClientException:
Entity with the specified id does not exist in the system.,
The main trick of deleting is PartionKey id. You suppose inside PartionKey provide id
like in the code example.
I have tried many ways, but I was always receiving different errors...Only this solution worked for me.
await client.DeleteDocumentAsync(input[0].SelfLink,
new RequestOptions
{
PartitionKey = new PartitionKey(input[0].Id)
});
Hope this helps :)

How to Deactivate a LDAP User?

I am using a library to authenticate LDAP Users, whose code is as follows:
public void authUser(String username, String pwd)
throws Exception
{
try
{
Properties env = getEnvironmentForContext();
env.put("java.naming.security.principal", "uid=" +
username + ",ou=users, dc=company"));
env.put("java.naming.security.credentials", pwd);
context = getContext(env);
System.out.println("Authentication Succeeded");
}
catch (Exception e)
{
System.out.println("Authentication Failed");
throw e;
}
}
Please note, i cannot modify the above Authentication Code. It comes from a external Library.
But, i want to deactivate some users (not delete them), so that Authentication Fails.
I am using LDAP (not Active Directory). Do not know what LDAP Software it is though, i can connect to it using 'LDAP Browser Client'.
The users exist under: dc=company, ou=users, uid=username
What attribute can i add/change on LDAP 'user' to de-activate a user.
Could i move the user to a different group like: dc=company, ou=deactivatedusers, uid=username? But this is not the preferred option, plus am not sure best way to do that.
EDIT: The LDAP being used is: Netscape/Sun/iPlanet
To answer your question per the Oracle iPlanet (Sun) documentation :
Setting the attribute nsAccountLock to true will disable a users account, and prevent them from binding to the directory.
However, in terms of the code you already have, I just don't see any way of accomplishing this... Is there something preventing you from writing your own implementation for iPlanet using the System.DirectoryServices.Protocols namespace in .Net?
Here is how I bind and authorize users against an iPlanet server :
//Build servername from variables
var BuildServerName = new StringBuilder();
BuildServerName.Append(ServerName);
BuildServerName.Append(":" + Convert.ToString(Port));
var ldapConnection = new LdapConnection(BuildServerName.ToString());
//Authenticate the Admin username and password, making sure it's a valid login
try
{
//Pass in the network (administrative) creds, and the domain.
var networkCredential = new NetworkCredential(Username, Password, config.LdapAuth.LdapDomain);
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.SessionOptions.VerifyServerCertificate += delegate { return true; };
ldapConnection.AuthType = AuthType.Anonymous;;
ldapConnection.Bind(networkCredential);
//Lets find this person so we can use the correct DN syntax when we authorize them.
SearchRequest FindThem = new SearchRequest();
FindThem.Filter = config.LdapAuth.LdapFilter.Replace("{{Patron}}", Patron);
FindThem.DistinguishedName = config.LdapAuth.LdapDomain;
FindThem.Scope = System.DirectoryServices.Protocols.SearchScope.Subtree;
//We'll execute a search using the bound user
SearchResponse searchresults = (SearchResponse) ldapConnection.SendRequest(FindThem);
//Should only get on result back, if not throw an error
if(searchresults.Entries.Count == 1)
{
SearchResultEntryCollection entries = searchresults.Entries;
SearchResultEntry thispatron = entries[0];
PatronDN = thispatron.DistinguishedName;
}
}
If you wanted to move disabled users to a specific group, from this point you could write logic to check the DistinguishedName of that user, and throw a handled exception if their DistinguishedName contains the name of that group. Also, if the nsAccountLock attribute is available to your binding account as a readable attribute, you could just check the value of that attribute for true, and handle the user accordingly.
Here is the java code for disabling and enabling user in Active Directory using JNDI.
Make sure to connect with your AD before calling below code.
public void disableEnableUser() throws Exception {
ModificationItem[] mods = new ModificationItem[1];
//To enable user
//int UF_ACCOUNT_ENABLE = 0x0001;
//mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("userAccountControl",Integer.toString(UF_ACCOUNT_ENABLE)));
// To disable user
int UF_ACCOUNT_DISABLE = 0x0002;
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("userAccountControl",Integer.toString(UF_ACCOUNT_DISABLE)));
ctx.modifyAttributes("CN=John ABC,OU=Users,OU=anyone,DC=yourcompanyname,DC=com", mods);
}
Distinguished name = "CN=John ABC,OU=Users,OU=anyone,DC=yourcompanyname,DC=com"
This name is depend on your structure of Active Directory, you can confirm from your suport team.
If the directory software supports a password policy feature, it probably provides attributes to lock/deactivate the user. If not, you can simply nullify the password attribute (e.g., userpassword). The LDAP server should return the "inappropriate authentication" error to the client when the authenticated bind is performed.
You could just change the user's password. If it's OpenLDAP with the password-policy overlay, or another LDAP server that supports locking, you can lock the user as well. You really will have to find out.

Resources