Reset a Managed Chrome Device with SDK using Google Apps Script - google-admin-sdk

I'm attempting to create a dashboard for admins to allow them to reset a chrome device managed by GoogleAdmin using google apps script.
I don't see any way to perform a reset using Admin SDK API. Can this be done?

If you want to deprovision and/or disable a ChromeOS device
The supported actions when using the Directory API, according to the documentation here are:
deprovision: Remove a device from management that is no longer active, being resold, or is being submitted for return / repair, use the deprovision action to dissociate it from management.
disable: If you believe a device in your organization has been lost or stolen, you can disable the device so that no one else can use it. When a device is disabled, all the user can see when turning on the Chrome device is a screen telling them that it’s been disabled, and your desired contact information of where to return the device.
Taking this into account, this is how the request would look like:
POST https://admin.googleapis.com/admin/directory/v1/customer/{customerId}/devices/chromeos/{resourceId}/action
If you want to reboot and/or remote powerwash a ChromeOS device
However, if you simply plan on doing a powerwash or a reboot, you can make use of the below information:
REBOOT: Reboot the device. Can only be issued to Kiosk and managed guest session devices.
REMOTE_POWERWASH: Wipes the device by performing a power wash. Executing this command in the device will remove all data including user policies, device policies and enrollment policies.
Warning: This will revert the device back to a factory state with no enrollment unless the device is subject to forced or auto enrollment. Use with caution, as this is an irreversible action!
Taking this into account, this is how the request would look like:
POST https://admin.googleapis.com/admin/directory/v1/customer/{customerId}/devices/chromeos/{deviceId}:issueCommand
Apps Script
As for applying any of these in Apps Script, you will have to add the Admin SDK API advanced service and choose the directory _v1 version and simulate any of the above requests.
Code
Assuming you want to remote powerwash a device, you will have to write something similar to this:
let resource = {
YOUR_RESOURCE_HERE;
"commandType": "REMOTE_POWERWASH"
};
let customerId = 'CUSTOMER_ID';
let deviceId = 'DEVICE_ID';
AdminDirectory.Customer.Devices.Chromeos.issueCommand(resource, customerId, deviceId);
Not what you are looking for?
You can simply create a feature request on Google's Issue Tracker and provide the details with regards to your task by filling in the form here.
Reference
Directory API Manage ChromeOS Devices.

Related

Amazon Connect Stop Call Recording

