def __init__(self, access_token):
        self.access_token = access_token
        self.api_base_uri = constant.Resources.MSGraph + 'v1.0' + '/'
        self.rest_api_service = RestApiService()

        auth_provider = AuthProvider()
        auth_provider.access_token(self.access_token)
        self.ms_graph_client = msgraph.GraphServiceClient(
            self.api_base_uri, auth_provider, msgraph.HttpProvider())
示例#2
0
class AADGraphService(object):

    def __init__(self, tenant_id, access_token):
        self.api_base_uri = constant.Resources.AADGraph + tenant_id + '/'
        self.access_token = access_token
        self.rest_api_service = RestApiService()

    def get_service_principal(self):
        url = self.api_base_uri + "servicePrincipals?api-version=1.6&$filter=appId eq '%s'" % constant.client_id
        app_content = self.rest_api_service.get_json(url, self.access_token)
        return app_content['value'][0]

    def delete_service_principal(self, service_principal_id):
        version = '?api-version=1.6'
        url = self.api_base_uri + 'servicePrincipals/%s' % service_principal_id + version
        self.rest_api_service.delete(url, self.access_token)

    def add_app_role_assignments(self, service_principal_id, service_principal_id_name):
        url = self.api_base_uri + 'users?api-version=1.6&$expand=appRoleAssignments'
        users_content = self.rest_api_service.get_json(url, self.access_token)
        users = users_content['value']

        count = 0
        for user in users:
            if all(a['resourceId'] != service_principal_id for a in user['appRoleAssignments']):
                self._add_app_role_assignment(user, service_principal_id, service_principal_id_name)
                count = count + 1                
        return count

    def _add_app_role_assignment(self, user, service_principal_id, service_principal_id_name):
        app_role_assignment = {
            'odata.type': 'Microsoft.DirectoryServices.AppRoleAssignment',
            'principalDisplayName': user['displayName'],
            'principalId': user['objectId'],
            'principalType': 'User',
            'resourceId': service_principal_id,
            'resourceDisplayName': service_principal_id_name
        }
        post_url = self.api_base_uri + 'users/%s' % user['objectId'] + '/appRoleAssignments?api-version=1.6'
        self.rest_api_service.post_json(post_url, self.access_token, data=app_role_assignment)
示例#3
0
 def __init__(self, tenant_id, access_token):
     self.api_base_uri = constant.Resources.AADGraph + tenant_id + '/'
     self.access_token = access_token
     self.rest_api_service = RestApiService()
 def __init__(self, tenant_id, access_token):
     self.api_base_uri = constant.Resources.MSGraph + '/' + constant.Resources.MSGraph_VERSION + '/'
     self.access_token = access_token
     self.rest_api_service = RestApiService()
     self.skip_token_re = re.compile('(?<=skiptoken=).*')
