Wednesday, November 25, 2020

adding share links

Used this medium post which links to this codepen as a starting point for implementing share over email (a mailto link), copy to clipboard, and sharing via facebook, twitter and linkedin. Our code is on my (private) github repo.

Monday, November 23, 2020

firebase authentication tutorial without the need to set up billing - but ...

The official firebase auth tutorial from Google needs you to set up billing. This tutorial made by the community doesn't need you to set up billing. 

But since it's based on old versions of libs, with the current (newer) version of falcon, gives error at

from falcon.version import __version__  # NOQA


Saturday, November 21, 2020

exporting users from a large google group

We wanted to export all the current subscribers to a large google group (>30k), and the export members functionality doesn't seem to work even for owners of the group*. So, brute-forcing to the rescue. Used SikuliX to automate the process of going to each page of subscribers, select all, copy, paste into a text file, save, and move to the next page of 100 users after sorting the users by join date earliest first. Since I didn't have opencv installed using apt on this machine and didn't want to break any opencv3.x configuration I might have done, used hard-coded locations on screen instead of Sikuli's feature detection. So, I had to manually click popups to ensure proper wait times after each operation. The script looked like this - 
 
i=18 #the page from which we're starting
while(True):  
  dragDrop(Location(721,265), Location(821,365)) #drag at the top end
  type("a",KeyModifier.CTRL)        #Ctrl a - select all
  type("c",KeyModifier.CTRL)        #Ctrl c - copy
  click(Location(1301,565))         #click inside text editor
  type("v",KeyModifier.CTRL)        #Ctrl v - paste
  popup("waiting for paste")
  click(Location(1336,450))         #click save toolbar icon
  popup("waiting for save dialog")
  click(Location(726,102))          #click on save dialog
  type(str(i))                      #save filename = pagenumber
  popup("waiting for save")
  click(Location(1311,720))
  popup("waiting for creating new file")
  click(Location(1276,450))
  i=i+1
  click(Location(1207,232))
  popup("waiting for pageload")

Then the following python script helped parse it into a csv - 
#!/usr/bin/env python3
import sys
count = 0
for line in sys.stdin:
    #print(line)
    if line.startswith("Profile image"):
        Profileim = line
        username = next(sys.stdin).strip()
        ExtOrRadiosaiId = next(sys.stdin).strip()
        if (ExtOrRadiosaiId == "External"):
            emailid = next(sys.stdin).strip()
        else:
            emailid = ExtOrRadiosaiId
        print('{},{}'.format(username, emailid))
        count = count + 1
        
print(count)

by calling it as 
cat * | parsedumpinfile.py > mycsvfilename.csv

Earlier, I had thought about importing the txt files into a spreadsheet and processing the fields there, creating a formula to copy every sixth (email id) to column next to username, taking care to select six + six + six before dragging down, using a modified method from
to select every sixth row. Or using autoformat in LibreOffice Calc, which looks like this.



But the python script above is much easier and cleaner, of course. 

*Edit - For a group inside a GSuite account, this method using Directory API might work. But GSuite api and googlegroups.com api are different. Only brute-forcing works for googlegroups.com :)

Thursday, November 19, 2020

low cost video capture and streaming

How times have changed since the days of the $1000 Matrox RT2000 which we purchased in 1999-2001. This HDMI frame-grabber costs only $35. But it's just a simple HDMI to USB conversion, raw frames with no encoding. So the PC needs to be capable enough to handle the high-bitrate stream and do encoding on the fly. Since these are generally used by gamers for streaming, beefy machines are not an issue. And OBS Studio is the software of choice. Then, OBS Studio has "BrowserSource" which can be used to capture - no hardware required, except OBS Studio's own hardware requirements

All these could be possibilities if Google goes ahead with its plan to remove access to Google Meet recording ability for Education customers.

Sunday, November 15, 2020

creating and distributing private keys as pem files

I wanted to create and distribute some keys as filename.pem for people to ssh into a server like
ssh -i filename.pem username@machine.name
as is done for qwiklabs. With a bit of digging, found that the pem file is actually the private key and not the public key, and the whole process would be as follows.

setting up letsencrypt certificates for multiple virtual hosts with apache

The preferred method is to just run certbot multiple times with each required domain, as mentioned at https://www.digitalocean.com/community/tutorials/how-to-set-up-let-s-encrypt-certificates-for-multiple-apache-virtual-hosts-on-ubuntu-14-04 

