コード例 #1
0
ファイル: GroupBL.cs プロジェクト: Minocula/MindTouch_Core
        public static XDoc GetGroupXmlVerbose(GroupBE group, string relation)
        {
            XDoc groupXml = GetGroupXml(group, relation);

            ServiceBE authService = ServiceBL.GetServiceById(group.ServiceId);

            if (authService != null)
            {
                groupXml.Add(ServiceBL.GetServiceXml(authService, "authentication"));
            }

            groupXml.Start("users");
            if (group.UserIdsList != null)
            {
                groupXml.Attr("count", group.UserIdsList.Length);
            }

            groupXml.Attr("href", DekiContext.Current.ApiUri.At("groups", group.Id.ToString(), "users"));
            groupXml.End();

            //Permissions for the group
            RoleBE role = PermissionsBL.GetRoleById(group.RoleId);

            groupXml.Add(PermissionsBL.GetRoleXml(role, "group"));
            return(groupXml);
        }
コード例 #2
0
ファイル: GroupBL.cs プロジェクト: Minocula/MindTouch_Core
        private static void ParseGroupXml(XDoc groupDoc, out uint?id, out string name, out ServiceBE authService, out RoleBE role, out UserBE[] userList)
        {
            name = groupDoc["groupname"].AsText ?? groupDoc["name"].AsText;
            string authserviceidstr = groupDoc["service.authentication/@id"].AsText;
            string rolestr          = groupDoc["permissions.group/role"].AsText;

            authService = null;
            role        = null;
            id          = null;


            if (!groupDoc["@id"].IsEmpty)
            {
                uint id_temp;
                if (!uint.TryParse(groupDoc["@id"].Contents, out id_temp))
                {
                    throw new GroupIdAttributeInvalidArgumentException();
                }
                id = id_temp;
            }

            if (!string.IsNullOrEmpty(authserviceidstr))
            {
                uint serviceid;
                if (!uint.TryParse(authserviceidstr, out serviceid))
                {
                    throw new ServiceAuthIdAttrInvalidArgumentException();
                }

                authService = ServiceBL.GetServiceById(serviceid);
                if (authService == null)
                {
                    throw new ServiceDoesNotExistInvalidArgumentException(serviceid);
                }
            }

            if (!string.IsNullOrEmpty(rolestr))
            {
                role = PermissionsBL.GetRoleByName(rolestr);
                if (role == null)
                {
                    throw new RoleDoesNotExistInvalidArgumentException(rolestr);
                }
            }
            else
            {
                role = PermissionsBL.RetrieveDefaultRoleForNewAccounts();
            }
            if (!groupDoc["users"].IsEmpty)
            {
                userList = ReadUserListXml(groupDoc["users"]);
            }
            else
            {
                userList = new UserBE[] { }
            };
        }
コード例 #3
0
ファイル: GroupBL.cs プロジェクト: Minocula/MindTouch_Core
        private static UserBE[] ProcessGroupMemberInput(GroupBE group, XDoc userList)
        {
            if (!userList.HasName("users"))
            {
                throw new GroupExpectedUserRootNodeInvalidArgumentException();
            }

            ServiceBE service = ServiceBL.GetServiceById(group.ServiceId);

            if (service == null)
            {
                throw new GroupServiceNotFoundFatalException(group.ServiceId, group.Name);
            }

            //Changing members of an external group is not supported. You may modify members in the external provider instead.
            if (!ServiceBL.IsLocalAuthService(service))
            {
                throw new ExternalGroupMemberInvalidOperationException();
            }

            UserBE[] members = ReadUserListXml(userList);
            ValidateGroupMemberList(service, members);
            return(members);
        }
