public async Task <ActionResult> AddMemberToGroup(SingleGroupMemberDTO dto)
        {
            //Validate DTO
            if (!dto.Validate())
            {
                return(BadRequest("All fields must contain valid values"));
            }
            //Prevent duplicate
            if ((await _context.GroupAssignments.FindAsync(dto.GroupID, dto.UserUsername)) is not null)
            {
                return(Conflict("Assignment already exists"));
            }
            if (!await _context.Groups.AnyAsync(group => group.GroupID == dto.GroupID &&
                                                group.Course.User.Username == GetUsername()))
            {
                return(BadRequest("Either group does not exist or the group is owned by another user"));
            }

            await _context.GroupAssignments
            .AddAsync(new GroupAssignment()
            {
                GroupID = dto.GroupID, UserUsername = dto.UserUsername.ToLower()
            });

            await _context.SaveChangesAsync();

            // ReSharper disable once Mvc.ActionNotResolved
            return(CreatedAtAction("members", new { groupid = dto.GroupID }));
        }
Example #2
0
        public async Task <IActionResult> PutCourse(Guid id, CourseDTO courseDTO)
        {
            //Validate Request
            if (id != courseDTO.CourseID)
            {
                return(BadRequest());
            }
            if (courseDTO.CourseName is null || courseDTO.ShortCourseName is null || courseDTO.SDUCourseID is null)
            {
                return(BadRequest("Field is null"));
            }
            if (await _context.Users.FindAsync(courseDTO.OwnerUsername) == null)
            {
                return(BadRequest("User Does not exist"));
            }
            if (!courseDTO.ShortCourseName.Any() || !courseDTO.CourseName.Any() || !courseDTO.SDUCourseID.Any())
            {
                return(BadRequest("Field Empty"));
            }

            var CourseValidationResponse = Course.Validate(courseDTO.OwnerUsername, courseDTO.CourseName, courseDTO.ShortCourseName, courseDTO.SDUCourseID);

            if (CourseValidationResponse.Item1 != true)
            {
                return(BadRequest(CourseValidationResponse.Item2));
            }

            //Perform Request
            var course = await _context.Courses.FindAsync(id);

            _context.Entry(course).State = EntityState.Modified;

            course.UserUsername    = courseDTO.OwnerUsername;
            course.ShortCourseName = courseDTO.ShortCourseName;
            course.SDUCourseID     = courseDTO.SDUCourseID;
            course.CourseName      = courseDTO.CourseName;

            try
            {
                _context.Courses.Update(course);
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!CourseExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(NoContent());
        }
        public async Task <ActionResult> PostToken(SSOTokenDTO tokendata)
        {
            Console.WriteLine(tokendata);
            try
            {
                UserDTO user = await SSOHelper.GetSSOData(tokendata);

                User databaseUserReturn = await _context.Users.FindAsync(user.Username.ToLower());

                if (databaseUserReturn == null)
                {
                    _context.Users.Add(await UserFactory.Create(user.Username, user.Mail, user.Gn, user.Sn));
                    await _context.SaveChangesAsync();

                    user.AccountType = nameof(Models.User.UserType.User);
                }
                else
                {
                    if (databaseUserReturn.Mail == null)
                    {
                        databaseUserReturn.Mail = user.Mail;
                    }
                    if (databaseUserReturn.GeneralName == null)
                    {
                        databaseUserReturn.GeneralName = user.Gn;
                    }
                    if (databaseUserReturn.Surname == null)
                    {
                        databaseUserReturn.Surname = user.Sn;
                    }
                    _context.Users.Update(databaseUserReturn);
                    await _context.SaveChangesAsync();

                    user.AccountType = databaseUserReturn.AccountType.ToString();
                }

                var response = new { jwt = JwtHelper.Create(user, _configuration.GetValue <String>("APIHostName")) };
                return(Ok(response));
            }
            catch (ArgumentException)
            {
                return(Unauthorized("Authentication Failed"));
            }
        }
Example #4
0
        public async Task <ActionResult> DeleteMachine(Guid id)
        {
            //Validate id
            if (id == Guid.Empty)
            {
                return(BadRequest("Invalid ID"));
            }
            //Validate machine existance
            var machine = await _context.Machines.FindAsync(id);

            if (machine == null)
            {
                return(BadRequest("Machine Not Found"));
            }
            //Validate machine "ownership"
            if (machine.UserUsername != GetUsername())
            {
                return(BadRequest("You do not own this machine"));
            }
            //Validate machine not allready scheduled for deletion
            if ((await _context.MachineDeletionRequests.FindAsync()) != null)
            {
                return(BadRequest("Machine allready scheduled for deletion"));
            }
            //Schedule for deletion
            DateTime deletiontime = DateTime.UtcNow.AddDays(30);

            _context.MachineDeletionRequests.Add(new MachineDeletionRequest()
            {
                MachineID    = machine.MachineID,
                DeletionDate = deletiontime,
                UserUsername = GetUsername()
            });
            machine.MachineCreationStatus = CreationStatus.SHEDULED_FOR_DELETION;
            _context.Machines.Update(machine);
            await _context.SaveChangesAsync();

            //Return on successfull
            return(Ok($"Machine scheduled for deletion: {deletiontime.ToLocalTime()}"));
        }
        public async Task <IActionResult> PutGroup(Guid id, GroupNameDTO dto)
        {
            //Validate the request
            if (id != dto.GroupID)
            {
                return(BadRequest());
            }
            //Validate course
            if (!_context.Courses.Any(course => course.User.Username == GetUsername() && course.CourseID == dto.CourseID))
            {
                return(BadRequest());
            }

            try
            {
                var group = await _context.Groups.FindAsync(id);

                group.GroupName = dto.GroupName;
                _context.Groups.Update(group);
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!GroupExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }
            catch (NullReferenceException)
            {
                return(NotFound());
            }

            return(NoContent());
        }
Example #6
0
        public async Task <ActionResult> PostUser(EducatorEmailDTO emailDTO)
        {
            var email = emailDTO.Email;

            if (email == null || email.Length == 0)
            {
                return(BadRequest("Input Empty"));
            }
            if (!(new Regex(@"^[A-Za-z0-9]{1,10}@[a-zA-Z0-9]*\.sdu\.dk$").IsMatch(email)))
            {
                return(BadRequest("Email was invalid"));
            }
            var foundUser = await _context.Users.FindAsync(email.Split("@")[0]);

            if (foundUser == null)
            {
                await _context.Users.AddAsync(await UserFactory.Create(Email: email, Username: email.Split("@")[0]));

                await _context.SaveChangesAsync();

                return(Ok("New user created based on entered email"));
            }
            else
            {
                if (foundUser.AccountType == Models.User.UserType.Administrator ||
                    foundUser.AccountType == Models.User.UserType.Educator)
                {
                    return(BadRequest("Requested User allready has the requested or a higher permission level"));
                }
                foundUser.AccountType = Models.User.UserType.Educator;
                _context.Users.Update(foundUser);
                await _context.SaveChangesAsync();

                return(Ok("Existing user updated"));
            }
        }
        /// <summary>
        /// Takes machines that have the creation status of <see cref="CreationStatus.QUEUED_FOR_CREATION"/> and status of active and configures them and sets them to configured
        /// </summary>
        /// <param name="state"></param>
        private async void CreatedTimerCallback(object state)
        {
            if (_CreatedIsGoing)
            {
                return;
            }
            try
            {
                _CreatedIsGoing = true;
                VmDeploymentContext _context = GetContext();
                var PollTime = DateTimeOffset.UtcNow;
                var machines = await _context.Machines.Where(machine => machine.MachineCreationStatus == CreationStatus.QUEUED_FOR_CREATION).ToListAsync();

                foreach (Machine machine in machines)
                {
                    if (machine.MachineStatus?.MachineState == MachineStates.ACTIVE)
                    {
                        Console.WriteLine($"MachineControllerService.CreatedTimerCallback: Machine Booted after creation: { machine.MachineID}");
                        try
                        {
                            if (machine.MachineStatus?.MachineIp == null)
                            {
                                Console.WriteLine($"Error configuring machine: no ip");
                                continue;
                            }
                            await _machineConfigurator.ConfigureMachineWithFile(machine);//TODO: Return to using ssh based configuration
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine($"Error occurred configuring machine: {machine.HostName}, {machine.MachineID}");
                            Console.WriteLine($"Error: {e.Message}");
                            Console.WriteLine(e.StackTrace);
                            continue;
                        }
                        machine.MachineCreationStatus = CreationStatus.CONFIGURED;
                        _context.Machines.Update(machine);
                        await _context.SaveChangesAsync();
                    }
                }
            }
            finally
            {
                _CreatedIsGoing = false;
            }
        }
Example #8
0
        public async Task <ActionResult <Machine> > PostMachineGroupBased(CreateMachineGroupBased machines)
        {
            var Randomizer = new Random();

            //Validate input
            foreach (var machine in machines.Machines)
            {
                //Validate ownership
                var group = await _context.Groups.FindAsync(machine.Group);

                if (group == null)
                {
                    return(BadRequest($"Invalid Group id"));
                }
                if (group.CourseID != machine.CourseID)
                {
                    return(BadRequest($"GroupID: {machine.Group} is not assiciated with the course {machine.CourseID}"));
                }
                if (group.Course.UserUsername != GetUsername())
                {
                    return(Unauthorized($"You do not have ownership over the course: {machine.CourseID}, and therefor not over the group id requested"));
                }

                //Validate Content
                if (!Regex.IsMatch(machine.Hostname, ValidateHostname))
                {
                    return(BadRequest($"Invalid Hostname: {machine.Hostname}"));
                }
                if (!machine.Apt.AsParallel().All(apt => Regex.IsMatch(apt, ValidateAptRegex)))
                {
                    return(BadRequest($"Invalid apt package in list: {String.Join(", ", machine.Apt.ToArray())}"));
                }
                if (!machine.Ppa.AsParallel().All(ppa => Regex.IsMatch(ppa, ValidatePpaRegex)))
                {
                    return(BadRequest($"Invalid ppa in list: {String.Join(", ", machine.Ppa.ToArray())}"));
                }
                if (!machine.LinuxGroups.AsParallel().All(group => Regex.IsMatch(group, ValidateLinuxGroup)))
                {
                    return(BadRequest($"Invalid linux group in list: {String.Join(", ", machine.LinuxGroups)}"));
                }
                if (!machine.Ports.AsParallel().All(port => port > 0 && port <= 65535))
                {
                    return(BadRequest($"Port Out of bound in list: {String.Join(", ", machine.Ports)}"));
                }

                if (machine.VCPU != null && (machine.VCPU < 1 || machine.VCPU > 8))
                {
                    return(BadRequest($"Machine VCPU count out of bounds: {machine.VCPU}, VCPU count must be greater than 0 and less than 9"));
                }

                if (machine.Memory != null && (machine.Memory < 1024 || machine.Memory > 8192))
                {
                    return(BadRequest($"Machine memory amount out of bounds: {machine.Storage}, Memory must be greater that 1023 and less than 8193"));
                }
                if (machine.Memory != null && machine.Memory % 1024 != 0)
                {
                    return(BadRequest($"Invalid memory amount: {machine.Storage}, Memory must be a multiple of 1024"));
                }

                if (machine.Storage != null && (machine.Storage < 30720 || machine.Storage > 51200))
                {
                    return(BadRequest($"Machine storage amount out of bounds: {machine.Storage}, Memmory must be greater that 30719 and less than 51201"));
                }
                if (machine.Storage != null && machine.Storage % 1024 != 0)
                {
                    return(BadRequest($"Invalid memmory amount: {machine.Storage}, Memmory must be a multiple of 1024"));
                }

                var NewMachineID = Guid.NewGuid();
                _context.Machines.Add(new Machine
                {
                    CourseID              = machine.CourseID,
                    HostName              = machine.Hostname,
                    MachineID             = NewMachineID,
                    UserUsername          = GetUsername(),
                    MachineCreationStatus = CreationStatus.REGISTERED,
                    Apt         = machine.Apt,
                    LinuxGroups = machine.LinuxGroups,
                    Ports       = machine.Ports,
                    Ppa         = machine.Ppa,
                    Memory      = machine.Memory ?? 1024,
                    VCPU        = machine.VCPU ?? 1,
                    Storage     = machine.Storage ?? 30720
                });
                _context.MachineAssignments.Add(new()
                {
                    MachineAssignmentID = Guid.NewGuid(),
                    GroupID             = machine.Group,
                    MachineID           = NewMachineID,
                    OneTimePassword     = new string(Enumerable.Repeat(chars, 12).Select(s => s[Randomizer.Next(s.Length)]).ToArray()),
                    UserUsername        = null
                });;
            }

            await _context.SaveChangesAsync();

            return(Ok("Machines Registered for creation, creation will start soon."));
        }