From ff656b0389cc32ed470141d07025e7c697f452e4 Mon Sep 17 00:00:00 2001 From: mischa Date: Wed, 10 May 2023 20:23:28 +0200 Subject: [PATCH] Initial commit, script for Frontegg API --- .gitignore | 2 ++ claimdomain.pl | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ talon.cnf.sample | 5 +++ 3 files changed, 100 insertions(+) create mode 100644 .gitignore create mode 100755 claimdomain.pl create mode 100644 talon.cnf.sample diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6739550 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +token.txt +*.cnf diff --git a/claimdomain.pl b/claimdomain.pl new file mode 100755 index 0000000..896edb4 --- /dev/null +++ b/claimdomain.pl @@ -0,0 +1,93 @@ +#!/usr/bin/env perl +# +# Copyright 2023, Mischa Peters , Talon Cyber Security. +# claimfdomain.pl +# Version 1.0 - 20230610 +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# Claim Domain force-validate for Talon via Frontegg +# +use 5.026; +use strict; +use warnings; +use autodie; +use Config::Tiny; +use File::Basename; +use File::stat; +use POSIX qw(strftime); +use HTTP::Tiny; +use JSON::PP; + +my $USAGE = <<"END_USAGE"; +Usage: $0 +END_USAGE + +my $domain = $ARGV[0]; +$domain || die($USAGE); + +my @CONFIG_FILES = grep { -e } ('./talon.cnf', './.talon.cnf', '/etc/talon.cnf', "$ENV{'HOME'}/.talon.cnf", "$ENV{'HOME'}/talon.cnf"); +my $config = Config::Tiny->read($CONFIG_FILES[-1], 'utf8') || die("Uable to find talon.cnf"); +my $FRONTEGG_URL = $config->{talon}{FRONTEGG_URL}; +my $FRONTEGG_CLIENTID = $config->{talon}{FRONTEGG_CLIENTID}; +my $FRONTEGG_KEY = $config->{talon}{FRONTEGG_KEY}; +my $TTL = "82800"; +my $STORE = dirname($0) . "/token.txt"; + +my %HEADERS = ("Accept" => "application/json", "Content-Type" => "application/json", "Cache-Control" => "no-cache"); +my $request = HTTP::Tiny->new('default_headers' => \%HEADERS); +my $json = JSON::PP->new; +my $url; +my $body; +my $response; +my $token; + +# +# POST authenticate and get token +# + +if (-e $STORE) { + my $mtime = stat($STORE)->mtime(); + if ((time() - $mtime) < $TTL) { + print "Using stored token\n"; + open my $fh_token, '<', $STORE; + $token = <$fh_token>; + close $fh_token; + } else { + unlink($STORE); + } +} +if (! -e $STORE) { + print "Fetching new token\n"; + $url = "${FRONTEGG_URL}/auth/vendor/"; + print "$url\n"; + $body = JSON::PP->new->space_after->encode({clientId => $FRONTEGG_CLIENTID, secret => $FRONTEGG_KEY}); + $response = $request->post($url, {'content' => $body}); + $token = $json->decode($response->{'content'})->{'token'}; + + print "$response->{'status'} $response->{'reason'}\n"; + print "Received TOKEN: ${token}\n"; + + open my $fh_token, '>', $STORE; + print $fh_token "$token"; + close $fh_token; +} + +# +# PUT force-validate +# +$url = "${FRONTEGG_URL}/team/resources/sso/v1/configurations/domains/${domain}/force-validate"; +print "$url\n"; +$body = JSON::PP->new->space_after->encode({validated => \1}); +$response = $request->put($url, {'headers' => {"Authorization" => "Bearer $token"}, 'content' => $body}); +print "$response->{'status'} $response->{'reason'}\n"; diff --git a/talon.cnf.sample b/talon.cnf.sample new file mode 100644 index 0000000..0ec15cb --- /dev/null +++ b/talon.cnf.sample @@ -0,0 +1,5 @@ +[talon] +# Frontegg URL, CLIENTID and KEY tokens +FRONTEGG_URL = https://api.us.frontegg.com +FRONTEGG_CLIENTID = +FRONTEGG_KEY =