class EducationService(object):
    def __init__(self, tenant_id, access_token):
        self.api_base_uri = constant.Resources.MSGraph + '/' + constant.Resources.MSGraph_VERSION + '/'
        self.access_token = access_token
        self.rest_api_service = RestApiService()
        self.skip_token_re = re.compile('(?<=skiptoken=).*')

    def get_me(self):
        url = self.api_base_uri + 'education/me?$expand=schools,classes'
        return self.rest_api_service.get_object(url,
                                                self.access_token,
                                                model=EduUser)

    def get_schools(self):
        '''
        Get all schools that exist in the Azure Active Directory tenant.
        '''
        url = self.api_base_uri + 'education/schools'
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=School)

    def get_school(self, school_id):
        '''
        Get a school by using the object_id.
        '''
        url = self.api_base_uri + 'education/schools/%s' % school_id
        return self.rest_api_service.get_object(url,
                                                self.access_token,
                                                model=School)

    def get_my_classes(self, school_id=None):
        '''
        Get my classes within a school
        <param name="school_id">The school id.</param>
        '''
        url = self.api_base_uri + 'education/me/classes?$expand=schools'
        classes = self.rest_api_service.get_object_list(url,
                                                        self.access_token,
                                                        model=Class)
        if school_id:
            classes = [
                c for c in classes if any(s.id == school_id for s in c.schools)
            ]

        for c in classes:
            c.members = self.get_class_members(c.id)

        classes.sort(key=lambda c: c.code)
        return classes

    def get_classes(self, school_id, top=12, nextlink=''):
        '''
        Get classes within a school
        <param name="school_id">The school id.</param>
        <param name="mysection_emails">All my section's email</param>
        <param name="top">Get record number from API</param>
        <param name="nextlink">Get skiptoken from nextlink</param>
        '''
        skiptoken = self._get_skip_token(nextlink)
        url = self.api_base_uri + "education/schools/%s/classes?$expand=schools&$top=%s&skiptoken=%s" % (
            school_id, top, skiptoken)
        return self.rest_api_service.get_object_list(
            url, self.access_token, model=Class, next_key='@odata.nextLink')

    def get_class(self, class_id):
        '''
        Get a section by using the object_id.
        <param name="object_id">The Object ID of the section.</param>
        '''
        url = self.api_base_uri + "education/classes/%s" % class_id
        return self.rest_api_service.get_object(url,
                                                self.access_token,
                                                model=Class)

    def get_class_members(self, class_id):
        '''
        Get a class members by using the object_id.
        <param name="class_id">The Object ID of the section.</param>
        <param name="object_type">The members type.</param>
        '''
        url = self.api_base_uri + 'education/classes/%s/members' % class_id
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=EduUser)

    def get_teachers(self, school_id):
        '''
        Get teachers within a school
        '''
        url = self.api_base_uri + "users?$filter=extension_fe2174665583431c953114ff7268b7b3_Education_SyncSource_SchoolId eq '%s' and extension_fe2174665583431c953114ff7268b7b3_Education_ObjectType eq 'Teacher'" % school_id
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=EduUser)

    def add_member(self, class_id, user_id):
        '''
        Add a user to members of a class.
        Reference URL: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/group_post_members
        '''
        url = self.api_base_uri + "groups/" + class_id + "/members/$ref"
        data = {
            '@odata.id':
            'https://graph.microsoft.com/v1.0/directoryObjects/' + user_id
        }
        return self.rest_api_service.post_json(url, self.access_token, None,
                                               data)

    def add_owner(self, class_id, user_id):
        '''
        Add a user to owner of a class.
        Reference URL: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/group_post_owners
        '''
        url = self.api_base_uri + "groups/" + class_id + "/owners/$ref"
        data = {
            '@odata.id': 'https://graph.microsoft.com/v1.0/users/' + user_id
        }
        return self.rest_api_service.post_json(url, self.access_token, None,
                                               data)

    def get_assignments(self, class_id):
        '''
        Get assignments of a class.
        '''
        url = self.api_base_uri + 'education/classes/' + class_id + "/assignments"
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=Assignment)

    def get_assignment(self, class_id, assignment_id):
        url = self.api_base_uri + 'education/classes/' + class_id + "/assignments/" + assignment_id
        return self.rest_api_service.get_object(url,
                                                self.access_token,
                                                model=Assignment)

    def add_assignment(self, class_id, name, dueDateTime):
        url = self.api_base_uri + 'education/classes/' + class_id + "/assignments"
        data = {
            "displayName": name,
            "status": "draft",
            "dueDateTime": dueDateTime,
            "allowStudentsToAddResourcesToSubmission": "true",
            "assignTo": {
                "@odata.type":
                "#microsoft.graph.educationAssignmentClassRecipient"
            }
        }
        return self.rest_api_service.post_json(url, self.access_token, None,
                                               data)

    def publish_assignment(self, class_id, assignment_id):
        url = self.api_base_uri + "education/classes/" + class_id + "/assignments/" + assignment_id + "/publish"
        return self.rest_api_service.post_json(url, self.access_token, None,
                                               None)

    def get_Assignment_Resource_Folder_URL(self, class_id, assignment_id):
        url = self.api_base_uri + "education/classes/" + class_id + "/assignments/" + assignment_id + "/GetResourcesFolderUrl"
        return self.rest_api_service.get_json(url, self.access_token)

    def get_Assignment_Resources(self, class_id, assignment_id):
        url = self.api_base_uri + "education/classes/" + class_id + "/assignments/" + assignment_id + "/resources"
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=AssignmentResource)

    def get_Assignment_Submissions_By_User(self, class_id, assignment_id,
                                           user_id):
        url = self.api_base_uri + 'education/classes/' + class_id + '/assignments/' + assignment_id + '/submissions?$filter=submittedBy/user/id eq \'' + user_id + '\''
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=AssignmentResource)

    def get_Submission_Resources(self, class_id, assignment_id, user_id):
        url = self.api_base_uri + 'education/classes/' + class_id + '/assignments/' + assignment_id + '/submissions?$filter=submittedBy/user/id eq \'' + user_id + '\''
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=AssignmentResource)

    def get_Submissions(self, class_id, assignment_id):
        url = self.api_base_uri + 'education/classes/' + class_id + '/assignments/' + assignment_id + '/submissions'
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=Submission)

    def get_Submission_Resources(self, class_id, assignment_id, submission_id):
        url = self.api_base_uri + 'education/classes/' + class_id + '/assignments/' + assignment_id + '/submissions/' + submission_id + '/resources'
        return self.rest_api_service.get_object_list(
            url, self.access_token, model=EducationAssignmentResource)

    def add_assignment_resources(self, class_id, assignment_id, fileName,
                                 resourceURL):
        url = self.api_base_uri + "/education/classes/" + class_id + "/assignments/" + assignment_id + "/resources"
        fileType = self.get_fileType(fileName)
        json = {
            "resource": {
                "displayName": fileName,
                "@odata.type": fileType,
                "file": {
                    "odataid": resourceURL
                }
            }
        }
        self.rest_api_service.post_json(url, self.access_token, None, json)

    def add_Submission_Resource(self, class_id, assignment_id, fileName,
                                resourceURL, submission_id):
        url = self.api_base_uri + "/education/classes/" + class_id + "/assignments/" + assignment_id + "/submissions/" + submission_id + "/resources"
        fileType = self.get_fileType(fileName)
        json = {
            "resource": {
                "displayName": fileName,
                "@odata.type": fileType,
                "file": {
                    "odataid": resourceURL
                }
            }
        }

        self.rest_api_service.post_json(url, self.access_token, None, json)

    def get_fileType(self, fileName):
        defaultFileType = "#microsoft.graph.educationFileResource"
        if fileName.find(".docx") != -1:
            defaultFileType = "#microsoft.graph.educationWordResource"
        if fileName.find(".xlsx") != -1:
            defaultFileType = "#microsoft.graph.educationExcelResource"
        return defaultFileType

    def uploadFileToOneDrive(self, ids, file):
        url = "https://graph.microsoft.com/v1.0/drives/" + ids[
            0] + "/items/" + ids[1] + ":/" + file.name + ":/content"

        return self.rest_api_service.put_file(url, self.access_token, file)

    def _get_skip_token(self, nextlink):
        if nextlink:
            matches = self.skip_token_re.findall(nextlink)
            if matches:
                return matches[0]
        return ''
