Created
August 18, 2024 17:51
-
-
Save Aketzu/9a704055f2f2b09cb68df14b0abb58bc to your computer and use it in GitHub Desktop.
Synchronization script from Kompassi users to Google Workspace
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# as gem google-apis-admin_directory_v1 | |
require "google/apis/admin_directory_v1" | |
require "googleauth" | |
require "googleauth/stores/file_token_store" | |
require "fileutils" | |
require 'securerandom' | |
require 'mail' | |
require 'httparty' | |
KOMPASSI_USER="user" | |
KOMPASSI_PASS="pass" | |
KOMPASSI_GROUP="event-labour-conitea" | |
GOOGLE_GROUP='[email protected]' | |
OOB_URI = "urn:ietf:wg:oauth:2.0:oob".freeze | |
APPLICATION_NAME = "Directory API Ruby Quickstart".freeze | |
CREDENTIALS_PATH = "google-credentials.json".freeze | |
TOKEN_PATH = "token.yaml".freeze | |
SCOPE = [Google::Apis::AdminDirectoryV1::AUTH_ADMIN_DIRECTORY_USER, Google::Apis::AdminDirectoryV1::AUTH_ADMIN_DIRECTORY_GROUP] | |
def normalize_email(str) | |
# This should match the way Kompassi normalizes non-ascii characters in email | |
str.downcase.gsub(/ /, '.').gsub(/[äå]/, 'a').gsub(/[ö]/, 'o').gsub(/[é]/, 'e') | |
end | |
# Get group members from Kompassi | |
url = "https://kompassi.eu/api/v1/groups/#{KOMPASSI_GROUP}/members" | |
resp = HTTParty.get(url, basic_auth: { username: KOMPASSI_USER, password: KOMPASSI_PASS }) | |
kompassi_members = {} | |
resp.each do |u| | |
event_mail = normalize_email(u['first_name'] + "." + u['surname'] + "@event.fi") | |
u['event_mail'] = event_mail | |
kompassi_members[event_mail] = u | |
end | |
# Either use stored authentication or prompt for web auth | |
def authorize | |
client_id = Google::Auth::ClientId.from_file CREDENTIALS_PATH | |
token_store = Google::Auth::Stores::FileTokenStore.new file: TOKEN_PATH | |
authorizer = Google::Auth::UserAuthorizer.new client_id, SCOPE, token_store | |
user_id = "default" | |
credentials = authorizer.get_credentials user_id | |
if credentials.nil? | |
url = authorizer.get_authorization_url base_url: 'http://localhost' | |
puts "Open the following URL in the browser and enter the resulting code after authorization:\n" + url | |
code = gets | |
credentials = authorizer.get_and_store_credentials_from_code( | |
user_id: user_id, code: code, base_url: 'http://localhost' | |
) | |
end | |
credentials | |
end | |
# Google authentication | |
# Create new project as target workspace owner in https://console.cloud.google.com/ | |
# Enable "Admin SDK API" and get OAuth 2.0 client id file (google-credentials.json) from credentials page | |
@gapi = Google::Apis::AdminDirectoryV1::DirectoryService.new | |
@gapi.client_options.application_name = APPLICATION_NAME | |
@gapi.authorization = authorize | |
# Create new user to Google Workspace | |
def createuser(firstname, lastname, primary_email, secondary_email, phone) | |
name = Google::Apis::AdminDirectoryV1::UserName.new( | |
given_name: firstname, | |
family_name: lastname | |
) | |
password = SecureRandom.base64(9) | |
usr = Google::Apis::AdminDirectoryV1::User.new( | |
primary_email: primary_email, | |
name: name, | |
password: password, | |
change_password_at_next_login: true, | |
emails: [ { address: secondary_email, type: 'home' } ], | |
recovery_email: secondary_email, | |
recovery_phone: phone.gsub(/^0/, '+358') | |
) | |
resp = nil | |
begin | |
resp = @gapi.insert_user(usr) | |
mail = Mail.new do | |
from 'IT Support <[email protected]>' | |
to secondary_email | |
subject 'New account created' | |
body "Your Google account has been created.\n\nUsername: #{primary_email}\nPassword: #{password}\n" | |
end | |
mail['charset'] = 'UTF-8' | |
mail.delivery_method :sendmail | |
mail.deliver | |
rescue Google::Apis::ClientError => ex | |
case ex.status_code | |
when 412 | |
puts "Invalid data" | |
when 409 | |
puts "Already added" | |
else | |
puts "Unknown error: " + ex.to_s | |
end | |
end | |
resp | |
end | |
# Get current Google Workspace users | |
def getusers() | |
pagetok = nil | |
users = {} | |
loop do | |
response = @gapi.list_users(domain: "event.fi", order_by: "email", page_token: pagetok) | |
response.users.each do |user| | |
users[user.primary_email] = user | |
end | |
pagetok = response.next_page_token | |
break if !pagetok | |
end | |
users | |
end | |
# Add Google user to Google group | |
def groupadd(group, user) | |
begin | |
puts "Adding #{user.primary_email} to #{group}" | |
response = @gapi.insert_member(group, user) | |
#pp response | |
rescue Google::Apis::ClientError => ex | |
case ex.status_code | |
when 412 | |
puts "Unknown user" | |
when 409 | |
puts "Already added" | |
else | |
puts "Unknown error: " + ex.to_s | |
end | |
end | |
end | |
# All users | |
google_users = getusers | |
# Current Google group members | |
resp = @gapi.list_members(GOOGLE_GROUP) | |
group_members = resp.members.map {|m| m.email } | |
# Current members in Kompassi | |
targetgroup = kompassi_members.keys | |
# Add missing users to group in Google | |
(targetgroup - group_members).each do |usr| | |
unless google_users.keys.include? usr | |
kusr = kompassi_members[usr] | |
puts "Create #{usr}" | |
resp = createuser(kusr['first_name'], kusr['surname'], kusr['event_mail'], kusr['email'], kusr['phone']) | |
google_users[usr] = resp | |
end | |
groupadd GOOGLE_GROUP, google_users[usr] | |
end | |
# Check and unsuspend users | |
targetgroup.each do |usr| | |
gusr = google_users[usr] | |
next unless gusr.suspended | |
puts "Unsuspend #{usr}" | |
gusr.suspended = false | |
resp = @gapi.update_user(usr, gusr) | |
end | |
# Removing users from group is currently done manually |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment