I'm using the MSFT Bot Framework to build a team bot but my bot is only relevant to my organization. Actually I don't want anyone outside my organization to be able to talk to it.
I've been looking how to limit my bot to a specific Office 365 organization but can't find how to do it. The only thing I can find is using the other party userstring to see in which org they live.
My question:
Is ther a way to limit my bot to a single O365 organization?
Thanks
Bram
Its been 2 years but there's no real answer and it popped up in my related list tho...
These days you can write an easy simple middleware that does the tenant filtering like here:
public static string TenantFilterSettingAny = "#ANY#";
/// <summary>
/// Here are below scenarios -
/// #Scenario 1 - Reject the Bot If Tenant is configured in web.config and doesn't match with Incoming request tenant
/// #Scenario 2 - Allow Bot for every Tenant if Tenant is not configured in web.config file and default value is #ANY#
/// </summary>
/// <param name="activity"></param>
/// <param name="currentTenant"></param>
/// <returns></returns>
public static bool RejectMessageBasedOnTenant(IMessageActivity activity, string currentTenant)
{
if (!String.Equals(ConfigurationManager.AppSettings["OFFICE_365_TENANT_FILTER"], TenantFilterSettingAny))
{
//#Scenario 1
return !string.Equals(ConfigurationManager.AppSettings["OFFICE_365_TENANT_FILTER"], currentTenant);
}
else
{
//Scenario 2
return false;
}
}
Its taken from this sample
The most reliable way right now is to implement authentication of users, as demonstrated in AuthBot, and then check the tenant-id of the logged-in user.
Related
The docs says:
Payable methods. We can allow methods to accept token transfer
together with the function call. This is done so that contracts can
define a fee in tokens that needs to be payed when they are used. By
the default the methods are not payable and they will panic if someone
will attempt to transfer tokens to them during the invocation. This is
done for safety reason, in case someone accidentally transfers tokens
during the function call.
https://github.com/near/near-sdk-rs
Does the token here mean only native near tokens?
Whey this function have to be payable? To pay near tokens for storage?
/// Transfer `amount` of tokens from the caller of the contract (`predecessor_id`) to
/// `new_owner_id`.
/// Act the same was as `transfer_from` with `owner_id` equal to the caller of the contract
/// (`predecessor_id`).
/// Requirements:
/// * Caller of the method has to attach deposit enough to cover storage difference at the
/// fixed storage price defined in the contract.
#[payable]
pub fn transfer(&mut self, new_owner_id: AccountId, amount: U128) {
// NOTE: New owner's Account ID checked in transfer_from.
// Storage fees are also refunded in transfer_from.
self.transfer_from(env::predecessor_account_id(), new_owner_id, amount);
}
https://github.com/near-examples/FT/blob/master/contracts/rust/src/lib.rs#L211
Does the token here mean only native near tokens?
Yes
Whey this function have to be payable? To pay near tokens for storage?
If you want this function to be able to accept deposit. How the deposit is going to be used is up to the contract to decide.
i am a beginner in signalR and Need to make an application where there are many users having many roles, and there should be three channels of sending notification to clients
1. Public (Used For All)
2. Private (Sending Notification to Single Person)
3. Group and Sub Group (Sending Notification to the persons who are member of some group or sub-group)
Problem is i am unable to understand the user differentiation in SignalR and not getting the concept of groups.
Anyone please Guide me
First of all, you can start to read the Microsoft documentation about the groups. Then you can read the authorization documentation so you would be able to create groups and manage users for each role.
What you can do is, when the client connects to the Hub, and assuming you know the users role (using the context and the authorization) you will add them to those 3 groups.
Then it is easy to send message to those groups, you have such examples everywhere in the stackOverflow and the internet.
Hope this helps you.
Code example:
/// <summary>
/// Called when a new connection is established with the hub.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task OnConnectedAsync()
{
// 1. Add the use to the public group
await this.Groups.AddToGroupAsync( this.Context.ConnectionId, "PublicGroup");
// 2. Add user to the private channel, single person
await this.Groups.AddToGroupAsync(this.Context.ConnectionId, this.Context.User.Identity.Name);
if (this.Context.User.IsInRole("Admin"))
{
// 3. Add the user to the Admin group
await this.Groups.AddToGroupAsync(this.Context.ConnectionId, "Admin");
}
// add to other groups...
await base.OnConnectedAsync();
}
I'm playing with Google Drive's API and I would know if I need to do the code bellow each time I need to use the API:
import "package:googleapis_auth/auth_browser.dart" as gauth;
import "package:googleapis/drive/v2.dart" as drive;
...
var clientid = new gauth.ClientId("xxx.apps.googleusercontent.com", null);
var scope = [drive.DriveApi.DriveScope];
gauth.createImplicitBrowserFlow(clientid, scope).then((gauth.BrowserOAuth2Flow flow) {
flow.clientViaUserConsent().then((gauth.AutoRefreshingAuthClient client) {
var drive_api = new drive.DriveApi(client);
// My code here.
}).catchError((e) => print(e));
});
...
Once client var generated, there is no way to recover it without to do these code lines each time?
I personally save the variable you called drive_api globally (in memory) and reuse it in my application (i.e. my webapp so yes it will run again when you reload the page). Some errors (I guess when the token needs to be refreshed, or if the permissions are revoked) might require you to re-run the whole flow. I think the trick is to run it "silently" after the page is loaded
flow.clientViaUserConsent(immediate: true)
by doing so, your "drive_api" variable will be loaded if the user already granted permission in previous sessions. For example I typically enable some buttons at this point
and if it fails (i sometimes add a "login button"), explicitly call (better do that on "on-click" to allow popup to appear)
flow.clientViaUserConsent()
Some doc for the immediate parameter:
/// If [immediate] is `true` there will be no user involvement. If the user
/// is either not logged in or has not already granted the application access,
/// a `UserConsentException` will be thrown.
///
/// If [immediate] is `false` the user might be asked to login (if he is not
/// already logged in) and might get asked to grant the application access
/// (if the application hasn't been granted access before).
I have developed a Managed Browser Helper Object (BHO). This works on all machines except one.
I have ensured that protected mode is off and UAC is also turned off on this machine.
This particular machine is Win Vista with IE 8.
I added some debug logs and message box in GetSite and Setsite. I do not see these logs or message box. I am assuming that these are not being called for some reason.
Is there some better way to debug my problem?
Thanks
Once it happens to me when I entered wrong COM object GUID. In 'must-have' interface 'IObjectWithSite' the definition must-be as follows:
/// <summary>
/// Interface to hook into IE
/// </summary>
[
ComImport(),
ComVisible(true),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352") // Defined here: http://msdn.microsoft.com/en-us/library/aa768186(v=vs.85).aspx
]
interface IObjectWithSite
{
/// <summary>
/// Function will register our program with actual browser
/// </summary>
/// <param name="pUnkSite"></param>
/// <returns></returns>
//[PreserveSig]
void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] object pUnkSite);
/// <summary>
/// Callers invoke this to retrieve the container site previously sent to SetSite().
/// This implementation handles the return of appropriate HRESULT per the
/// documented interface requirements for IObjectWithSite.
/// </summary>
/// <param name="riid">GUID for the interface requested of the site object</param>
/// <param name="ppvSite">Fill this with the site object if we find the interface through QI call</param>
void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvSite);
}//interface close
But since you sad that only one machine doesn't support it...
Is there a way my program can determine when it's running on a Remote Desktop (Terminal Services)?
I'd like to enable an "inactivity timeout" on the program when it's running on a Remote Desktop session. Since users are notorious for leaving Remote Desktop sessions open, I want my program to terminate after a specified period of inactivity. But, I don't want the inactivity timeout enabled for non-RD users.
GetSystemMetrics(SM_REMOTESESSION) (as described in http://msdn.microsoft.com/en-us/library/aa380798.aspx)
Here's the C# managed code i use:
/// <summary>
/// Indicates if we're running in a remote desktop session.
/// If we are, then you MUST disable animations and double buffering i.e. Pay your taxes!
///
/// </summary>
/// <returns></returns>
public static Boolean IsRemoteSession
{
//This is just a friendly wrapper around the built-in way
get
{
return System.Windows.Forms.SystemInformation.TerminalServerSession;
}
}
The following works if you want to know about YOUR application which is running in YOUR session:
BOOL IsRemoteSession(void)
{
return GetSystemMetrics( SM_REMOTESESSION );
}
But not in general for any process ID.
If you want to know about any arbitrary process which could be running in any arbitrary session then you can use the below method.
You can first convert the process ID to a session ID by calling ProcessIdToSessionId. Once you have the session ID you can use it to call: WTSQuerySessionInformation. You can specify WTSInfoClass as value WTSIsRemoteSession and this will give you the information about if that application is a remote desktop connection or not.
BOOL IsRemoteSession(DWORD sessionID)
{
//In case WTSIsRemoteSession is not defined for you it is value 29
return WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionID, WTSIsRemoteSession, NULL, NULL);
}