コード例 #4
0
ファイル: AuthBL.cs プロジェクト: Minocula/MindTouch_Core
        //--- Class Methods ---
        public static UserBE Authenticate(DreamContext context, DreamMessage request, uint serviceId, bool autoCreateExternalUser, bool allowAnon, out bool altPassword)
        {
            UserBE user = null;

            altPassword = false;

            // Case 1: username/fullname, password, provider (login window)
            //      1. Validate & retrieve fullname using credentials
            //          Failed -> return null
            //      2. Populate user object
            //          A. Populates user info
            //          B. Populates group info in user object
            //      3. Does fullname exist?
            //          Yes -> Update user (email, fullname, ...)
            //          No  -> Create user
            //      4. Update Group information
            //      5. return user object
            //
            // Case 2: fullname, password (http, api, ...)
            //      1. Lookup full name, exist?
            //          Yes -> return user
            //          No -> return null
            //
            // Case 3: auth-token (header auth)
            //      0. Valid auth token?
            //          No -> return null
            //      1. Lookup user by name
            //          Found -> return user
            //          Else  -> return null

            string    userName      = null;
            string    password      = null;
            UserBE    userFromToken = null;
            ServiceBE authService   = null;

            // Extract authtoken and impersonation authtoken from request.
            // AllowAnon is false when in GET/POST: users/authenticate or when ?authenticate=true.
            // Standard user authtokens are ignored when AllowAnon=false but impersonation tokens are accepted.
            bool impersonationOnly = !allowAnon;

            userFromToken = UserFromAuthTokenInRequest(context, impersonationOnly);

            if (userFromToken == null)
            {
                HttpUtil.GetAuthentication(context.Uri.ToUri(), request.Headers, out userName, out password);
            }

            // check if we need to retrieve authentication service information
            if (serviceId > 0)
            {
                authService = ServiceBL.GetServiceById(serviceId);
                if (authService == null)
                {
                    throw new AuthServiceIdInvalidArgumentException(serviceId);
                }
                if (authService.Type != ServiceType.AUTH)
                {
                    throw new AuthNotAnAuthServiceInvalidArgumentException(serviceId);
                }
            }

            // check if a username was provided
            if (!string.IsNullOrEmpty(userName))
            {
                //Case 2: Given username + password
                if (authService == null)
                {
                    //Assuming local user or existing external account
                    user = DbUtils.CurrentSession.Users_GetByName(userName);
                    if (user != null)
                    {
                        serviceId   = user.ServiceId;
                        authService = ServiceBL.GetServiceById(serviceId);
                    }
                    else
                    {
                        LoginAccessDenied(context, request, userName, null, password);
                    }
                }
                if (authService == null)
                {
                    throw new AuthServiceIdInvalidArgumentException(serviceId);
                }
                if (authService.Type != ServiceType.AUTH)
                {
                    throw new AuthNotAnAuthServiceInvalidArgumentException(serviceId);
                }
                if (user == null)
                {
                    //Performing auth on local account
                    if (ServiceBL.IsLocalAuthService(authService))
                    {
                        user = DbUtils.CurrentSession.Users_GetByName(userName);
                    }
                    else
                    {
                        //Performing external auth. Lookup by external user name
                        user = DbUtils.CurrentSession.Users_GetByExternalName(userName, authService.Id);
                    }
                    if (user != null && user.ServiceId != authService.Id)
                    {
                        ServiceBE currentUsersAuthService = ServiceBL.GetServiceById(user.ServiceId);
                        if (currentUsersAuthService != null)
                        {
                            throw new AuthLoginExternalUserConflictException(currentUsersAuthService.Description);
                        }
                        throw new LoginExternalUserUnknownConflictException();
                    }
                }

                //Local account in the db.
                if (user != null && ServiceBL.IsLocalAuthService(authService))
                {
                    //Validate password for local account or validate the apikey
                    if (!IsValidAuthenticationForLocalUser(user, password, out altPassword))
                    {
                        // try impersonation using the ApiKey
                        if (string.IsNullOrEmpty(password) && PermissionsBL.ValidateRequestApiKey())
                        {
                            DekiContext.Current.Instance.Log.InfoFormat("user '{0}' authenticated via apikey impersonation", userName);
                        }
                        else
                        {
                            LoginAccessDenied(context, request, userName, user.ID, password);
                        }
                    }
                }

                // User was not found in the db and not being asked to create it.
                if (user == null && !autoCreateExternalUser)
                {
                    LoginAccessDenied(context, request, userName, null, password);
                }

                // Creating local account if apikey checks out and our authservice is local
                if (user == null && string.IsNullOrEmpty(password) && PermissionsBL.ValidateRequestApiKey() && ServiceBL.IsLocalAuthService(authService))
                {
                    XDoc newUserDoc = new XDoc("user")
                                      .Elem("username", userName);
                    DreamMessage newUserResponse = DekiContext.Current.ApiPlug.At("users")
                                                   .With("apikey", DreamContext.Current.GetParam("apikey", string.Empty))
                                                   .Post(newUserDoc);
                    user = UserBL.GetUserById(newUserResponse.ToDocument()["/user/@id"].AsUInt ?? 0);
                    if (user != null && !string.IsNullOrEmpty(password))
                    {
                        user = UserBL.SetPassword(user, password, false);
                    }
                }

                // Got an external account
                // Passing in the user object from db if it was found.
                List <GroupBE> externalGroups = null;
                if (!ServiceBL.IsLocalAuthService(authService))
                {
                    bool   bypassAuthentication = false;
                    string externalName;
                    if (user == null || string.IsNullOrEmpty(user.ExternalName))
                    {
                        externalName = userName;
                    }
                    else
                    {
                        externalName = user.ExternalName;
                    }

                    // If apikey is valid, try to bypass auth with the external provider
                    // and only lookup user/group details.
                    if (string.IsNullOrEmpty(password) && PermissionsBL.ValidateRequestApiKey())
                    {
                        DekiContext.Current.Instance.Log.InfoFormat("user '{0}' authenticating being bypassed via apikey impersonation", userName);
                        bypassAuthentication = true;
                    }

                    user = ExternalServiceSA.BuildUserFromAuthService(authService, user, userName, bypassAuthentication, externalName, password, out externalGroups);
                }

                // User was not found or did not authenticate with external provider
                if (user == null)
                {
                    LoginAccessDenied(context, request, userName, null, password);
                }
                else
                {
                    //New user creation from external provider
                    if (user.ID == 0)
                    {
                        if (!autoCreateExternalUser)
                        {
                            LoginAccessDenied(context, request, userName, null, password);
                        }
                    }
                    else
                    {
                        //user exists
                        // TODO (steveb): ???
                    }
                    if (user.UserActive)
                    {
                        user = UserBL.CreateOrUpdateUser(user);
                        if (externalGroups != null)
                        {
                            UserBL.UpdateUsersGroups(user, externalGroups.ToArray());
                        }
                    }
                }
            }
            else if (userFromToken != null)
            {
                // valid token exists that resolved to a user
                user = userFromToken;
            }
            else if (allowAnon)
            {
                // Anonymous user
                user = DbUtils.CurrentSession.Users_GetByName(DekiWikiService.ANON_USERNAME);
            }
            if (user == null)
            {
                //No credentials. Or token not provided or is invalid.
                LoginAccessDenied(context, request, null, null, password);
            }
            else if (!user.UserActive && !PermissionsBL.ValidateRequestApiKey())
            {
                //If a valid api key is provided, override the disabled account flag
                throw new AuthUserDisabledForbiddenException(user.Name);
            }
            return(user);
        }
