private BWebServiceResponse OnRequest_CreateTestUser(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { string OptionalName = BUtility.RandomString(12, true) + "_test"; string EmailWithoutPostfix = OptionalName + "@test.com"; var AccumulatedSSOMethodRightsOrDefault = new JArray() { JObject.Parse(JsonConvert.SerializeObject( new AccessScope() { WildcardPath = "*", AccessRights = new List <string>() { "GET", "POST", "PUT", "DELETE" } })) }; if (!CreateUser(out string _UserID, EmailWithoutPostfix, _ErrorMessageAction, OptionalName)) { return(BWebResponse.InternalError("User creation process has been failed.")); } if (!CreateAuthMethod(out string _ApiKey, _UserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Auth method creation process has been failed.")); } if (!Controller_Rights_Internal.Get().GrantUserWithRights(false, _UserID, AccumulatedSSOMethodRightsOrDefault, _ErrorMessageAction)) { return(BWebResponse.InternalError("Grant user with rights process has been failed.")); } return(BWebResponse.StatusCreated("User has been created.", new JObject() { [UserDBEntry.KEY_NAME_USER_ID] = _UserID, [AuthMethod.API_KEY_PROPERTY] = _ApiKey, [AuthMethod.USER_EMAIL_PROPERTY] = EmailWithoutPostfix })); }
private BWebServiceResponse CreateAccessMethodForUser(HttpListenerContext _Context, out bool _bSetClearanceForApiKey, out string _ApiKey, Action <string> _ErrorMessageAction) { _bSetClearanceForApiKey = false; _ApiKey = null; AuthMethod NewMethod = null; using (var InputStream = _Context.Request.InputStream) { using (var ResponseReader = new StreamReader(InputStream)) { try { NewMethod = JsonConvert.DeserializeObject <AuthMethod>(ResponseReader.ReadToEnd()); } catch (Exception e) { _ErrorMessageAction?.Invoke("User_CreateListAccessMethods_ForUser->CreateAccessMethodForUser: Read request body stage has failed. Exception: " + e.Message + ", Trace: " + e.StackTrace); return(BWebResponse.BadRequest("Malformed request body. Request must be a valid json form.")); } } } if (NewMethod == null) { return(BWebResponse.BadRequest("Request body does not contain all mandatory information or some fields are invalid.")); } BPrimitiveType AuthMethodKey = null; if (NewMethod.Method == AuthMethod.Methods.USER_EMAIL_PASSWORD_METHOD) { if (NewMethod.UserEmail == null || NewMethod.PasswordMD5 == null || NewMethod.UserEmail.Length == 0 || NewMethod.PasswordMD5.Length == 0) { return(BWebResponse.BadRequest("Request body does not contain all fields.")); } AuthMethodKey = new BPrimitiveType(NewMethod.UserEmail + NewMethod.PasswordMD5); } else if (NewMethod.Method == AuthMethod.Methods.USER_NAME_PASSWORD_METHOD) { if (NewMethod.UserName == null || NewMethod.PasswordMD5 == null || NewMethod.UserName.Length == 0 || NewMethod.PasswordMD5.Length == 0) { return(BWebResponse.BadRequest("Request body does not contain all fields.")); } AuthMethodKey = new BPrimitiveType(NewMethod.UserName + NewMethod.PasswordMD5); } else if (NewMethod.Method == AuthMethod.Methods.API_KEY_METHOD) { int ExistenceTrial = 0; while (ExistenceTrial < 3) { if (!BUtility.CalculateStringMD5(BUtility.RandomString(32, false), out NewMethod.ApiKey, _ErrorMessageAction)) { return(BWebResponse.InternalError("Hashing error.")); } NewMethod.ApiKey = NewMethod.ApiKey.ToUpper(); if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + NewMethod.ApiKey, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } if (!DatabaseService.UpdateItem( UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY, new BPrimitiveType(NewMethod.ApiKey), new JObject() { [UserDBEntry.KEY_NAME_USER_ID] = RequestedUserID }, out JObject _, EBReturnItemBehaviour.DoNotReturn, DatabaseService.BuildAttributeNotExistCondition(UniqueUserFieldsDBEntry.KEY_NAME_API_KEY), _ErrorMessageAction)) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + NewMethod.ApiKey, _ErrorMessageAction); ExistenceTrial++; } else { _bSetClearanceForApiKey = true; _ApiKey = NewMethod.ApiKey; break; } }
public static bool GenerateUserID(out string _NewUserID, Action <string> _ErrorMessageAction) { return(BUtility.CalculateStringMD5(BUtility.RandomString(32, true), out _NewUserID, _ErrorMessageAction)); }
public static bool GenerateNonExistentUniqueID( WebServiceBaseTimeoutable _Request, IBDatabaseServiceInterface _DatabaseService, string _TableName, string _TableKeyName, string[] _TableEntryMustHaveProperties, EGetClearance _GetClearance, out string _GeneratedUniqueID, out BWebServiceResponse _FailureResponse, Action <string> _ErrorMessageAction = null) { _GeneratedUniqueID = null; _FailureResponse = BWebResponse.InternalError(""); int ExistenceTrial = 0; while (_GeneratedUniqueID == null && ExistenceTrial < 3) { if (!BUtility.CalculateStringMD5(BUtility.RandomString(32, false), out _GeneratedUniqueID, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Hashing operation has failed."); return(false); } if (_GetClearance == EGetClearance.Yes && !Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(_Request.InnerProcessor, _TableName, _GeneratedUniqueID, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Atomic operation control has failed."); return(false); } if (!_DatabaseService.GetItem( _TableName, _TableKeyName, new BPrimitiveType(_GeneratedUniqueID), _TableEntryMustHaveProperties, out JObject ExistenceCheck, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Database existence check operation has failed."); return(false); } if (ExistenceCheck != null) { if (_GetClearance == EGetClearance.Yes) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(_Request.InnerProcessor, _TableName, _GeneratedUniqueID, _ErrorMessageAction); } _GeneratedUniqueID = null; ExistenceTrial++; } else { break; } } if (_GeneratedUniqueID == null) { _FailureResponse = BWebResponse.InternalError("Unique model ID generation operation has failed."); return(false); } return(true); }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (!UrlParameters.TryGetValue("redirect_url", out string RedirectUrlEncoded) || RedirectUrlEncoded.Length == 0) { RedirectUrlEncoded = DEFAULT_REDIRECT_URL_ENCODED; } if (_Context.Request.HttpMethod != "GET") { _ErrorMessageAction?.Invoke("SSOLoginRequest: GET method is accepted. But received request method: " + _Context.Request.HttpMethod); return(SSOCommon.MakeCallerRedirected(WebUtility.UrlDecode(RedirectUrlEncoded), true, BWebResponse.Error_BadRequest_Code, "GET method is accepted. But received request method: " + _Context.Request.HttpMethod)); } if (!UrlParameters.TryGetValue("tenant", out string TenantName) || TenantName.Length == 0) { TenantName = DEFAULT_TENANT_NAME; } else { TenantName = TenantName.ToLower(); } //Existing token from header string ClientAuthorization = null; if (BWebUtilities.DoesContextContainHeader(out List <string> ClientAuthorizationHeaderValues, out string _, _Context, "client-authorization")) { BUtility.CheckAndGetFirstStringFromList(ClientAuthorizationHeaderValues, out ClientAuthorization); if (ClientAuthorization != null && ClientAuthorization.Length == 0) { ClientAuthorization = null; } } //Existing token from url parameters //Note: Must be token type prepended. Example: ?existing_token=bearer%20abc123123 if (!UrlParameters.TryGetValue("existing_token", out string ExistingToken) || ExistingToken.Length == 0) { ExistingToken = null; } else { ExistingToken = WebUtility.UrlDecode(ExistingToken); } //If both existing tokens are non-null; it is error if (ClientAuthorization != null && ExistingToken != null) { _ErrorMessageAction?.Invoke("Error: SSOLoginRequest: Both existing tokens from url parameters and headers are non-null."); return(SSOCommon.MakeCallerRedirected(WebUtility.UrlDecode(RedirectUrlEncoded), true, BWebResponse.Error_BadRequest_Code, "Both existing tokens from url parameters and headers are non-null.")); } //From now on, use ClientAuthorization; not ExistingToken if (ExistingToken != null) { ClientAuthorization = ExistingToken; } //Check and try refresh if expired if (ClientAuthorization != null && new Controller_SSOAccessToken(ClientAuthorization, DatabaseService, MemoryService, AzureAD_AppID, AzureAD_ClientSecret, SSOSuperAdmins, _ErrorMessageAction) .PerformCheckAndRefresh( out Controller_SSOAccessToken.EPerformCheckAndRefreshSuccessStatus _, out ClientAuthorization, out string UserID, out string _)) { return(SSOCommon.MakeCallerRedirected(WebUtility.UrlDecode(RedirectUrlEncoded), false, 0, null, UserID, ClientAuthorization)); } //Get api passthrough endpoint from internal set state var LocalErrorString = ""; if (!InternalSetState.GetValueFromMemoryService( out string ApiPassthroughEndpoint, InternalSetState.API_PASSTHROUGH_PUBLIC_ENDPOINT_PROPERTY, MemoryService, (string _Message) => { LocalErrorString = _Message; _ErrorMessageAction?.Invoke(_Message); })) { return(SSOCommon.MakeCallerRedirected(WebUtility.UrlDecode(RedirectUrlEncoded), true, 500, LocalErrorString)); } string ServersideRedirectUrl = WebUtility.UrlEncode(ApiPassthroughEndpoint + "/auth/login/azure/callback"); string AzureAuthenticationEndpointBase = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize" + "?client_id=" + AzureAD_AppID + "&response_type=id_token code" + "&redirect_uri=" + ServersideRedirectUrl; var TrialCount = 0; string SSOStateUniqueID; BMemoryQueryParameters SSOStateUniqueID_QueryParameters; do { if (!BUtility.CalculateStringMD5(BUtility.RandomString(32, true), out SSOStateUniqueID, _ErrorMessageAction)) { return(SSOCommon.MakeCallerRedirected(WebUtility.UrlDecode(RedirectUrlEncoded), true, 500, "SSO State ID generation has failed.")); } SSOStateUniqueID_QueryParameters = SSOStateMEntry.ID_SSO_STATE_MEMORY_SERVICE_KEY(SSOStateUniqueID); if (!MemoryService.SetKeyValueConditionally( SSOStateUniqueID_QueryParameters, new Tuple <string, BPrimitiveType>( SSOStateMEntry.HASH_KEY, new BPrimitiveType(JsonConvert.SerializeObject( new SSOStateMEntry() { ServersideRedirectUrl = ServersideRedirectUrl, TenantName = TenantName, Status = SSOStateMEntry.STATUS_AUTHENTICATING }) ) ), _ErrorMessageAction)) { SSOStateUniqueID = null; } } while (SSOStateUniqueID == null && ++TrialCount < 5); if (SSOStateUniqueID == null) { return(SSOCommon.MakeCallerRedirected(WebUtility.UrlDecode(RedirectUrlEncoded), true, 500, "Unique SSO State ID generation has failed.")); } MemoryService.SetKeyExpireTime(SSOStateUniqueID_QueryParameters, TimeSpan.FromSeconds(120), _ErrorMessageAction); var AzureAuthenticationEndpoint = AzureAuthenticationEndpointBase + "&scope=" + SSOCommon.SCOPE_URL_ENCODED + "&response_mode=form_post" + "&nonce=" + SSOStateUniqueID + "&state=" + WebUtility.UrlEncode( "redirect_url=" + RedirectUrlEncoded + "&tenant=" + TenantName + "&state=" + SSOStateUniqueID); return(SSOCommon.MakeCallerRedirected(AzureAuthenticationEndpoint, false, 0, null)); }
public bool CreateInstance( string _UniqueInstanceName, string _Description, string _MachineType, long _DiskSizeGB, int _GpuCount, string _GpuName, string _OSSourceImageURL, EBVMDiskType _DiskType, EBVMOSType _OSType, IDictionary <string, string> _Labels, BVMNetworkFirewall _FirewallSettings, string _OptionalStartupScript, out int _ErrorCode, Action <string> _ErrorMessageAction = null) { _ErrorCode = 400; if (!BUtility.CalculateStringMD5(BUtility.RandomString(32, true), out string RandomFirewallTag, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("BVMServiceGC->CreateInstance: Firewall tag MD5 generation has failed."); return(false); } RandomFirewallTag = "a-" /*Has to start with a letter*/ + RandomFirewallTag; try { using (var Service = GetService()) { var NewInstance = new Instance() { Name = _UniqueInstanceName, Description = _Description, DeletionProtection = false, Zone = "projects/" + ProjectID + "/zones/" + ZoneName, Labels = _Labels, MachineType = "projects/" + ProjectID + "/zones/" + ZoneName + "/machineTypes/" + _MachineType, Disks = new List <AttachedDisk>() { new AttachedDisk() { AutoDelete = true, Boot = true, Kind = "compute#attachedDisk", DeviceName = _UniqueInstanceName, Mode = "READ_WRITE", InitializeParams = new AttachedDiskInitializeParams() { SourceImage = _OSSourceImageURL, DiskType = "projects/" + ProjectID + "/zones/" + ZoneName + "/diskTypes/" + (_DiskType == EBVMDiskType.SSD ? "pd-ssd" : "pd-standard"), DiskSizeGb = _DiskSizeGB }, Type = "PERSISTENT" } }, NetworkInterfaces = new List <NetworkInterface>() { new NetworkInterface() { AccessConfigs = new List <AccessConfig>() { new AccessConfig() { Kind = "compute#accessConfig", Name = "External NAT", NetworkTier = "PREMIUM", Type = "ONE_TO_ONE_NAT" } }, Kind = "compute#networkInterface", Name = "nic0", Network = "projects/" + ProjectID + "/global/networks/default", Subnetwork = "projects/" + ProjectID + "/regions/" + ZoneName.Substring(0, ZoneName.LastIndexOf('-')) + "/subnetworks/default" } }, Tags = new Tags() { Items = new List <string>() { RandomFirewallTag } }, Metadata = new Metadata() { Kind = "compute#metadata", Items = new List <Metadata.ItemsData>() }, ShieldedInstanceConfig = new ShieldedInstanceConfig() { EnableVtpm = true, EnableSecureBoot = false, EnableIntegrityMonitoring = true }, Scheduling = new Scheduling() { AutomaticRestart = true, Preemptible = false, OnHostMaintenance = "TERMINATE" } }; if (_OptionalStartupScript != null) { NewInstance.Metadata.Items.Add(new Metadata.ItemsData() { Key = _OSType == EBVMOSType.Linux ? "startup-script" : "windows-startup-script-ps1", Value = _OptionalStartupScript }); } if (_GpuCount > 0) { if (NewInstance.GuestAccelerators == null) { NewInstance.GuestAccelerators = new List <AcceleratorConfig>(); } NewInstance.GuestAccelerators.Add( new AcceleratorConfig() { AcceleratorCount = _GpuCount, AcceleratorType = "projects/" + ProjectID + "/zones/" + ZoneName + "/acceleratorTypes/" + _GpuName }); } if (_OSType == EBVMOSType.Windows) { if (NewInstance.Disks[0].GuestOsFeatures == null) { NewInstance.Disks[0].GuestOsFeatures = new List <GuestOsFeature>(); } if (!NewInstance.Disks[0].GuestOsFeatures.Any(Item => Item.Type == "VIRTIO_SCSI_MULTIQUEUE")) { NewInstance.Disks[0].GuestOsFeatures.Add(new GuestOsFeature() { Type = "VIRTIO_SCSI_MULTIQUEUE" }); } if (!NewInstance.Disks[0].GuestOsFeatures.Any(Item => Item.Type == "WINDOWS")) { NewInstance.Disks[0].GuestOsFeatures.Add(new GuestOsFeature() { Type = "WINDOWS" }); } if (!NewInstance.Disks[0].GuestOsFeatures.Any(Item => Item.Type == "MULTI_IP_SUBNET")) { NewInstance.Disks[0].GuestOsFeatures.Add(new GuestOsFeature() { Type = "MULTI_IP_SUBNET" }); } if (!NewInstance.Disks[0].GuestOsFeatures.Any(Item => Item.Type == "UEFI_COMPATIBLE")) { NewInstance.Disks[0].GuestOsFeatures.Add(new GuestOsFeature() { Type = "UEFI_COMPATIBLE" }); } } var NewFirewall = new Firewall() { Kind = "compute#firewall", Name = RandomFirewallTag, Priority = 1000, Direction = "INGRESS", SelfLink = "projects/" + ProjectID + "/global/firewalls/" + RandomFirewallTag, Network = "projects/" + ProjectID + "/global/networks/default", SourceRanges = new List <string>(), TargetTags = new List <string>() { RandomFirewallTag }, Allowed = new List <Firewall.AllowedData>() }; if (_FirewallSettings.bOpenAll) { NewFirewall.Allowed.Add(new Firewall.AllowedData() { IPProtocol = "tcp" }); NewFirewall.Allowed.Add(new Firewall.AllowedData() { IPProtocol = "udp" }); } else { foreach (var Current in _FirewallSettings.OpenPorts) { string[] OpenFor; if (Current.OpenFor == BVMNetworkFirewall.EVMNetworkFirewallPortProtocol.TCP) { OpenFor = new string[] { "tcp" } } ; else if (Current.OpenFor == BVMNetworkFirewall.EVMNetworkFirewallPortProtocol.UDP) { OpenFor = new string[] { "udp" } } ; else { OpenFor = new string[] { "tcp", "udp" } }; var PortList = new List <string>() { Current.FromPortInclusive + "-" + Current.ToPortInclusive }; foreach (var OFor in OpenFor) { NewFirewall.Allowed.Add(new Firewall.AllowedData() { IPProtocol = OFor, Ports = PortList }); } } } var FirewallCreationResult = Service.Firewalls.Insert(NewFirewall, ProjectID).Execute(); if (FirewallCreationResult == null || (FirewallCreationResult.HttpErrorStatusCode.HasValue && FirewallCreationResult.HttpErrorStatusCode.Value >= 400)) { _ErrorMessageAction?.Invoke("BVMServiceGC->CreateInstance: Firewall creation has failed: " + (FirewallCreationResult == null ? "Result is null." : FirewallCreationResult.HttpErrorMessage)); _ErrorCode = FirewallCreationResult.HttpErrorStatusCode.Value; return(false); } var VMCreationResult = Service.Instances.Insert(NewInstance, ProjectID, ZoneName).Execute(); if (VMCreationResult == null || (VMCreationResult.HttpErrorStatusCode.HasValue && VMCreationResult.HttpErrorStatusCode.Value >= 400)) { _ErrorMessageAction?.Invoke("BVMServiceGC->CreateInstance: VM creation has failed: " + (VMCreationResult == null ? "Result is null." : VMCreationResult.HttpErrorMessage)); _ErrorCode = VMCreationResult.HttpErrorStatusCode.Value; return(false); } } } catch (Exception e) { _ErrorMessageAction?.Invoke("BVMServiceGC->CreateInstance: " + e.Message + ", Trace: " + e.StackTrace); return(false); } return(true); }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (_Context.Request.HttpMethod != "POST") { _ErrorMessageAction?.Invoke("LoginRequest: POST method is accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("POST method is accepted. But received request method: " + _Context.Request.HttpMethod)); } JObject ParsedBody; using (var InputStream = _Context.Request.InputStream) { using (var ResponseReader = new StreamReader(InputStream)) { try { ParsedBody = JObject.Parse(ResponseReader.ReadToEnd()); } catch (Exception e) { _ErrorMessageAction?.Invoke("LoginRequest-> Read request body stage has failed. Exception: " + e.Message + ", Trace: " + e.StackTrace); return(BWebResponse.BadRequest("Malformed request body. Request must be a valid json form.")); } } } if (!ParsedBody.ContainsKey(AuthMethod.API_KEY_PROPERTY) && ((!ParsedBody.ContainsKey(AuthMethod.USER_NAME_PROPERTY) && !ParsedBody.ContainsKey(AuthMethod.USER_EMAIL_PROPERTY)) || !ParsedBody.ContainsKey(AuthMethod.PASSWORD_MD5_PROPERTY))) { _ErrorMessageAction?.Invoke("LoginRequest-> Request does not have required fields."); return(BWebResponse.BadRequest("Request does not have required fields.")); } string Method; if (ParsedBody.ContainsKey(AuthMethod.API_KEY_PROPERTY)) { var ApiKey = (string)ParsedBody[AuthMethod.API_KEY_PROPERTY]; Method = ApiKey; } else { var PasswordMD5 = ((string)ParsedBody[AuthMethod.PASSWORD_MD5_PROPERTY]).ToLower(); if (ParsedBody.ContainsKey(UserDBEntry.USER_NAME_PROPERTY)) { Method = (string)ParsedBody[UserDBEntry.USER_NAME_PROPERTY] + PasswordMD5; } else { Method = ((string)ParsedBody[UserDBEntry.USER_EMAIL_PROPERTY]).ToLower() + PasswordMD5; } } if (!AuthenticationCommon.FetchUserInfoFromMemoryService_ByMethod(MemoryService, Method, out string UserID, out string _, out string _, _ErrorMessageAction)) { if (!AuthenticationCommon.FetchUserInfoFromDatabaseService_ByMethod(DatabaseService, MemoryService, Method, out UserID, out _, out _, out BWebServiceResponse FailureResponse, _ErrorMessageAction)) { return(FailureResponse); } } if (!BUtility.CalculateStringMD5(BUtility.RandomString(32, true), out string AccessTokenMD5, _ErrorMessageAction)) { return(BWebResponse.InternalError("Hash operation failed.")); } var AccessTokenMD5WithTokenType = "Basic " + AccessTokenMD5; var QueryParameters = new BMemoryQueryParameters() { Domain = Resources_DeploymentManager.Get().GetDeploymentBranchNameEscapedLoweredWithDash().ToUpper(), SubDomain = "SELF_SIGNED_ACCESS_TOKEN_VALIDATION", Identifier = AccessTokenMD5WithTokenType }; MemoryService.SetKeyValue(QueryParameters, new Tuple <string, BPrimitiveType>[] { new Tuple <string, BPrimitiveType>("method", new BPrimitiveType(Method)) }, _ErrorMessageAction); MemoryService.SetKeyExpireTime(QueryParameters, TimeSpan.FromHours(1), _ErrorMessageAction); return(BWebResponse.StatusOK("Login successful.", new JObject() { ["userId"] = UserID, ["token"] = AccessTokenMD5WithTokenType })); }