2026-01-14 10:23:49 +01:00
using Duplicati.Library.Interface ;
using Duplicati.Library.Utility.Options ;
2026-01-22 17:01:13 +01:00
using Duplicati.Proprietary.Office365.SourceItems ;
2026-01-14 10:23:49 +01:00
namespace Duplicati.Proprietary.Office365 ;
internal static class OptionsHelper
{
internal const string ModuleKey = "office365" ;
2026-01-22 17:01:13 +01:00
internal const string OFFICE_TENANT_OPTION = "office365-tenant-id" ;
internal const string OFFICE_CLIENT_OPTION = "office365-client-id" ;
internal const string OFFICE_SECRET_OPTION = "office365-client-secret" ;
internal const string OFFICE_CERTIFICATE_PATH_OPTION = "office365-certificate-path" ;
internal const string OFFICE_CERTIFICATE_PASSWORD_OPTION = "office365-certificate-password" ;
internal const string OFFICE_GRAPH_BASE_OPTION = "office365-graph-base-url" ;
internal const string OFFICE_SCOPE_OPTION = "office365-scope" ;
2026-01-20 12:13:19 +01:00
internal const string OFFICE_SCOPE_OPTION_DEFAULT = "https://graph.microsoft.com/.default" ;
2026-01-22 17:01:13 +01:00
internal const string OFFICE_IGNORE_EXISTING_OPTION = "office365-ignore-existing" ;
internal const string OFFICE_INCLUDED_ROOT_TYPES_OPTION = "office365-included-root-types" ;
internal const string OFFICE_INCLUDED_USER_TYPES_OPTION = "office365-included-user-types" ;
internal const string OFFICE_INCLUDED_GROUP_TYPES_OPTION = "office365-included-group-types" ;
/// <summary>
/// User types that require delegated permissions, default disabled.
/// </summary>
private static readonly Office365UserType [] DELEGATED_USER_TYPES =
[
Office365UserType.Tasks,
Office365UserType.Notes
] ;
/// <summary>
/// Group types that require delegated permissions, default disabled.
/// </summary>
private static readonly Office365GroupType [] DELEGATED_GROUP_TYPES =
[
2026-01-23 11:28:02 +01:00
Office365GroupType.Calendar,
Office365GroupType.Notes
2026-01-22 17:01:13 +01:00
] ;
/// <summary>
/// The default included root types.
/// </summary>
private static readonly Office365MetaType [] DEFAULT_INCLUDED_ROOT_TYPES =
Enum . GetValues < Office365MetaType >()
. ToArray ();
/// <summary>
/// The default included group types.
/// </summary>
private static readonly Office365GroupType [] DEFAULT_INCLUDED_GROUP_TYPES =
Enum . GetValues < Office365GroupType >()
. Except ( DELEGATED_GROUP_TYPES )
. ToArray ();
/// <summary>
/// The default included user types.
/// </summary>
private static readonly Office365UserType [] DEFAULT_INCLUDED_USER_TYPES =
Enum . GetValues < Office365UserType >()
. Except ( DELEGATED_USER_TYPES )
. ToArray ();
2026-01-14 10:23:49 +01:00
internal const string DEFAULT_GRAPH_BASE_URL = "https://graph.microsoft.com" ;
internal sealed record ParsedOptions (
string TenantId ,
AuthOptionsHelper . AuthOptions AuthOptions ,
2026-01-20 10:36:37 +01:00
string GraphBaseUrl ,
string? CertificatePath ,
2026-01-20 12:13:19 +01:00
string? CertificatePassword ,
2026-01-22 17:01:13 +01:00
string Scope ,
Office365MetaType [] IncludedRootTypes ,
Office365UserType [] IncludedUserTypes ,
Office365GroupType [] IncludedGroupTypes
2026-01-14 10:23:49 +01:00
);
internal static ParsedOptions ParseAndValidateOptions ( string url , Dictionary < string , string? > options )
{
var _authOptions = AuthOptionsHelper . ParseWithAlias ( options , new Library . Utility . Uri ( url ), OFFICE_CLIENT_OPTION , OFFICE_SECRET_OPTION )
. RequireCredentials ();
var _tenantId = options . GetValueOrDefault ( OFFICE_TENANT_OPTION )!;
if ( string . IsNullOrWhiteSpace ( _tenantId ))
throw new UserInformationException ( Strings . MissingTenantId , "MissingTenantId" );
var _graphBaseUrl = options . GetValueOrDefault ( OFFICE_GRAPH_BASE_OPTION ) ?? DEFAULT_GRAPH_BASE_URL ;
if ( string . IsNullOrWhiteSpace ( _graphBaseUrl ))
_graphBaseUrl = DEFAULT_GRAPH_BASE_URL ;
2026-01-20 10:36:37 +01:00
var _certificatePath = options . GetValueOrDefault ( OFFICE_CERTIFICATE_PATH_OPTION );
var _certificatePassword = options . GetValueOrDefault ( OFFICE_CERTIFICATE_PASSWORD_OPTION );
2026-01-20 12:13:19 +01:00
var _scope = options . GetValueOrDefault ( OFFICE_SCOPE_OPTION );
if ( string . IsNullOrWhiteSpace ( _scope ))
_scope = OFFICE_SCOPE_OPTION_DEFAULT ;
2026-01-28 19:36:05 +01:00
var includedRootTypes = Library . Utility . Utility . ParseFlagsOption ( options , OFFICE_INCLUDED_ROOT_TYPES_OPTION , ( Office365MetaType ) DEFAULT_INCLUDED_ROOT_TYPES . Aggregate ( 0 , ( acc , type ) => acc | ( int ) type ));
var includedUserTypes = Library . Utility . Utility . ParseFlagsOption ( options , OFFICE_INCLUDED_USER_TYPES_OPTION , ( Office365UserType ) DEFAULT_INCLUDED_USER_TYPES . Aggregate ( 0 , ( acc , type ) => acc | ( int ) type ));
var includedGroupTypes = Library . Utility . Utility . ParseFlagsOption ( options , OFFICE_INCLUDED_GROUP_TYPES_OPTION , ( Office365GroupType ) DEFAULT_INCLUDED_GROUP_TYPES . Aggregate ( 0 , ( acc , type ) => acc | ( int ) type ));
2026-01-22 17:01:13 +01:00
2026-01-14 10:23:49 +01:00
return new ParsedOptions (
TenantId : _tenantId ,
AuthOptions : _authOptions ,
2026-01-20 10:36:37 +01:00
GraphBaseUrl : _graphBaseUrl ,
CertificatePath : _certificatePath ,
2026-01-20 12:13:19 +01:00
CertificatePassword : _certificatePassword ,
2026-01-22 17:01:13 +01:00
Scope : _scope ,
2026-01-28 19:36:05 +01:00
IncludedRootTypes : Enum . GetValues < Office365MetaType >(). Where ( n => includedRootTypes . HasFlag ( n )). ToArray (),
IncludedUserTypes : Enum . GetValues < Office365UserType >(). Where ( n => includedUserTypes . HasFlag ( n )). ToArray (),
IncludedGroupTypes : Enum . GetValues < Office365GroupType >(). Where ( n => includedGroupTypes . HasFlag ( n )). ToArray ()
2026-01-14 10:23:49 +01:00
);
}
internal static IList < ICommandLineArgument > SupportedCommands =>
[
new CommandLineArgument(OFFICE_TENANT_OPTION, CommandLineArgument.ArgumentType.String, Strings.OfficeTenantOptionShort, Strings.OfficeTenantOptionLong),
new CommandLineArgument(OFFICE_CLIENT_OPTION, CommandLineArgument.ArgumentType.String, Strings.OfficeClientOptionShort, Strings.OfficeClientOptionLong, null, [AuthOptionsHelper.AuthUsernameOption] , null ),
new CommandLineArgument ( OFFICE_SECRET_OPTION , CommandLineArgument . ArgumentType . Password , Strings . OfficeSecretOptionShort , Strings . OfficeSecretOptionLong , null , [ AuthOptionsHelper . AuthPasswordOption ], null ),
2026-01-20 10:36:37 +01:00
new CommandLineArgument ( OFFICE_CERTIFICATE_PATH_OPTION , CommandLineArgument . ArgumentType . Path , Strings . OfficeCertificatePathOptionShort , Strings . OfficeCertificatePathOptionLong ),
new CommandLineArgument ( OFFICE_CERTIFICATE_PASSWORD_OPTION , CommandLineArgument . ArgumentType . Password , Strings . OfficeCertificatePasswordOptionShort , Strings . OfficeCertificatePasswordOptionLong ),
2026-01-20 12:13:19 +01:00
new CommandLineArgument ( OFFICE_GRAPH_BASE_OPTION , CommandLineArgument . ArgumentType . String , Strings . OfficeGraphBaseOptionShort , Strings . OfficeGraphBaseOptionLong , DEFAULT_GRAPH_BASE_URL ),
2026-01-22 17:01:13 +01:00
new CommandLineArgument ( OFFICE_SCOPE_OPTION , CommandLineArgument . ArgumentType . String , Strings . OfficeScopeOptionShort , Strings . OfficeScopeOptionLong , OFFICE_SCOPE_OPTION_DEFAULT ),
new CommandLineArgument ( OFFICE_INCLUDED_ROOT_TYPES_OPTION , CommandLineArgument . ArgumentType . Flags , Strings . OfficeIncludedRootTypesShort , Strings . OfficeIncludedRootTypesLong , string . Join ( "," , DEFAULT_INCLUDED_ROOT_TYPES . Select ( n => n . ToString ()). ToArray ()), null , Enum . GetNames < Office365MetaType >()),
new CommandLineArgument ( OFFICE_INCLUDED_USER_TYPES_OPTION , CommandLineArgument . ArgumentType . Flags , Strings . OfficeIncludedUserTypesShort , Strings . OfficeIncludedUserTypesLong , string . Join ( "," , DEFAULT_INCLUDED_USER_TYPES . Select ( n => n . ToString ()). ToArray ()), null , Enum . GetNames < Office365UserType >()),
new CommandLineArgument ( OFFICE_INCLUDED_GROUP_TYPES_OPTION , CommandLineArgument . ArgumentType . Flags , Strings . OfficeIncludedGroupTypesShort , Strings . OfficeIncludedGroupTypesLong , string . Join ( "," , DEFAULT_INCLUDED_GROUP_TYPES . Select ( n => n . ToString ()). ToArray ()), null , Enum . GetNames < Office365GroupType >())
2026-01-14 10:23:49 +01:00
];
}