class MSGraphService(object):
    def __init__(self, access_token):
        self.access_token = access_token
        self.api_base_uri = constant.Resources.MSGraph + 'v1.0' + '/'
        self.rest_api_service = RestApiService()

        auth_provider = AuthProvider()
        auth_provider.access_token(self.access_token)
        self.ms_graph_client = msgraph.GraphServiceClient(
            self.api_base_uri, auth_provider, msgraph.HttpProvider())

    def get_o365_user(self, tenant_id):
        me = self._get_me().to_dict()
        org = self._get_organization(tenant_id)

        id = me['id']
        first_name = me['givenName']
        last_name = me['surname']
        display_name = me['displayName']
        email = me['mail']
        if not email:
            email = me['userPrincipalName']
        tenant_name = org['displayName']
        roles = self._get_roles(id)
        photo = '/Photo/UserPhoto/' + id
        return O365User(id, email, first_name, last_name, display_name,
                        tenant_id, tenant_name, roles, photo)

    def get_photo(self, object_id):
        url = self.api_base_uri + 'users/%s/photo/$value' % object_id
        try:
            return self.rest_api_service.get_img(url, self.access_token)
        except:
            return None

    def get_documents(self, object_id):
        url = self.api_base_uri + 'groups/%s/drive/root/children' % object_id
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=Document)

    def get_documents_root(self, object_id):
        url = self.api_base_uri + 'groups/%s/drive/root' % object_id
        document = self.rest_api_service.get_object(url,
                                                    self.access_token,
                                                    model=Document)
        return document.web_url

    def get_conversations(self, object_id):
        url = self.api_base_uri + 'groups/%s/conversations' % object_id
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=Conversation)

    def get_conversations_url(self, conversation_id, section_email):
        return 'https://outlook.office.com/owa/?path=/group/%s/mail&exsvurl=1&ispopout=0&ConvID=%s' % (
            section_email,
            conversation_id,
        )

    def get_conversations_root(self, section_email):
        return 'https://outlook.office.com/owa/?path=/group/%s/mail&exsvurl=1&ispopout=0' % section_email

    def _get_roles(self, user_id):
        roles = []
        # check if the user is an admin
        directory_roles = self._get_directory_roles()
        admin_role = next(
            r for r in directory_roles
            if r.display_name == constant.company_admin_role_name)
        if admin_role:
            members = admin_role.to_dict()['members']
            if any(m for m in members if m['id'] == user_id):
                roles.append(constant.Roles.Admin)
        # check if the user is a faculty or a student
        assigned_licenses = self._get_assigned_licenses()
        for license in assigned_licenses:
            license_id = license['skuId']
            if license_id == constant.O365ProductLicenses.Faculty or license_id == constant.O365ProductLicenses.FacultyPro:
                roles.append(constant.Roles.Faculty)
            if license_id == constant.O365ProductLicenses.Student or license_id == constant.O365ProductLicenses.StudentPro:
                roles.append(constant.Roles.Student)
        return roles

    def _get_me(self):
        return self.ms_graph_client.me.get()

    def _get_assigned_licenses(self):
        url = self.api_base_uri + 'me/assignedLicenses'
        return self.rest_api_service.get_json(url, self.access_token)['value']

    def _get_organization(self, tenant_id):
        url = self.api_base_uri + 'organization/' + tenant_id
        return self.rest_api_service.get_json(url, self.access_token)

    def _get_directory_roles(self):
        expand_members = msgraph.options.QueryOption('$expand', 'members')
        return self.ms_graph_client.directory_roles.request(
            options=[expand_members]).get()
