Iterating 'forEach' member with a role - foreach

I have found several posts that seem to be trying to solve this problem, but none of the solutions / attempts I have seen will work for me.
I have a 'role' which my bot fetches successfully. On command I want the bot to then go through each of the members with that role and give them additional roles.
It simply will not work, so (for testing / debugging purposes) I currently have the following code:
const teamCaptainRole = await message.guild.roles.cache.find(role => role.name === "Team Captain");
console.log(teamCaptainRole.members)
await teamCaptainRole.members.forEach(member => {
console.log(member)
});
Previous 'console logs' of "teamCaptainRole" have shown me that I am successfully fetching the role. The console log of "teamCaptainRole.members" returns:
Collection [Map] {}
I have done googling around these words, but just find myself on a wild goose chase - I cannot find a way to dig down into this Map / Collection. I do not have any prior experience of working with maps, but arrays and objects I understand well. The 'forEach' never seems to trigger, but also doesn't throw any errors - simply nothing happens. Right now I would just love to be able to see a series of console logs of members that have that role so that I know the forEach is working.
Any help?

let role = message.guild.roles.cache.find(r => r.name === "Team Captain");
let giveRole = message.guild.roles.cache.find(r => r.name === "Enter Role Here");
let users = role.members.map(m => message.guild.member(m.user));
for(let user of users) {
user.roles.add(giveRole);
}
role -> The role where we will search the users from.
giveRole -> The role we will give all members that have role.
users -> The users who have role.
You could use users.forEach() as well but I used a basic for-loop. We map those users who have the role, but as an GuildMember Object, so that we can add giveRole in the for-loop.

Related

Autodesk Simple Viewer - "Could not list models. "

I'm trying to implement the code example in this repo:
https://github.com/autodesk-platform-services/aps-simple-viewer-dotnet
While launching in debugging mode, I get an error in the AuthController.cs says:
Could not list models. See the console for more details
I didn't make any significant changes to the original code, I only changed the env vars (client id, secret etc..)
The error is on the below function:
async function setupModelSelection(viewer, selectedUrn) {
const dropdown = document.getElementById('models');
dropdown.innerHTML = '';
try {
const resp = await fetch('/api/models');
if (!resp.ok) {
throw new Error(await resp.text());
}
const models = await resp.json();
dropdown.innerHTML = models.map(model => `<option value=${model.urn} ${model.urn === selectedUrn ? 'selected' : ''}>${model.name}</option>`).join('\n');
dropdown.onchange = () => onModelSelected(viewer, dropdown.value);
if (dropdown.value) {
onModelSelected(viewer, dropdown.value);
}
} catch (err) {
alert('Could not list models. See the console for more details.');
console.error(err);
}
}
I get an access token so my client id and secret are probably correct, I also added the app to the cloud hub, what could be the problem, why the app can't find the projects in the hub?
I can only repeat what AlexAR said - the given sample is not for accessing files from user hubs like ACC/BIM 360 Docs - for that follow this: https://tutorials.autodesk.io/tutorials/hubs-browser/
To address the specific error. One way I can reproduce that is if I set the APS_BUCKET variable to something simple that has likely been used by someone else already, e.g. "mybucket", and so I'll get an error when trying to access the files in it, since it's not my bucket. Bucket names need to be globally unique. If you don't want to come up with a unique name yourself, then just do not declare the APS_BUCKET environment variable and the sample will generate a bucket name for you based on the client id of your app.

Why does this discord bot tell me :kick is a nil value?

