allow for custom 2FA, #1223

This commit is contained in:
larshp 2018-03-03 09:06:21 +00:00
parent 8d6f507cb7
commit a6e28f4337
5 changed files with 125 additions and 99 deletions

View File

@ -10,7 +10,6 @@ CLASS zcl_abapgit_2fa_auth_base DEFINITION
ALIASES: ALIASES:
authenticate FOR zif_abapgit_2fa_authenticator~authenticate, authenticate FOR zif_abapgit_2fa_authenticator~authenticate,
supports_url FOR zif_abapgit_2fa_authenticator~supports_url, supports_url FOR zif_abapgit_2fa_authenticator~supports_url,
get_service_id_from_url FOR zif_abapgit_2fa_authenticator~get_service_id_from_url,
is_2fa_required FOR zif_abapgit_2fa_authenticator~is_2fa_required, is_2fa_required FOR zif_abapgit_2fa_authenticator~is_2fa_required,
delete_access_tokens FOR zif_abapgit_2fa_authenticator~delete_access_tokens, delete_access_tokens FOR zif_abapgit_2fa_authenticator~delete_access_tokens,
begin FOR zif_abapgit_2fa_authenticator~begin, begin FOR zif_abapgit_2fa_authenticator~begin,
@ -94,11 +93,6 @@ CLASS ZCL_ABAPGIT_2FA_AUTH_BASE IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD get_service_id_from_url.
rv_id = 'UNKNOWN SERVICE'. " Please overwrite in subclasses
ENDMETHOD.
METHOD is_2fa_required. METHOD is_2fa_required.
rv_required = abap_false. rv_required = abap_false.
ENDMETHOD. ENDMETHOD.

View File

@ -12,7 +12,7 @@ CLASS zcl_abapgit_2fa_auth_registry DEFINITION
"! @parameter ro_authenticator | Found authenticator instance "! @parameter ro_authenticator | Found authenticator instance
"! @raising lcx_2fa_unsupported | No authenticator found that supports the service "! @raising lcx_2fa_unsupported | No authenticator found that supports the service
get_authenticator_for_url IMPORTING iv_url TYPE string get_authenticator_for_url IMPORTING iv_url TYPE string
RETURNING VALUE(ro_authenticator) TYPE REF TO zif_abapgit_2fa_authenticator RETURNING VALUE(ri_authenticator) TYPE REF TO zif_abapgit_2fa_authenticator
RAISING zcx_abapgit_2fa_unsupported, RAISING zcx_abapgit_2fa_unsupported,
"! Check if there is a two factor authenticator available for the url "! Check if there is a two factor authenticator available for the url
"! @parameter iv_url | Url of the repository / service "! @parameter iv_url | Url of the repository / service
@ -52,17 +52,26 @@ CLASS ZCL_ABAPGIT_2FA_AUTH_REGISTRY IMPLEMENTATION.
METHOD class_constructor. METHOD class_constructor.
DEFINE _register.
CREATE OBJECT li_authenticator TYPE &1. DATA: lt_sub TYPE seo_relkeys,
ls_sub LIKE LINE OF lt_sub,
li_authenticator TYPE REF TO zif_abapgit_2fa_authenticator,
lo_class TYPE REF TO cl_oo_class.
TRY.
lo_class ?= cl_oo_class=>get_instance( 'ZCL_ABAPGIT_2FA_AUTH_BASE' ).
lt_sub = lo_class->get_subclasses( ).
LOOP AT lt_sub INTO ls_sub.
CREATE OBJECT li_authenticator TYPE (ls_sub-clsname).
INSERT li_authenticator INTO TABLE gt_registered_authenticators. INSERT li_authenticator INTO TABLE gt_registered_authenticators.
END-OF-DEFINITION. ENDLOOP.
CATCH cx_class_not_existent.
* class in local report
CREATE OBJECT li_authenticator TYPE zcl_abapgit_2fa_github_auth.
INSERT li_authenticator INTO TABLE gt_registered_authenticators.
ENDTRY.
DATA: li_authenticator TYPE REF TO zif_abapgit_2fa_authenticator.
" If there are new authenticators these need to be added here manually.
" I do not think there is an equivalent to SEO_INTERFACE_IMPLEM_GET_ALL for local classes
" without invoking the compiler directly.
_register: zcl_abapgit_2fa_github_auth.
ENDMETHOD. ENDMETHOD.
@ -71,7 +80,7 @@ CLASS ZCL_ABAPGIT_2FA_AUTH_REGISTRY IMPLEMENTATION.
LOOP AT gt_registered_authenticators ASSIGNING <li_authenticator>. LOOP AT gt_registered_authenticators ASSIGNING <li_authenticator>.
IF <li_authenticator>->supports_url( iv_url ) = abap_true. IF <li_authenticator>->supports_url( iv_url ) = abap_true.
ro_authenticator = <li_authenticator>. ri_authenticator = <li_authenticator>.
RETURN. RETURN.
ENDIF. ENDIF.
ENDLOOP. ENDLOOP.