Is it possible to stop call recordings in Amazon Connect so the customer and agent can discuss sensitive material without being recorded?
I am aware of the set call recording behaviour blocks, but they don't seem to work on a call that has already been started with an agent with call recording enabled. Transferring to another contact flow with the recording type set to none doesn't seem to make a difference and the call carries on being recorded.
I am aware of the sample workflow Sample secure input with agent as outlined in this AWS blog https://aws.amazon.com/premiumsupport/knowledge-center/disable-recording-amazon-connect. This does work, however it relies on the customer entering payment details whilst the agent is on hold - preventing the agent and customer from having a sensitive conversation.
It seems the only way to stop recording once it has been enabled is to put the agent on hold?
Do not know if you have not solved your issue yet, but amazon has update their Amazon Connect API that would allow you to suspend the recording.
Boto3 implementation
response = client.suspend_contact_recording(
InstanceId='string',
ContactId='string',
InitialContactId='string'
)
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/connect.html#Connect.Client.suspend_contact_recording
They have also allow you to Start, Pause, Stop. (
We have just started to review this for a POC, turn recording off be default for a group of queues. Allow to Agents to start and stop and pause recording as needed.
You can also read this in an Amazon Blog post that should be able to help you fully implement the solution.
https://aws.amazon.com/blogs/contact-center/pausing-and-resuming-call-recordings-with-a-new-api-in-amazon-connect/#:~:text=is%20not%20recorded.-,End%20the%20call.,you%20start%20and%20stop%20it.
After speaking with Architects at AWS, the desired and designed for solution is to have the customer automatically enter sensitive information with the agent on hold and call recording turned off to remain PCI compliant.
If that is not an option there are workarounds possible that go against the way Amazon Connect has been designed. In order to turn off call recording once it has been enabled on a call, a new contact ID must be established. To do this you would need to transfer the user to your external phone number again or transfer to a queue and disable call recording in that new flow.
This brings in extra issues around how to get the customer back to the original agent once the sensitive information has been discussed. It also means you would potentially have 3+ contact IDs for the same transaction, with call recording spread across them.

Inter-Process communication in a microservices architecture

we are moving from monolithic to microservice architecture application, we're still in planning phase and we want to know what is the best practices of building it.
suppose we have two services :
User
Device
getUserDevices(UserId)
addDevice(DeviceInfo, UserId)
...
Each user has multiple devices
what is the most common, cleaner and proper way of asking the server to get all user devices ?
1- {api-url}/User/{UserId}/devices
needs another HTTP request to communicate with Device service.
for user X, get linked devices from User service.
// OR
2- {api-url}/Device/{UserId}/devices
for user X, get linked devices from Device service.
There are a lot of classic patterns available to solve such problems in Microservices. You have 2 microservices - 1 for User (Microservice A) and 1 for Device (Microservice B). The fundamental principle of a microservice is to have a separate database for each of the microservice. If any microservice wants to talk to each other (or to get data from another microservice), they can but they would do it using an API. Another way for communication between 2 microservices is by events. When something happens in Microservice A, it will raise an event and push it to a central event store or a message queue and Microservice B would subscribe to some or all of the events emitted by A.
I guess in your domain, A would have methods like - Add/Update/Delete a User and B would have Add/Update/Delete a device. Each user can have its own unique id and other data fields like Name, Address, Email etc. Each device can have its own unique id, a user id, and other data fields like Name, Type, Manufacturer, Price etc. Whenever you "Add" a device, you can send a POST request or a command (if you use CQRS) to Device Microservice with the request containing data about device + user-id and it could raise an event called "DeviceAdded". It can also have events corresponding to Update and Delete like "DeviceUpdated" and "DeviceRemoved". The microservice A can subscribe to events - "DeviceAdded", "DeviceRemoved", and "DeviceUpdated" events emitted by B and whenever any such event is raised, it will handle that event and denormalize that event into its own little database of Devices (Which you can call UserRelationships). In future, it can listen to events from other microservices too (so your pattern here would be extensible and scalable).
So now to get all devices owned by a user, all you have to do is make an end-point in User Microservice like "http://{microservice-A-host}:{port}/user/{user-id}/devices" and it will return you a list of the devices by querying for user-id in its own little database of UserRelationships which you must have been maintaining through events.
Good Reference is here: https://www.nginx.com/blog/event-driven-data-management-microservices/
it may really be either way, but to my liking, I would choose to put it under /Devices/{userId}/devices as you are looking for the devices given the user id. I hope this helps. Have a nice one!
You are requesting a resource from a service, resource being a device and service being a device service.
From a rest standpoint, you are looking for a resource and your service is providing various methods to manipulate that resource.
The following url can be used.
[GET] ../device?user_id=xyz
And device information can be fetched via ../device/{device_id}
Having said that, if you had one service that is providing for both user and device data than the following would have made sense.
[GET] ../user/{userId}/device
Do note that this is just a naming convention and you can pick what suits best for you, thing is pick one and hold onto it.
When exposing the api consistency is more important.
One core principle of the microservice architecture is
defining clear boundaries and responsibilities of each microservice.
I can say that it's the same Single Responsibility Principle from SOLID, but on macro level.
Сonsidering this principle we get:
Users service is responsible for user management/operations
Devices service is responsible for operations with devices
You question is
..proper way of asking the server to get all user devices
It's 100% responsibility of the Devices service and Users service nothing know about devices.
As I can see you thinking only in routing terms (yes API consistency is also important).
From one side the better and more logical URL is /api/users/{userId}/devices
- you try to get user's devices, these devices belong to user.
From other side you can use the routes like /api/devices/user/{userId} (/api/devices/{deviceId}) and that can be more easily processed
by the routing system to send a request to the Devices service.
Taking into account other constraints you can choose the option that is right for your design.
And also small addition to:
needs another HTTP request to communicate with Device service.
in the architecture of your solution you can create an additional special and separate component that routes the requests to the desired microservice, not only direct calls are possible from one microservice to another.
You should query the device service only.
And treat the user id like a filter in the device service. For eg: you should search on userid similar to how you would search device based on device type. Just another filter
Eg : /devices?userid=
Also you could cache some basic information of user in device service, to save round trips on getting user data
With microservices there is nothing wrong with both the options. However the device api makes more sense and further I'll prefer
GET ../device/{userId}/devices
over
GET ../device?user_id=123
There are two reasons:
As userId should already be there with devices service you'll save one call to user service. Otherwise it'll go like Requester -> User service -> Device Service
You can use POST ../device/{userId}/devices to create new device for particular user. Which looks more restful then parameterized URL.

CoRegisterClassObject returns error (session 0?)

A customer is running one of our programs, usually run as a service, as an application. The customer is getting the following error on CoRegisterClassObject():
The class is configured to run as a security id different from the caller.
It looks like some type of session 0 error, but why should CoRegisterClassObject() care about session 0? COM should allow both services (session 0) and apps (session > 0) and not care what registers what, shouldn't it?
Also, I don't like the fact that it's not in the list of errors returnable by CoRegisterClassObject(), as per the Microsoft doc webpage.
The error code in question is CO_E_WRONG_SERVER_IDENTITY (0x80004015).
Per this page:
COM security frequently asked questions
Q6 Why does CoRegisterClassObject return CO_E_WRONG_SERVER_IDENTITY? When launching my ATL 1.1 server service as an .exe file, I receive CO_E_WRONG_SERVER_IDENTITY from CoRegisterClassObject. (The class is configured to run as a security ID different from the caller.) This seems to occur whether I skip the CoInitializeSecurity or not. It fails running as a service or as an .exe file.
A. Many services are debugged by running them as console applications in the interactive user identity. Because the service is already registered to run in a different identity (configurable by the Services control panel applet), OLE fails the CoRegisterClassObject and RunningObjectTable::Register(ROTFLAGS_ALLOWANYCLIENT) calls by returning CO_E_WRONG_SERVER_IDENTITY to enforce security and to prevent malicious servers from spoofing the server. To debug by running in the interactive user's identity, make the following changes in the server's registry entries to prevent these failures:
• To prevent CoRegisterClassObject failure, remove the following named value:
[HKEY_CLASSES_ROOT\APPID\{0bf52b15-8cab-11cf-8572-00aa00c006cf}]
"LocalService"="HelloOleServerService"
• To prevent a IRunningObjectTable::Register(ROTFLAGS_ALLOWANYCLIENT) failure, follow these steps:
Remove the following named value:
[HKEY_CLASSES_ROOT\APPID\{0bf52b15-8cab-11cf-8572-00aa00c006cf}]
"LocalService"="HelloOleServerService"
Then add the following named value:
[HKEY_CLASSES_ROOT\APPID\{0bf52b15-8cab-11cf-8572-00aa00c006cf}]
"RunAs"="Interactive User"
You muist restore the modified registry entries after debugging.
I am assuming you would have to replace {0bf52b15-8cab-11cf-8572-00aa00c006cf} with your COM object's actual CLSID instead.

GetUserNameExA function cannot give user Details at system startup time(GINA)?

i am using c++ win32 API.
i tried to get user details using GetUserNameExA();
i have use this function into system logondialog source(GINA).
in my logfile,it gives
CN=ComputerName,CN=Computers,DC=JEGAN,DC=COM".
But it's used after logon on to system,at that time it gives user details like "CN=sanju,CN=USERS,DC=JEGAN,DC=COM" in my other solution.
i want user details only,but it gives system details at the logon time,how can i achieve user details at logontime?
note: i have already tried ADSI,LDAP functions & directoryservices cant able to use.so suggest any other system functions.
David is correct - the GINA DLL is loaded by the WinLogon.exe process. Check Task Manager and you'll see that WinLogon.exe runs as Local System. The GetUserName and GetUserNameEx functions provide information about the identity for the current thread:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx
From a 20,000 foot view, after a user's credentials have been validated, the GINA notifies all Network Providers of the successful login. After this, it loads the user's profile and creates the user's shell (Explorer.exe) which is then displayed.
You might try using a Network Provider instead. They are fully supported up through Windows 8 and multiple NPs can be defined for the system so you won't run into the 'chaining' issues that GINAs have.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa378775.aspx
The NPLogonNotify function will receive the user's cleartext name, domain and password (sometimes you'll receive a UPN as username in which case the domain is blank). You can use this information as is, perform LDAP-based lookups to AD or use LogonUser & ImpersonateLoggedOnUser before calling GetUserNameEx. Be extremely careful with this last approach since network providers run as Local system within the WinLogon.exe process. Always call RevertToSelf and CloseHandle to undo/clean up the previous calls.
The only (quite quirky) workaround for what you are trying to do is to log on some other user account on the side which has access to the domain and can thus query user details (don't remember the permissions needed in detail, though). Otherwise I'd suggest you go with Gregg's answer.
With a thread impersonated as such user you should then be able to query the information for the user that you are going to log on (how do you even know by that time?) via NetUserGetInfo() and friends. Choose the USER_INFO_* struct that best suits your needs and simply ask the domain server for the information. This should also work on earlier and later systems (the functionality, not the GINA itself).

Exchange Web Services, try to use ExchangeImpersonationType

I am trying to use EWS, first time trying to use the ExchangeServiceBinding. The code I am using is below:
_service = new ExchangeServiceBinding();
//_service.Credentials = new NetworkCredential(userName, userPassword, this.Domain);
_service.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
_service.Url = this.ServiceURL;
ExchangeImpersonationType ei = new ExchangeImpersonationType();
ConnectingSIDType sid = new ConnectingSIDType();
sid.PrimarySmtpAddress = this.ExchangeAccount;
ei.ConnectingSID = sid;
_service.ExchangeImpersonation = ei;
The application is an aspnet 3.5 trying to create a task using EWS. I have tried to use impersonation because I will not know the logon user's domain password, so I thought impersonation would be the best fit. Any thoughts on how I can utilize impersonation? Am I setting this correctly, I get an error while trying to run my application. I also tried without impersonation just to try to see if I can create a task, no luck either. Any help would be appreciated. Thanks.
Without broader context of your code snip, I can't tell for sure what's wrong, but here are a few things you might find useful...
You mention you had trouble connecting without impersonation.
I'm assuming you are using Exchange Server 2007 SP1, yes?
Do you have a mailbox for which you do know the username and password? If so, consider trying to connect to that mailbox, just to see if you can send an email or query for inbox count. That will help verify your connection at least.
As to exchange impersonation,
have the permissions been set on the Client Access Server (CAS) to enable impersonation?
Have the permissions been set on either the mailbox or mailbox database (containing the mailbox you are attempting to access)?
are you in a cross-forest scenario that requires additional trust relationships?
If not, that might explain why you cannot connect.
Some links you might find useful
Configuring (http://msdn.microsoft.com/en-us/library/bb204095.aspx)
Using Exchange impersonation (http://msdn.microsoft.com/en-us/library/bb204088.aspx)
Access multiple resource mailboxes (http://msexchangeteam.com/archive/2007/12/13/447731.aspx)