Skip to content

Instantly share code, notes, and snippets.

@Aketzu
Created August 18, 2024 17:51
Show Gist options
  • Save Aketzu/9a704055f2f2b09cb68df14b0abb58bc to your computer and use it in GitHub Desktop.
Save Aketzu/9a704055f2f2b09cb68df14b0abb58bc to your computer and use it in GitHub Desktop.
Synchronization script from Kompassi users to Google Workspace
#!/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