• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

uw-it-aca / canvas-sis-provisioner / 6698520699

30 Oct 2023 08:45PM UTC coverage: 56.318% (+0.02%) from 56.295%
6698520699

Pull #911

github-actions

web-flow
Merge branch 'main' into develop
Pull Request #911: Develop

25 of 25 new or added lines in 5 files covered. (100.0%)

4573 of 8120 relevant lines covered (56.32%)

0.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.64
/sis_provisioner/dao/user.py
1
# Copyright 2023 UW-IT, University of Washington
2
# SPDX-License-Identifier: Apache-2.0
3

4

5
from django.conf import settings
1✔
6
from uw_pws import PWS
1✔
7
from uw_gws import GWS
1✔
8
from uw_gws.models import GroupEntity
1✔
9
from uw_gws.exceptions import InvalidGroupID
1✔
10
from restclients_core.exceptions import DataFailureException
1✔
11
from sis_provisioner.exceptions import (
1✔
12
    UserPolicyException, MissingLoginIdException, TemporaryNetidException,
13
    InvalidLoginIdException)
14
import re
1✔
15

16
RE_ADMIN_NETID = re.compile(r"^[a-z]adm_[a-z][a-z0-9]{0,7}$", re.I)
1✔
17
RE_APPLICATION_NETID = re.compile(r"^a_[\w]{1,18}$", re.I)
1✔
18
RE_TEMPORARY_NETID = re.compile(
1✔
19
    r"^(?:wire|event|lib|lawlib|uwctc)[0-9]{4,}$", re.I)
20
RE_CANVAS_ID = re.compile(r"^\d+$")
1✔
21

22

23
def is_group_member(group_id, login_id, act_as=None, is_effective=False):
1✔
24
    return GWS(act_as=act_as).is_member(group_id, login_id, is_effective)
1✔
25

26

27
def is_group_admin(group_id, login_id):
1✔
28
    user = GroupEntity(name=login_id, type=GroupEntity.UWNETID_TYPE)
1✔
29
    group = GWS().get_group_by_id(group_id)
1✔
30
    return (user in group.admins or user in group.updaters)
1✔
31

32

33
def valid_net_id(login_id):
1✔
34
    if not login_id:
1✔
35
        raise MissingLoginIdException('Missing UWNetID')
1✔
36

37
    if RE_TEMPORARY_NETID.match(login_id):
1✔
38
        raise TemporaryNetidException('Temporary UWNetID not permitted')
1✔
39

40
    if not PWS().valid_uwnetid(login_id):
1✔
41
        raise InvalidLoginIdException('Not a valid UWNetID')
1✔
42

43

44
def valid_admin_net_id(login_id):
1✔
45
    if RE_ADMIN_NETID.match(login_id) is None:
1✔
46
        raise InvalidLoginIdException('Not a valid Admin UWNetID')
1✔
47

48

49
def valid_application_net_id(login_id):
1✔
50
    if RE_APPLICATION_NETID.match(login_id) is None:
1✔
51
        raise InvalidLoginIdException('Not a valid Application UWNetID')
1✔
52

53

54
def valid_nonpersonal_net_id(netid):
1✔
55
    try:
1✔
56
        valid_admin_net_id(netid)
1✔
57
    except UserPolicyException:
1✔
58
        try:
1✔
59
            valid_application_net_id(netid)
1✔
60
        except InvalidLoginIdException:
1✔
61
            group = getattr(settings, 'NONPERSONAL_NETID_EXCEPTION_GROUP', '')
1✔
62
            try:
1✔
63
                if not is_group_member(group, netid):
1✔
64
                    raise InvalidLoginIdException('UWNetID not permitted')
1✔
65
            except InvalidGroupID:
1✔
66
                raise InvalidLoginIdException('UWNetID not permitted')
1✔
67

68

69
def valid_reg_id(regid):
1✔
70
    if not PWS().valid_uwregid(regid):