I am extremely new to making Discord bots. I am using discordia as my library. Currently, I am making a kick command but for some reason when I attempt to kick the mentioned user, it says "bot.lua:52: attempt to call method 'kick' (a nil value)". However, if I were to attempt to kick the person who sent the message, it works just fine.
client:on("messageCreate", function(msg)
local content = msg.content
local member = msg.member
local channel = msg.guild
local Author = msg.author
if content:sub(1,5) == prefix.."kick" then
local isMod = false
local function checkIfIsMod()
for i, v in pairs(member.roles) do
if v.name:lower() == "admin" then
isMod = true
end
end
end
checkIfIsMod()
if isMod then
print("yes")
if #msg.mentionedUsers > 1 then
msg:reply("Mention one user at a time!")
elseif #msg.mentionedUsers == 0 then
msg:reply("Mention someone!")
elseif #msg.mentionedUsers == 1 then
local mentioned = msg.mentionedUsers[1]
mentioned:kick()
msg:reply("kicked")
end
else
msg:reply("You aren't a mod!")
end
end
end)
I do not understand everything about Discordia, but I have read the documentation and testing and I hope to elucidate the problem now:
Every connected person has two objects known to the bot: User and Member. A user is a Discord account, a member is someone in a server. In real terms: You log into Discord as a user. You are a member of multiple servers.
You cannot kick a User, because a User is not connected to the server. A Member is. kick is a method of Member.
msg.author returns a User, msg.member returns a Member. You say in your post that you are able to kick the person who writes the message. You do not show this code, but I have to assume you are calling kick on msg.member since it would not work on msg.author.
When you mention users, they are returned as a list of IDs (msg.mentionedUsers). Every ID has one user, but a user can be multiple "members" across multiple servers. You need to get the member relationship between the User who is mentioned and the guild (server) the mention is called in. You can do this with Guild:getMember(ID). You could also do this (according to the docs) with Guild.members:get(ID), but this is cached. Offline members are not necessarily cached (known to the method), so I found it safer to use Guild:getMember(ID) (which will make an HTTP request). You can get the guild with msg.guild (as seen in your original code).
Here is working code that iterates over all mentioned users and kicks them. You could rework this to only kick the first person if you wish. You can put this inside your if isMod then statement.
for id in msg.mentionedUsers:iter() do
local u = msg.guild:getMember(id)
print("kicking", u.name)
u:kick()
end

firebase session for two users [duplicate]

In my main page I have a list of users and i'd like to choose and open a channel to chat with one of them.
I am thinking if use the id is the best way and control an access of a channel like USERID1-USERID2.
But of course, user 2 can open the same channel too, so I'd like to find something more easy to control.
Please, if you want to help me, give me an example in javascript using a firebase url/array.
Thank you!
A common way to handle such 1:1 chat rooms is to generate the room URL based on the user ids. As you already mention, a problem with this is that either user can initiate the chat and in both cases they should end up in the same room.
You can solve this by ordering the user ids lexicographically in the compound key. For example with user names, instead of ids:
var user1 = "Frank"; // UID of user 1
var user2 = "Eusthace"; // UID of user 2
var roomName = 'chat_'+(user1<user2 ? user1+'_'+user2 : user2+'_'+user1);
console.log(user1+', '+user2+' => '+ roomName);
user1 = "Eusthace";
user2 = "Frank";
var roomName = 'chat_'+(user1<user2 ? user1+'_'+user2 : user2+'_'+user1);
console.log(user1+', '+user2+' => '+ roomName);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
A common follow-up questions seems to be how to show a list of chat rooms for the current user. The above code does not address that. As is common in NoSQL databases, you need to augment your data model to allow this use-case. If you want to show a list of chat rooms for the current user, you should model your data to allow that. The easiest way to do this is to add a list of chat rooms for each user to the data model:
"userChatrooms" : {
"Frank" : {
"Eusthace_Frank": true
},
"Eusthace" : {
"Eusthace_Frank": true
}
}
If you're worried about the length of the keys, you can consider using a hash codes of the combined UIDs instead of the full UIDs.
This last JSON structure above then also helps to secure access to the room, as you can write your security rules to only allow users access for whom the room is listed under their userChatrooms node:
{
"rules": {
"chatrooms": {
"$chatroomid": {
".read": "
root.child('userChatrooms').child(auth.uid).child(chatroomid).exists()
"
}
}
}
}
In a typical database schema each Channel / ChatGroup has its own node with unique $key (created by Firebase). It shouldn't matter which user opened the channel first but once the node (& corresponding $key) is created, you can just use that as channel id.
Hashing / MD5 strategy of course is other way to do it but then you also have to store that "route" info as well as $key on the same node - which is duplication IMO (unless Im missing something).
We decided on hashing users uid's, which means you can look up any existing conversation,if you know the other persons uid.
Each conversation also stores a list of the uids for their security rules, so even if you can guess the hash, you are protected.
Hashing with js-sha256 module worked for me with directions of Frank van Puffelen and Eduard.
import SHA256 from 'crypto-js/sha256'
let agentId = 312
let userId = 567
let chatHash = SHA256('agent:' + agentId + '_user:' + userId)