示例#7
0
class AADGraphService(object):
    def __init__(self, tenant_id, access_token):
        self.api_base_uri = constant.Resources.AADGraph + '/' + tenant_id + '/'
        self.access_token = access_token
        self.skip_token_re = re.compile('(?<=skiptoken=).*')
        self.rest_api_service = RestApiService()

    def get_service_principal(self):
        url = self.api_base_uri + "servicePrincipals?api-version=1.6&$filter=appId eq '%s'" % constant.client_id
        app_content = self.rest_api_service.get_json(url, self.access_token)
        return next(iter(app_content['value']), None)

    def delete_service_principal(self, service_principal_id):
        version = '?api-version=1.6'
        url = self.api_base_uri + 'servicePrincipals/%s' % service_principal_id + version
        self.rest_api_service.delete(url, self.access_token)

    def add_app_role_assignments(self, service_principal_id,
                                 service_principal_id_name):
        count = 0
        url = self.api_base_uri + 'users?api-version=1.6&$expand=appRoleAssignments'
        skip_token = None
        while True:
            url2 = url + '&$skiptoken=' + skip_token if skip_token else url
            users_content = self.rest_api_service.get_json(
                url2, self.access_token)
            users = users_content['value']
            skip_token = self._get_skip_token(
                users_content.get('odata.nextLink'))
            for user in users:
                if all(a['resourceId'] != service_principal_id
                       for a in user['appRoleAssignments']):
                    try:
                        self._add_app_role_assignment(
                            user, service_principal_id,
                            service_principal_id_name)
                        count = count + 1
                    except:
                        pass
            if skip_token == None:
                break
        return count

    def _add_app_role_assignment(self, user, service_principal_id,
                                 service_principal_id_name):
        app_role_assignment = {
            'odata.type': 'Microsoft.DirectoryServices.AppRoleAssignment',
            'principalDisplayName': user['displayName'],
            'principalId': user['objectId'],
            'principalType': 'User',
            'resourceId': service_principal_id,
            'resourceDisplayName': service_principal_id_name
        }
        post_url = self.api_base_uri + 'users/%s' % user[
            'objectId'] + '/appRoleAssignments?api-version=1.6'
        self.rest_api_service.post_json(post_url,
                                        self.access_token,
                                        data=app_role_assignment)

    def _get_skip_token(self, nextlink):
        if nextlink:
            matches = self.skip_token_re.findall(nextlink)
            if matches:
                return matches[0]
        return None