View File

@ -1,21 +1,27 @@
CLASS zcl_abapgit_2fa_github_auth DEFINITION CLASS zcl_abapgit_2fa_github_auth DEFINITION
PUBLIC PUBLIC
INHERITING FROM zcl_abapgit_2fa_auth_base INHERITING FROM zcl_abapgit_2fa_auth_base
FINAL
CREATE PUBLIC . CREATE PUBLIC .
PUBLIC SECTION. PUBLIC SECTION.
METHODS:
constructor, METHODS constructor
get_service_id_from_url REDEFINITION, IMPORTING
authenticate REDEFINITION, !iv_override TYPE string OPTIONAL .
is_2fa_required REDEFINITION,
delete_access_tokens REDEFINITION, METHODS zif_abapgit_2fa_authenticator~authenticate
end REDEFINITION. REDEFINITION .
METHODS zif_abapgit_2fa_authenticator~delete_access_tokens
REDEFINITION .
METHODS zif_abapgit_2fa_authenticator~end
REDEFINITION .
METHODS zif_abapgit_2fa_authenticator~is_2fa_required
REDEFINITION .
PROTECTED SECTION. PROTECTED SECTION.
DATA mv_github_api_url TYPE string VALUE `https://api.github.com/` ##NO_TEXT.
PRIVATE SECTION. PRIVATE SECTION.
CONSTANTS c_github_api_url TYPE string VALUE `https://api.github.com/` ##NO_TEXT.
CONSTANTS c_otp_header_name TYPE string VALUE `X-Github-OTP` ##NO_TEXT. CONSTANTS c_otp_header_name TYPE string VALUE `X-Github-OTP` ##NO_TEXT.
CONSTANTS c_restendpoint_authorizations TYPE string VALUE `/authorizations` ##NO_TEXT. CONSTANTS c_restendpoint_authorizations TYPE string VALUE `/authorizations` ##NO_TEXT.
DATA mi_authenticated_session TYPE REF TO if_http_client . DATA mi_authenticated_session TYPE REF TO if_http_client .
@ -58,7 +64,17 @@ CLASS ZCL_ABAPGIT_2FA_GITHUB_AUTH IMPLEMENTATION.
METHOD constructor. METHOD constructor.
super->constructor( '^https?://(www\.)?github.com.*$' ).
DATA: lv_match TYPE string.
IF iv_override IS SUPPLIED.
lv_match = iv_override.
ELSE.
lv_match = '^https?://(www\.)?github.com.*$'.
ENDIF.
super->constructor( lv_match ).
ENDMETHOD. ENDMETHOD.
@ -79,7 +95,7 @@ CLASS ZCL_ABAPGIT_2FA_GITHUB_AUTH IMPLEMENTATION.
cl_http_client=>create_by_url( cl_http_client=>create_by_url(
EXPORTING EXPORTING
url = c_github_api_url url = mv_github_api_url
ssl_id = 'ANONYM' ssl_id = 'ANONYM'
proxy_host = lo_settings->get_proxy_url( ) proxy_host = lo_settings->get_proxy_url( )
proxy_service = lo_settings->get_proxy_port( ) proxy_service = lo_settings->get_proxy_port( )
@ -200,7 +216,7 @@ CLASS ZCL_ABAPGIT_2FA_GITHUB_AUTH IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD authenticate. METHOD zif_abapgit_2fa_authenticator~authenticate.
DATA: li_http_client TYPE REF TO if_http_client, DATA: li_http_client TYPE REF TO if_http_client,
lv_http_code TYPE i, lv_http_code TYPE i,
lv_http_code_description TYPE string. lv_http_code_description TYPE string.
@ -247,7 +263,8 @@ CLASS ZCL_ABAPGIT_2FA_GITHUB_AUTH IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD delete_access_tokens. METHOD zif_abapgit_2fa_authenticator~delete_access_tokens.
DATA: li_http_client TYPE REF TO if_http_client, DATA: li_http_client TYPE REF TO if_http_client,
lv_http_code TYPE i, lv_http_code TYPE i,
lv_http_code_description TYPE string, lv_http_code_description TYPE string,
@ -308,18 +325,13 @@ CLASS ZCL_ABAPGIT_2FA_GITHUB_AUTH IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD end. METHOD zif_abapgit_2fa_authenticator~end.
super->end( ). super->end( ).
FREE mi_authenticated_session. FREE mi_authenticated_session.
ENDMETHOD. ENDMETHOD.
METHOD get_service_id_from_url. METHOD zif_abapgit_2fa_authenticator~is_2fa_required.
rv_id = 'github'.
ENDMETHOD.
METHOD is_2fa_required.
DATA: li_client TYPE REF TO if_http_client, DATA: li_client TYPE REF TO if_http_client,
lo_proxy TYPE REF TO zcl_abapgit_proxy_config. lo_proxy TYPE REF TO zcl_abapgit_proxy_config.
@ -329,7 +341,7 @@ CLASS ZCL_ABAPGIT_2FA_GITHUB_AUTH IMPLEMENTATION.
cl_http_client=>create_by_url( cl_http_client=>create_by_url(
EXPORTING EXPORTING
url = c_github_api_url url = mv_github_api_url
ssl_id = 'ANONYM' ssl_id = 'ANONYM'
proxy_host = lo_proxy->get_proxy_url( ) proxy_host = lo_proxy->get_proxy_url( )
proxy_service = lo_proxy->get_proxy_port( ) proxy_service = lo_proxy->get_proxy_port( )

View File

@ -9,7 +9,6 @@
<DESCRIPT>2FA for github</DESCRIPT> <DESCRIPT>2FA for github</DESCRIPT>
<EXPOSURE>2</EXPOSURE> <EXPOSURE>2</EXPOSURE>
<STATE>1</STATE> <STATE>1</STATE>
<CLSFINAL>X</CLSFINAL>
<CLSCCINCL>X</CLSCCINCL> <CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT> <FIXPT>X</FIXPT>
<UNICODE>X</UNICODE> <UNICODE>X</UNICODE>

View File

@ -15,9 +15,10 @@
"! used to avoid having multiple http sessions between <em>authenticate</em> and "! used to avoid having multiple http sessions between <em>authenticate</em> and
"! <em>delete_access_tokens</em>. "! <em>delete_access_tokens</em>.
"! </p> "! </p>
INTERFACE zif_abapgit_2fa_authenticator PUBLIC. INTERFACE zif_abapgit_2fa_authenticator
PUBLIC .
METHODS:
"! Generate an access token "! Generate an access token
"! @parameter iv_url | Repository url "! @parameter iv_url | Repository url
"! @parameter iv_username | Username "! @parameter iv_username | Username
@ -26,36 +27,40 @@ INTERFACE zif_abapgit_2fa_authenticator PUBLIC.
"! @parameter rv_access_token | Generated access token "! @parameter rv_access_token | Generated access token
"! @raising lcx_2fa_auth_failed | Authentication failed "! @raising lcx_2fa_auth_failed | Authentication failed
"! @raising lcx_2fa_token_gen_failed | Token generation failed "! @raising lcx_2fa_token_gen_failed | Token generation failed
authenticate IMPORTING iv_url TYPE string METHODS authenticate
iv_username TYPE string IMPORTING
iv_password TYPE string !iv_url TYPE string
iv_2fa_token TYPE string !iv_username TYPE string
RETURNING VALUE(rv_access_token) TYPE string !iv_password TYPE string
RAISING zcx_abapgit_2fa_auth_failed !iv_2fa_token TYPE string
RETURNING
VALUE(rv_access_token) TYPE string
RAISING
zcx_abapgit_2fa_auth_failed
zcx_abapgit_2fa_gen_failed zcx_abapgit_2fa_gen_failed
zcx_abapgit_2fa_comm_error, zcx_abapgit_2fa_comm_error .
"! Check if this authenticator instance supports the give repository url "! Check if this authenticator instance supports the give repository url
"! @parameter iv_url | Repository url "! @parameter iv_url | Repository url
"! @parameter rv_supported | Is supported "! @parameter rv_supported | Is supported
supports_url IMPORTING iv_url TYPE string METHODS supports_url
RETURNING VALUE(rv_supported) TYPE abap_bool, IMPORTING
"! Get a unique identifier for the service that hosts the repository !iv_url TYPE string
"! @parameter iv_url | Repository url RETURNING
"! @parameter rv_id | Service id VALUE(rv_supported) TYPE abap_bool .
"! @raising lcx_2fa_unsupported | Url is not supported
get_service_id_from_url IMPORTING iv_url TYPE string
RETURNING VALUE(rv_id) TYPE string
RAISING zcx_abapgit_2fa_unsupported,
"! Check if two factor authentication is required "! Check if two factor authentication is required
"! @parameter iv_url | Repository url "! @parameter iv_url | Repository url
"! @parameter iv_username | Username "! @parameter iv_username | Username
"! @parameter iv_password | Password "! @parameter iv_password | Password
"! @parameter rv_required | 2FA is required "! @parameter rv_required | 2FA is required
is_2fa_required IMPORTING iv_url TYPE string METHODS is_2fa_required
iv_username TYPE string IMPORTING
iv_password TYPE string !iv_url TYPE string
RETURNING VALUE(rv_required) TYPE abap_bool !iv_username TYPE string
RAISING zcx_abapgit_2fa_comm_error, !iv_password TYPE string
RETURNING
VALUE(rv_required) TYPE abap_bool
RAISING
zcx_abapgit_2fa_comm_error .
"! Delete all previously created access tokens for abapGit "! Delete all previously created access tokens for abapGit
"! @parameter iv_url | Repository url "! @parameter iv_url | Repository url
"! @parameter iv_username | Username "! @parameter iv_username | Username
@ -63,17 +68,24 @@ INTERFACE zif_abapgit_2fa_authenticator PUBLIC.
"! @parameter iv_2fa_token | Two factor token "! @parameter iv_2fa_token | Two factor token
"! @raising lcx_2fa_token_del_failed | Token deletion failed "! @raising lcx_2fa_token_del_failed | Token deletion failed
"! @raising lcx_2fa_auth_failed | Authentication failed "! @raising lcx_2fa_auth_failed | Authentication failed
delete_access_tokens IMPORTING iv_url TYPE string METHODS delete_access_tokens
iv_username TYPE string IMPORTING
iv_password TYPE string !iv_url TYPE string
iv_2fa_token TYPE string !iv_username TYPE string
RAISING zcx_abapgit_2fa_del_failed !iv_password TYPE string
!iv_2fa_token TYPE string
RAISING
zcx_abapgit_2fa_del_failed
zcx_abapgit_2fa_comm_error zcx_abapgit_2fa_comm_error
zcx_abapgit_2fa_auth_failed, zcx_abapgit_2fa_auth_failed .
"! Begin an authenticator session that uses internal caching for authorizations "! Begin an authenticator session that uses internal caching for authorizations
"! @raising lcx_2fa_illegal_state | Session already started "! @raising lcx_2fa_illegal_state | Session already started
begin RAISING zcx_abapgit_2fa_illegal_state, METHODS begin
RAISING
zcx_abapgit_2fa_illegal_state .
"! End an authenticator session and clear internal caches "! End an authenticator session and clear internal caches
"! @raising lcx_2fa_illegal_state | Session not running "! @raising lcx_2fa_illegal_state | Session not running
end RAISING zcx_abapgit_2fa_illegal_state. METHODS end
RAISING
zcx_abapgit_2fa_illegal_state .
ENDINTERFACE. ENDINTERFACE.