1✔
71
        raise InvalidLoginIdException('UWNetID not permitted')
1✔
72

73

74
def valid_gmail_id(login_id):
1✔
75
    try:
1✔
76
        (username, domain) = login_id.lower().split("@")
1✔
77
        username = username.split("+", 1)[0].replace(".", "")
1✔
78
        if not len(username):
1✔
79
            raise InvalidLoginIdException(
1✔
80
                "Invalid username: {}".format(login_id))
81
    except Exception:
1✔
82
        raise InvalidLoginIdException("Invalid username: {}".format(login_id))
1✔
83

84
    if domain not in ['gmail.com', 'google.com', 'googlemail.com']:
1✔
85
        raise InvalidLoginIdException("Invalid domain: {}".format(login_id))
1✔
86

87
    return "{}@{}".format(username, domain)
1✔
88

89

90
def valid_canvas_user_id(canvas_id):
1✔
91
    if (RE_CANVAS_ID.match(str(canvas_id)) is None):
1✔
92
        raise UserPolicyException("Invalid Canvas ID: {}".format(canvas_id))
1✔
93

94

95
def user_sis_id(user):
1✔
96
    return user.uwregid if hasattr(user, 'uwregid') else user.sis_user_id
1✔
97

98

99
def user_email(user):
1✔
100
    if hasattr(user, 'uwnetid') and user.uwnetid is not None:
1✔
101
        return '{}@uw.edu'.format(user.uwnetid)
1✔
102
    elif hasattr(user, 'email'):
1✔
103
        return user.email  # CanvasUser
×
104
    else:
105
        raise UserPolicyException('Invalid user')
1✔
106

107

108
def user_fullname(user):
1✔
109
    try:
1✔
110
        return user.get_first_last_name()
1✔
111
    except AttributeError:
1✔
112
        if hasattr(user, 'display_name'):
1✔
113
            return (user.display_name,)  # UW Entity
1✔
114
        elif hasattr(user, 'sis_user_id'):
1✔
115
            return (user.email.split('@')[0],)  # CanvasUser
×
116
        else:
117
            raise UserPolicyException('Invalid user')
1✔
118

119

120
def can_access_canvas(netid):
1✔
121
    login_group_id = getattr(settings, 'ALLOWED_CANVAS_LOGIN_USERS', '')
1✔
122
    try:
1✔
123
        if not is_group_member(login_group_id, netid, is_effective=True):
1✔
124
            raise UserPolicyException('UWNetID not permitted')
1✔
125
    except InvalidGroupID:
1✔
126
        raise UserPolicyException('UWNetID not permitted')
×
127
    return True
1✔
128

129

130
def get_person_by_netid(netid):
1✔
131
    pws = PWS()
1✔
132
    try:
1✔
133
        valid_net_id(netid)
1✔
134
        person = pws.get_person_by_netid(netid)
1✔
135

136
        if person.is_test_entity:
1✔
137
            valid_nonpersonal_net_id(netid)
1✔
138

139
    except DataFailureException as err:
1✔
140
        if err.status == 404:  # Non-personal netid?
1✔
141
            valid_nonpersonal_net_id(netid)
1✔
142
            person = pws.get_entity_by_netid(netid)
1✔
143
        else:
144
            raise
×
145

146
    return person
1✔
147

148

149
def get_person_by_regid(regid):
1✔
150
    pws = PWS()
1✔
151
    try:
1✔
152
        person = pws.get_person_by_regid(regid)
1✔
153
        valid_net_id(person.uwnetid)
1✔
154

155
        if person.is_test_entity:
1✔
156
            valid_nonpersonal_net_id(person.uwnetid)
1✔
157

158
    except DataFailureException as err:
1✔
159
        if err.status == 404:  # Non-personal regid?
1✔
160
            person = pws.get_entity_by_regid(regid)
1✔
161
            valid_nonpersonal_net_id(person.uwnetid)
×
162
        else:
163
            raise
×
164

165
    return person
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc