예제 #1
0
        /// <summary>
        /// Generates a JSON Web Token Token (JwtToken) for a given user and role. Based on the method with the same name from https://github.com/jatarga/WebApiJwt/blob/master/Controllers/AccountController.cs
        /// </summary>
        /// <param name="user">Which <see cref="GirafUser"/> to generate the token for</param>
        /// <returns>
        /// JWT Token as a string
        /// </returns>
        private async Task <string> GenerateJwtToken(GirafUser user, string impersonatedBy)
        {
            var claims = new List <Claim>
            {
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(ClaimTypes.NameIdentifier, user.Id),
                new Claim("departmentId", user.DepartmentKey?.ToString() ?? ""),
            };

            claims.AddRange(await GetRoleClaims(user));

            var key     = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.Value.JwtKey));
            var creds   = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration.Value.JwtExpireDays));

            var token = new JwtSecurityToken(
                _configuration.Value.JwtIssuer,
                _configuration.Value.JwtIssuer,
                claims,
                expires: expires,
                signingCredentials: creds
                );

            return(new JwtSecurityTokenHandler().WriteToken(token));
        }
예제 #2
0
        /// <summary>
        /// Checks if the user has some form of ownership of the pictogram.
        /// </summary>
        /// <param name="picto">The Pictogram in need of checking.</param>
        /// <param name="usr">The user in question.</param>
        /// <returns>A bool indicating whether the user owns the pictogram or not.</returns>
        private async Task <bool> CheckOwnership(Pictogram picto, GirafUser usr)
        {
            var ownsPictogram = false;

            switch (picto.AccessLevel)
            {
            case AccessLevel.PUBLIC:
                ownsPictogram = true;
                break;

            case AccessLevel.PROTECTED:
                ownsPictogram = await _giraf.CheckProtectedOwnership(picto, usr);

                break;

            case AccessLevel.PRIVATE:
                ownsPictogram = await _giraf.CheckPrivateOwnership(picto, usr);

                break;
            }
            if (!ownsPictogram)
            {
                return(false);
            }
            return(true);
        }
예제 #3
0
        /// <summary>
        /// Checks that a user gots the rights to register a specific role to a specific department
        /// Citizen can never register, department and guardian can only register guardians and citizens in same dep
        /// Super user can register all roles
        /// </summary>
        public async Task <bool> HasRegisterUserAccess(GirafUser authUser, GirafRoles roleToAdd, long departmentKey)
        {
            if (authUser == null)
            {
                return(false);
            }

            var authUserRole = await _roleManager.findUserRole(_userManager, authUser);

            if (authUserRole == GirafRoles.Citizen)
            {
                return(false);
            }

            if (authUserRole == GirafRoles.Guardian || authUserRole == GirafRoles.Department)
            {
                if (!(roleToAdd == GirafRoles.Guardian || roleToAdd == GirafRoles.Citizen) &&
                    departmentKey == authUser.DepartmentKey)
                {
                    return(false);
                }
            }
            // only super users can add Department role in fact a super user can do anything so just return true
            return(true);
        }
예제 #4
0
        /// <summary>
        /// Gets roles s.t we can get role from payload
        /// </summary>
        /// <param name="user"><see cref="GirafUser"/> to get claims for</param>
        /// <returns>The role claims for the given user</returns>
        private async Task <List <Claim> > GetRoleClaims(GirafUser user)
        {
            var roleclaims = new List <Claim>();
            var userRoles  = await _giraf._userManager.GetRolesAsync(user);

            roleclaims.AddRange(userRoles.Select(userRole => new Claim(ClaimTypes.Role, userRole)));
            return(roleclaims);
        }
예제 #5
0
        /// <summary>
        /// Method for checking whether the authenticated user is allowed to view information related to given department.
        /// </summary>
        public async Task <bool> HasReadDepartmentAccess(GirafUser authUser, long?departmentKey)
        {
            var authUserRole = await _roleManager.findUserRole(_userManager, authUser);

            if (authUserRole == GirafRoles.SuperUser)
            {
                return(true);
            }

            return(authUser.DepartmentKey == departmentKey);
        }
예제 #6
0
 private static void AddPictogramsToUser(GirafUser user, params Pictogram[] pictograms)
 {
     System.Console.WriteLine("Adding pictograms to " + user.UserName);
     foreach (var pict in pictograms)
     {
         if (pict.AccessLevel != AccessLevel.PRIVATE)
         {
             throw new InvalidOperationException($"You may only add private pictograms to users." +
                                                 " Pictogram id: {pict.Id}, AccessLevel: {pict.AccessLevel}.");
         }
         new UserResource(user, pict);
     }
 }
예제 #7
0
        private void AddGuardiansToCitizens(GirafUser user)
        {
            var roleGuardianId = _giraf._context.Roles.Where(r => r.Name == GirafRole.Guardian)
                                 .Select(c => c.Id).FirstOrDefault();
            var userIds = _giraf._context.UserRoles.Where(u => u.RoleId == roleGuardianId)
                          .Select(r => r.UserId).Distinct();
            var guardians = _giraf._context.Users.Where(u => userIds.Any(ui => ui == u.Id) &&
                                                        u.DepartmentKey == user.DepartmentKey).ToList();

            foreach (var guardian in guardians)
            {
                user.AddGuardian(guardian);
            }
        }
예제 #8
0
        private void AddCitizensToGuardian(GirafUser user)
        {
            // Add a relation to all the newly created guardians citizens
            var roleGuardianId = _giraf._context.Roles.Where(r => r.Name == GirafRole.Citizen)
                                 .Select(c => c.Id).FirstOrDefault();
            var userIds = _giraf._context.UserRoles.Where(u => u.RoleId == roleGuardianId)
                          .Select(r => r.UserId).Distinct();
            var citizens = _giraf._context.Users.Where(u => userIds.Any(ui => ui == u.Id) &&
                                                       u.DepartmentKey == user.DepartmentKey).ToList();

            foreach (var citizen in citizens)
            {
                user.AddCitizen(citizen);
            }
        }
예제 #9
0
        /// <summary>
        /// Check that a user has access to read the template of a given user
        /// </summary>
        public async Task <bool> HasTemplateAccess(GirafUser authUser)
        {
            if (authUser == null)
            {
                return(false);
            }

            var authUserRole = await _roleManager.findUserRole(_userManager, authUser);

            if (authUserRole == GirafRoles.Citizen)
            {
                return(false);
            }
            return(true);
        }
예제 #10
0
        public async Task <bool> HasTemplateAccess(GirafUser authUser, long?departmentKey)
        {
            if (departmentKey == null)
            {
                return(false);
            }

            var authUserRole = await _roleManager.findUserRole(_userManager, authUser);

            if (authUserRole == GirafRoles.SuperUser)
            {
                return(true);
            }

            return(HasTemplateAccess(authUser).Result&& authUser?.DepartmentKey == departmentKey);
        }
예제 #11
0
        /// <summary>
        /// Creates a list of roles a given user is part of
        /// </summary>
        /// <param name="roleManager">Reference to the roleManager</param>
        /// <param name="userManager">Reference to the userManager</param>
        /// <param name="user">The user in question</param>
        /// <returns>
        /// Instance of GirafRole enum
        /// </returns>
        public static async Task <GirafRoles> findUserRole(
            this RoleManager <GirafRole> roleManager,
            UserManager <GirafUser> userManager,
            GirafUser user)
        {
            GirafRoles userRole = new GirafRoles();

            foreach (var role in roleManager.Roles)
            {
                if (await userManager.IsInRoleAsync(user, role.Name))
                {
                    userRole = (GirafRoles)Enum.Parse(typeof(GirafRoles), role.Name);
                }
            }
            return(userRole);
        }
예제 #12
0
        public Task <bool> CheckPrivateOwnership(Pictogram pictogram, GirafUser user)
        {
            if (user == null)
            {
                return(Task.FromResult(false));
            }

            var ownsResource = _context.UserResources
                               .Any(ur => ur.Pictogram == pictogram && ur.Other == user);

            if (ownsResource)
            {
                return(Task.FromResult(true));
            }

            return(Task.FromResult(false));
        }
예제 #13
0
        public Task <bool> CheckProtectedOwnership(Pictogram pictogram, GirafUser user)
        {
            if (user == null)
            {
                return(Task.FromResult(false));
            }

            var ownsResource = _context.DepartmentResources
                               .Any(dr => dr.PictogramKey == pictogram.Id &&
                                    dr.OtherKey == user.DepartmentKey);

            if (ownsResource)
            {
                return(Task.FromResult(true));
            }

            return(Task.FromResult(false));
        }
예제 #14
0
        /// <summary>
        /// Checks if the user owns the given <paramref name="pictogram"/>.
        /// </summary>
        /// <param name="pictogram">The pictogram to check the ownership for.</param>
        /// <param name="user"></param>
        /// <returns>True if the user is authorized to see the resource and false if not.</returns>
        public async Task <bool> CheckPrivateOwnership(Pictogram pictogram, GirafUser user)
        {
            if (pictogram.AccessLevel != AccessLevel.PRIVATE)
            {
                return(false);
            }

            //The pictogram was not public, check if the user owns it.
            if (user == null)
            {
                return(false);
            }
            var ownedByUser = await _context.UserResources
                              .Where(ur => ur.PictogramKey == pictogram.Id && ur.OtherKey == user.Id)
                              .AnyAsync();

            return(ownedByUser);
        }
예제 #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:GirafRest.Models.DTOs.GirafUserDTO"/> class.
        /// </summary>
        /// <param name="user">User.</param>
        /// <param name="userRole">User role.</param>
        /// <param name="addGuardianRelation">If set to <c>true</c> add guardian relation.</param>
        public GirafUserDTO(GirafUser user, GirafRoles userRole)
        {
            //Add all trivial values
            Id         = user.Id;
            Username   = user.UserName;
            ScreenName = user.DisplayName;
            RoleName   = userRole.ToString();
            Role       = userRole;

            //Check if a user is in a department, add null as key if not.
            if (user.Department == null && user.DepartmentKey == -1)
            {
                Department = null;
            }
            else
            {
                Department = user.DepartmentKey;
            }
        }
예제 #16
0
        /// <summary>
        ///  Given the authenticated user and the id on another user this methods check if the authenticated user
        /// has the access to edit the provided user's userinformation.
        /// Does not currently support parents.
        /// </summary>
        public async Task <bool> HasEditOrReadUserAccess(GirafUser authUser, GirafUser userToEdit)
        {
            if (authUser == null || userToEdit == null)
            {
                return(false);
            }

            var authUserRole = await _roleManager.findUserRole(_userManager, authUser);

            var userRole = await _roleManager.findUserRole(_userManager, userToEdit);

            if (authUser.Id == userToEdit.Id)
            {
                return(true);
            }

            if (userRole == GirafRoles.SuperUser)
            {
                return(false);
            }

            switch (authUserRole)
            {
            case GirafRoles.Citizen:
                return(false);

            case GirafRoles.Guardian:
                if (authUser.DepartmentKey != userToEdit.DepartmentKey || userRole != GirafRoles.Citizen)
                {
                    return(false);
                }
                break;

            case GirafRoles.Department:
                if (authUser.DepartmentKey != userToEdit.DepartmentKey)
                {
                    return(false);
                }
                break;
            }

            return(true);
        }
예제 #17
0
        /// <summary>
        /// Checks if the current user's department owns the given resource.
        /// </summary>
        /// <param name="resource">The resource to check ownership for.</param>
        /// <param name="user"></param>
        /// <returns>True if the user's department owns the pictogram, false if not.</returns>
        public async Task <bool> CheckProtectedOwnership(Pictogram resource, GirafUser user)
        {
            if (resource.AccessLevel != AccessLevel.PROTECTED)
            {
                return(false);
            }

            if (user == null)
            {
                return(false);
            }

            //The pictogram was not owned by user, check if his department owns it.
            var ownedByDepartment = await _context.DepartmentResources
                                    .Where(dr => dr.PictogramKey == resource.Id && dr.OtherKey == user.Department.Key)
                                    .AnyAsync();

            return(ownedByDepartment);
        }
예제 #18
0
        public async Task <Response <DepartmentDTO> > Post([FromBody] DepartmentDTO depDTO)
        {
            try
            {
                if (depDTO?.Name == null)
                {
                    return(new ErrorResponse <DepartmentDTO>(ErrorCode.MissingProperties,
                                                             "Deparment name has to be specified!"));
                }

                var authenticatedUser = await _giraf.LoadBasicUserDataAsync(HttpContext.User);

                if (authenticatedUser == null)
                {
                    return(new ErrorResponse <DepartmentDTO>(ErrorCode.UserNotFound));
                }

                var userRole = await _roleManager.findUserRole(_giraf._userManager, authenticatedUser);

                if (userRole != GirafRoles.SuperUser)
                {
                    return(new ErrorResponse <DepartmentDTO>(ErrorCode.NotAuthorized));
                }

                //Add the department to the database.
                Department department = new Department(depDTO);

                //Add all members specified by either id or username in the DTO
                if (depDTO.Members != null)
                {
                    foreach (var mem in depDTO.Members)
                    {
                        var usr = await _giraf._context.Users
                                  .Where(u => u.UserName == mem.UserName || u.Id == mem.UserId)
                                  .FirstOrDefaultAsync();

                        if (usr == null)
                        {
                            return(new ErrorResponse <DepartmentDTO>(ErrorCode.InvalidProperties,
                                                                     "The member list contained an invalid id: " + mem));
                        }
                        department.Members.Add(usr);
                        usr.Department = department;
                    }
                }

                //Add all the resources with the given ids
                if (depDTO.Resources != null)
                {
                    foreach (var reso in depDTO.Resources)
                    {
                        var res = await _giraf._context.Pictograms
                                  .Where(p => p.Id == reso)
                                  .FirstOrDefaultAsync();

                        if (res == null)
                        {
                            return(new ErrorResponse <DepartmentDTO>(ErrorCode.InvalidProperties,
                                                                     "The list of resources contained an invalid resource id: " + reso));
                        }
                        var dr = new DepartmentResource(department, res);
                        await _giraf._context.DepartmentResources.AddAsync(dr);
                    }
                }

                await _giraf._context.Departments.AddAsync(department);

                //Create a new user with the supplied information

                var departmentUser = new GirafUser(depDTO.Name, department)
                {
                    IsDepartment = true
                };

                //department.Members.Add(user);

                var identityUser = await _giraf._userManager.CreateAsync(departmentUser, "0000");

                if (identityUser.Succeeded == false)
                {
                    return(new ErrorResponse <DepartmentDTO>(ErrorCode.CouldNotCreateDepartmentUser, string.Join("\n", identityUser.Errors)));
                }

                await _giraf._userManager.AddToRoleAsync(departmentUser, GirafRole.Department);

                //Save the changes and return the entity
                await _giraf._context.SaveChangesAsync();

                var members = DepartmentDTO.FindMembers(department.Members, _roleManager, _giraf);
                return(new Response <DepartmentDTO>(new DepartmentDTO(department, members)));
            }
            catch (System.Exception e)
            {
                var errorDescription = $"Exception in Post: {e.Message}, {e.InnerException}";
                _giraf._logger.LogError(errorDescription);
                return(new ErrorResponse <DepartmentDTO>(ErrorCode.Error, errorDescription));
            }
        }
예제 #19
0
 public GuardianRelation(GirafUser guardian, GirafUser citizen)
 {
     this.Citizen  = citizen;
     this.Guardian = guardian;
 }
예제 #20
0
        public async Task <bool> HasEditDepartmentAccess(GirafUser authUser, long?departmentKey)
        {
            var authUserRole = await _roleManager.findUserRole(_userManager, authUser);

            return(authUserRole == GirafRoles.SuperUser);
        }
예제 #21
0
        public async Task <Response <GirafUserDTO> > Register([FromBody] RegisterDTO model)
        {
            if (model == null)
            {
                return(new ErrorResponse <GirafUserDTO>(ErrorCode.MissingProperties));
            }
            //Check that all the necesarry data has been supplied
            if (!ModelState.IsValid)
            {
                return(new ErrorResponse <GirafUserDTO>(ErrorCode.MissingProperties));
            }

            if (String.IsNullOrEmpty(model.Username) || String.IsNullOrEmpty(model.Password))
            {
                return(new ErrorResponse <GirafUserDTO>(ErrorCode.InvalidCredentials));
            }

            var UserRoleStr = GirafRoleFromEnumToString(model.Role);

            if (UserRoleStr == null)
            {
                return(new ErrorResponse <GirafUserDTO>(ErrorCode.RoleNotFound));
            }

            // check that authenticated user has the right to add user for the given department
            // else all guardians, deps and admin roles can create user that does not belong to a dep
            if (model.DepartmentId != null)
            {
                if (!(await _authentication.HasRegisterUserAccess(await _giraf._userManager.GetUserAsync(HttpContext.User),
                                                                  model.Role, model.DepartmentId.Value)))
                {
                    return(new ErrorResponse <GirafUserDTO>(ErrorCode.NotAuthorized));
                }
            }

            var doesUserAlreadyExist = (_giraf._context.Users.FirstOrDefault(u => u.UserName == model.Username) != null);

            if (doesUserAlreadyExist)
            {
                return(new ErrorResponse <GirafUserDTO>(ErrorCode.UserAlreadyExists));
            }

            Department department = await _giraf._context.Departments.Where(dep => dep.Key == model.DepartmentId).FirstOrDefaultAsync();

            // Check that the department with the specified id exists
            if (department == null && model.DepartmentId != null)
            {
                return(new ErrorResponse <GirafUserDTO>(ErrorCode.DepartmentNotFound));
            }

            //Create a new user with the supplied information
            var user = new GirafUser(model.Username, department);

            if (model.DisplayName == null)
            {
                user.DisplayName = model.Username;
            }
            else
            {
                user.DisplayName = model.DisplayName;
            }
            var result = await _giraf._userManager.CreateAsync(user, model.Password);

            if (result.Succeeded)
            {
                if (department != null)
                {
                    if (model.Role == GirafRoles.Citizen)
                    {
                        AddGuardiansToCitizens(user);
                    }
                    else if (model.Role == GirafRoles.Guardian)
                    {
                        AddCitizensToGuardian(user);
                    }
                    // save changes
                    await _giraf._context.SaveChangesAsync();
                }
                await _giraf._userManager.AddToRoleAsync(user, UserRoleStr);

                await _signInManager.SignInAsync(user, isPersistent : true);

                _giraf._logger.LogInformation("User created a new account with password.");

                return(new Response <GirafUserDTO>(new GirafUserDTO(user, model.Role)));
            }

            return(new ErrorResponse <GirafUserDTO>(ErrorCode.Error));
        }