示例#8
0
class EducationService(object):
    def __init__(self, tenant_id, access_token):
        self.api_base_uri = constant.Resources.MSGraph + constant.Resources.MSGraph_VERSION + '/'
        self.access_token = access_token
        self.rest_api_service = RestApiService()
        self.skip_token_re = re.compile('\$skiptoken=.*')

    def get_my_school_id(self):
        url = self.api_base_uri + 'me'

        user_content = self.rest_api_service.get_json(url, self.access_token)
        school_id = user_content.get(
            'extension_fe2174665583431c953114ff7268b7b3_Education_SyncSource_SchoolId',
            '')
        return school_id

    def get_school_user_id(self):
        url = self.api_base_uri + 'me'
        user_content = self.rest_api_service.get_json(url, self.access_token)
        sid = user_content.get(
            'extension_fe2174665583431c953114ff7268b7b3_Education_SyncSource_StudentId',
            '')
        tid = user_content.get(
            'extension_fe2174665583431c953114ff7268b7b3_Education_SyncSource_TeacherId',
            '')
        if sid:
            return sid
        elif tid:
            return tid

    def get_schools(self):
        '''
        Get all schools that exist in the Azure Active Directory tenant.
        '''
        url = self.api_base_uri + 'administrativeUnits'
        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     model=School)

    def get_school(self, object_id):
        '''
        Get a school by using the object_id.
        <param name="object_id">The Object ID of the school administrative unit in Azure Active Directory.</param>
        '''
        url = self.api_base_uri + 'administrativeUnits/%s' % object_id
        return self.rest_api_service.get_object(url,
                                                self.access_token,
                                                model=School)

    def get_section_members(self, section_object_id):
        '''
        Get a section members by using the object_id.
        <param name="section_object_id">The Object ID of the section.</param>
        <param name="object_type">The members type.</param>
        '''
        url = self.api_base_uri + 'groups/%s?$expand=members' % section_object_id

        return self.rest_api_service.get_object_list(url,
                                                     self.access_token,
                                                     key='members',
                                                     model=EduUser)

    def get_my_sections(self, school_id):
        '''
        Get my sections within a school
        <param name="school_id">The school id.</param>
        '''
        url = self.api_base_uri + 'me/memberOf'
        section_list = self.rest_api_service.get_object_list(url,
                                                             self.access_token,
                                                             model=Section)
        mysection_list = [
            s for s in section_list if s.education_object_type == 'Section'
            and s.school_id == school_id
        ]

        for section in mysection_list:
            section.members = self.get_section_members(section.id)

        mysection_list.sort(key=lambda d: d.combined_course_number)

        return mysection_list

    def get_sections(self, school_id, top=12, nextlink=''):
        '''
        Get sections within a school
        <param name="school_id">The school id.</param>
        <param name="mysection_emails">All my section's email</param>
        <param name="top">Get record number from API</param>
        <param name="nextlink">Get skiptoken from nextlink</param>
        '''
        skiptoken = self._get_skip_token(nextlink)
        url = self.api_base_uri + "groups?$filter=extension_fe2174665583431c953114ff7268b7b3_Education_ObjectType eq 'Section' and extension_fe2174665583431c953114ff7268b7b3_Education_SyncSource_SchoolId eq '%s'&$top=%s%s" % (
            school_id, top, skiptoken)

        return self.rest_api_service.get_object_list(
            url, self.access_token, model=Section, next_key='@odata.nextLink')

    def get_section(self, object_id):
        '''
        Get a section by using the object_id.
        <param name="object_id">The Object ID of the section.</param>
        '''
        url = self.api_base_uri + 'groups/%s' % object_id
        return self.rest_api_service.get_object(url,
                                                self.access_token,
                                                model=Section)

    def get_members(self, object_id, top=12, nextlink=''):
        '''
        Get members within a school
        <param name="object_id">The Object ID of the school.</param>
        <param name="top">Get record number from API</param>
        <param name="nextlink">Get skiptoken from nextlink</param>
        '''
        skiptoken = self._get_skip_token(nextlink)
        url = self.api_base_uri + 'administrativeUnits/%s/members?$top=%s%s' % (
            object_id, top, skiptoken)
        return self.rest_api_service.get_object_list(
            url, self.access_token, model=EduUser, next_key='@odata.nextLink')

    def get_students(self, school_id, top=12, nextlink=''):
        '''
        Get students within a school
        <param name="school_id">The school id.</param>
        <param name="top">Get record number from API</param>
        <param name="nextlink">Get skiptoken from nextlink</param>
        '''
        skiptoken = self._get_skip_token(nextlink)
        url = self.api_base_uri + "users?$filter=extension_fe2174665583431c953114ff7268b7b3_Education_SyncSource_SchoolId eq '%s' and extension_fe2174665583431c953114ff7268b7b3_Education_ObjectType eq 'Student'&$top=%s%s" % (
            school_id, top, skiptoken)
        return self.rest_api_service.get_object_list(
            url, self.access_token, model=EduUser, next_key='@odata.nextLink')

    def get_teachers(self, school_id, top=12, nextlink=''):
        '''
        Get teachers within a school
        <param name="school_id">The school id.</param>
        <param name="top">Get record number from API</param>
        <param name="nextlink">Get skiptoken from nextlink</param>
        '''
        skiptoken = self._get_skip_token(nextlink)
        url = self.api_base_uri + "users?$filter=extension_fe2174665583431c953114ff7268b7b3_Education_SyncSource_SchoolId eq '%s' and extension_fe2174665583431c953114ff7268b7b3_Education_ObjectType eq 'Teacher'&$top=%s%s" % (
            school_id, top, skiptoken)

        return self.rest_api_service.get_object_list(
            url, self.access_token, model=EduUser, next_key='@odata.nextLink')

    def _get_skip_token(self, nextlink):
        if nextlink and nextlink.find('skiptoken') != -1:
            link_skiptoken = self.skip_token_re.findall(nextlink)[0]
            return '&%s' % link_skiptoken
        return ''