So, sudo certbot --apache -d example.com -d www.example.com

and later

sudo certbot --apache -d example2.com -d www.example2.com

or whatever. And then add to root's cron,

15 3 * * * /usr/bin/certbot renew --quiet

which checks every morning at 3:15 AM and renews any certs with validity less than 30 days more.

Saturday, November 14, 2020

troubleshooting a ruby on rails web server

To troubleshoot a web server running ruby on rails, checked the history of the ssh login I had been supplied (up arrow, up arrow, etc) and found that the admin had started rails using

rails s -p 5001 -b <ipaddress> -d
rails s -p 3001 -b <ipaddress> -d

for the two sites, and that they were running apache to proxy these ports to the two websites. The sites-available had virtual hosts configured like

DocumentRoot /full/path/to/rubyonrails/project/production
...
ProxyPass / http://xx.yy.zz.ww:5001/
ProxyPassReverse / http://xx.yy.zz.ww:5001/

and so on.

Found that the apache sites-enabled directory had some wrong entries + duplicate entries, which were causing apache to go back to the default configuration with no virtual servers, hence the various errors. There may be some issues with apache, serveralias and rails as mentioned here,

https://serverfault.com/questions/300226/serving-rails-through-apache-using-proxypass

that it was serving up the test page when the main domain was a server alias. So, I created a separate virtual server conf file in sites-available, with main-domain-name.conf which solved that issue. Then ran certbot for both domains for getting letsencrypt certificates.

Tuesday, November 10, 2020

debugging the radiosai google assistant action's audio search issue

Going step by step, found that dialogflow was returning the value "search" instead of the words the user was using. After going through the codelabs example at https://codelabs.developers.google.com/codelabs/actions-1/ ,  saw that after the dialogflow intent was edited with new training phrases without template mode, I needed to delete the old phrases, and then retrain before the changes would take effect, as per


Now, instead of the word "search", dialogflow returns the correct user phrase, as in the screenshot below.

image.png

After submitting this version as a release, the corrected version is live now. 

Monday, November 09, 2020

test of creating a free tier instance, using it for multiple users like students

Though GCP's "recommended way" of adding SSH keys is quite convoluted, found that I could use my usual method to add my key, and use PasswordAuthentication yes in /etc/sshd-config to allow password-based logins for users.

As can be seen in this techrepublic post, the way to prevent newly created users from seeing each others' directories is to edit the /etc/adduser.conf file, changing the default home directory permissions from 755 to 750. We can of course do this manually with sudo chmod 750 /home/user1 and so on.

Then, using a "Free Tier" f1 micro instance, someone can do text-based teaching like conducting a C lab after installing the required build tools like apt install gcc or apt-get install build-essential. Currently the specs of a free tier compute instance are -

1 F1-micro instance per month
Scalable, high-performance virtual machines.

1 non-preemptible f1-micro VM instance per month in one of the following US regions:
Oregon: us-west1
Iowa: us-central1
South Carolina: us-east1

30 GB-months HDD
5 GB-month snapshot storage in the following regions:
Oregon: us-west1
Iowa: us-central1
South Carolina: us-east1
Taiwan: asia-east1
Belgium: europe-west1

1 GB network egress from North America to all region destinations (excluding China and Australia) per month.

Saturday, November 07, 2020

Azure AD guest account and how to close an azure account

There are conflicting posts all around, saying that one can only remove subscriptions and not close an Azure account once it is opened. Since I had used this from a test domain, it was an "unmanaged organization" 

https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/users-close-account

  1. Sign in to close your account, using the account that you want to close.

  2. On My data requests, select Close account.

    My data requests - Close account

I used this to remove the test account I had created to delegate permissions for an app being developed by a third-party. The delegation of permissions via Azure Active Directory implies that the guest user has to switch directory to the directory of the current resource in the Azure portal, and then the guest user would have view access to the current directory name (and probably more). 



Monday, November 02, 2020

diffuse not opening - needs python2

 The graphical diff tool Diffuse was not opening - running it from the terminal gave the error message 

diffuse
  File "/usr/bin/diffuse", line 74
    print codecs.encode(unicode(s, 'utf_8'), sys.getfilesystemencoding())
               ^
SyntaxError: invalid syntax

Apparently this is because diffuse is written for python2.

So, edited the hashbang for /usr/bin/diffuse to use /usr/bin/env python2 instead of /usr/bin/env/ python, works now.

#!/usr/bin/env python2