コード例 #5
0
ファイル: UserBL.cs プロジェクト: Minocula/MindTouch_Core
        public static XDoc GetUserXmlVerbose(UserBE user, string relationAttr, bool showPrivateInfo, bool showGroups, bool showProperties)
        {
            XDoc userXml = GetUserXml(user, relationAttr, showPrivateInfo);

            userXml.Elem("date.created", user.CreateTimestamp);

            if (!IsAnonymous(user))
            {
                PageBE homePage = GetHomePage(user);
                if (homePage != null && homePage.ID != 0)
                {
                    userXml.Add(PageBL.GetPageXml(homePage, "home"));
                }
            }

            userXml.Start("status").Value(user.UserActive ? "active" : "inactive").End();
            userXml.Start("date.lastlogin").Value(user.Touched).End();
            userXml.Start("language").Value(user.Language).End();
            userXml.Start("timezone").Value(user.Timezone).End();

            ServiceBE authService = ServiceBL.GetServiceById(user.ServiceId);

            if (authService != null)
            {
                userXml.Add(ServiceBL.GetServiceXml(authService, "authentication"));
            }

            //Permissions for the user from user role
            userXml.Add(PermissionsBL.GetRoleXml(PermissionsBL.GetRoleById(user.RoleId), "user"));

            ulong effectivePermissions = PermissionsBL.CalculateEffectiveUserRights(user);

            //Effective permissions for the user from the role + group roles.
            userXml.Add(PermissionsBL.GetPermissionXml(effectivePermissions, "effective"));

            // Set of permissions revoked from the user
            userXml.Add(PermissionsBL.GetPermissionsRevokedXml(user));

            // check if groups should be included
            if (showGroups)
            {
                userXml.Start("groups");
                IList <GroupBE> groups = DbUtils.CurrentSession.Groups_GetByUser(user.ID);
                if (null != groups)
                {
                    foreach (GroupBE g in groups)
                    {
                        userXml.Add(GroupBL.GetGroupXmlVerbose(g, null));
                    }
                }
                userXml.End();
            }

            // retrieve properties for current user while providing an href for other users.
            if (showProperties && (DekiContext.Current != null && DekiContext.Current.User != null && DekiContext.Current.User.ID == user.ID))
            {
                IList <ResourceBE> props = PropertyBL.Instance.GetUserProperties(user.ID);
                userXml = PropertyBL.Instance.GetPropertyXml(props, GetUri(user), null, null, userXml);
            }
            else
            {
                userXml.Start("properties").Attr("href", GetUri(user).At("properties")).End();
            }

            // TODO Max: get <subscriptions> (watchlist) not implemented
            return(userXml);
        }