How to switch the user tenant id in Grails Multi Tenant Single DB plugin without relogin

Use Case : A single user with “single user name” should be able to use data available in different tenant without relogin.
Expected Flow :
User “A” login into tenant 1
He done some activity and able to access all tenant 1 data
He clicks on the “switch tenant” link and after that he should be able to access all data related to Tenant 2
Environment :
Grails v2.1
spring-security-core v1.2.7.3
multi-tenant-single-db v0.8.3
I am using following auto generated class
SpringSecurityTenantRepository
SpringSecurityTenantResolver
I used following code in controller but it did not work.
def switchedTenentId = params.switchedTenentId
if(switchedTenentId != null && !"".equals(switchedTenentId))
{
def currUser = springSecurityService.currentUser
springSecurityService.currentUser.userTenantId = new Long(switchedTenentId)
}
I googled but did not find any solution. I like to know the logic, solution or any sample code.
Thanks
Here is what I did:
User u = User.get(springSecurityService.currentUser.id)
u.userTenantId = params.switchedTenentId.toInteger()
u.save flush: true
springSecurityService.reauthenticate u.username
It worked like a charm.

Symfony 1.4 Permissions and Credentials AND OR not working

Need to know if I'm missing something... I'm using sfGuardPlugin and trying to get a complex credential to work... and it's not even that complex. I just can't get either AND or OR to work.
"user_a" is set up to have permission "A" in both permissions and group "A" which also has permission "A" assigned to it.
I also have a Permission "B" and a group "B" set up in the same fashion as above... however, I did not assign user_a to these permissions. To be clear: user_a only has A permissions.
Now in security I have the following (where the user needs to either have credential A or B):
dashboard:
credentials: [[A, B]]
Now when I try to have user_a access the dashboard, it fails and redirects to the credentials required page. I tried the same thing with an AND statement and set up user_a with both, using:
dashboard:
credentials: [A, B]
...again, it failed.
Now, when I remove the brackets, and just use one credential, it all works perfectly. It's just when I use them in combination, in any form, that I run into problems.
Furthermore, I have checked if the user has a single credential, using:
echo $user->hasCredential('A');
And it responds as expected: True
But if I assign the user to both A and B and then try either:
echo $user->hasCredential(array('A', 'B'), false);
or
echo $user->hasCredential(array('A', 'B'));
It responds with False.
I'm stumped. What am I missing? I MUST have at least the [[OR]] working. Has anyone else experienced this? Is there a work-around?
EDIT: code snippet in myUser.class:
public function hasCredential($permission_name)
{
//this overrides the default action (hasCredential) and instead of checking
//the user's session, it now checks the database directly.
if (!$this->isAuthenticated()) {
return false;
}
$gu = $this->getGuardUser();
$groups = $gu->getGroups();
$permissions = $gu->getPermissions();
$permission_names = array();
foreach($permissions as $permission) {
$permission_names[] = $permission->getName();
}
foreach($groups as $group) {
$group_permissions = $group->getPermissions();
foreach($group_permissions as $group_permission) {
$permission_names = array_merge($permission_names, array($group_permission->getName()));
}
}
$permission_names = array_unique($permission_names);
return (in_array($permission_name, $permission_names)) ? true : false;
}
EDIT:
The above code snippet is indeed the problem. I tested it without the code snippet and it works as expected. So my next question, is how to tweak the snippet to accommodate instances with AND or OR? Suggestions?
I'm going to close this question, because I have found the problem and I will open a new question as a result of the issue I'm having with the code snippet (which becomes a new question).

Resources