コード例 #6
0
ファイル: UserBL.cs プロジェクト: Minocula/MindTouch_Core
        private static void ParseUserXml(XDoc userDoc, out uint?id, out string username, out string email, out string fullname, out ServiceBE authService, out RoleBE role, out bool?active, out string language, out string timezone)
        {
            username = userDoc["username"].AsText;
            email    = userDoc["email"].AsText;
            fullname = userDoc["fullname"].AsText;
            language = userDoc["language"].AsText;
            timezone = userDoc["timezone"].AsText;
            string authserviceidstr = userDoc["service.authentication/@id"].AsText;
            string rolestr          = userDoc["permissions.user/role"].AsText;
            string statusStr        = userDoc["status"].AsText;

            authService = null;
            role        = null;

            id = null;

            if (!userDoc["@id"].IsEmpty)
            {
                uint id_temp;
                if (!uint.TryParse(userDoc["@id"].Contents, out id_temp))
                {
                    throw new UserIdAttrInvalidArgumentException();
                }
                id = id_temp;
            }

            if (!string.IsNullOrEmpty(authserviceidstr))
            {
                uint serviceid;
                if (!uint.TryParse(authserviceidstr, out serviceid))
                {
                    throw new ServiceAuthIdAttrInvalidArgumentException();
                }

                authService = ServiceBL.GetServiceById(serviceid);
                if (authService == null)
                {
                    throw new ServiceDoesNotExistInvalidArgumentException(serviceid);
                }
            }

            if (!string.IsNullOrEmpty(rolestr))
            {
                role = PermissionsBL.GetRoleByName(rolestr);
                if (role == null)
                {
                    throw new RoleDoesNotExistInvalidArgumentException(rolestr);
                }
            }

            if (!string.IsNullOrEmpty(statusStr))
            {
                switch (statusStr.ToLowerInvariant())
                {
                case "active":
                    active = true;
                    break;

                case "inactive":
                    active = false;
                    break;

                default:
                    throw new UserStatusAttrInvalidArgumentException();
                }
            }
            else
            {
                active = null;
            }

            if (!string.IsNullOrEmpty(timezone))
            {
                if (!timeZoneRegex.Match(timezone).Success)
                {
                    throw new UserTimezoneInvalidArgumentException();
                }
            }

            if (!string.IsNullOrEmpty(language))
            {
                string[] validLanguages = DekiContext.Current.Instance.Languages.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                string   tempLanguage   = language;
                if (!Array.Exists(validLanguages, delegate(string temp) { return(temp.EqualsInvariantIgnoreCase(tempLanguage)); }))
                {
                    throw new UserInvalidLanguageException();
                }
            }
        }