Skip to content

Commit 4f99dfe

Browse files
Merge pull request #533 from hotosm/hotfix/login
HOTFIX : Fixes login Issue
2 parents fe9dbb2 + 6cc808e commit 4f99dfe

File tree

8 files changed

+116
-42
lines changed

8 files changed

+116
-42
lines changed

.github/workflows/ci.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ jobs:
1919

2020
- name: Install gdal
2121
run: |
22-
sudo apt-add-repository ppa:ubuntugis/ubuntugis-unstable
2322
sudo apt-get update
24-
sudo apt-get install libgdal-dev osmctools gdal-bin libspatialindex-dev
23+
sudo apt-get install -y osmium-tool
24+
sudo apt-get install python3-dev build-essential cmake libboost-dev \
25+
libexpat1-dev zlib1g-dev libbz2-dev libgdal-dev gdal-bin libspatialindex-dev osmctools
2526
2627
- name: Install Dependencies
2728
run: |

core/settings/contrib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
SOCIAL_AUTH_OPENSTREETMAP_LOGIN_URL = "/osm/login/"
4646
SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY = os.getenv("OSM_API_KEY")
4747
SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET = os.getenv("OSM_API_SECRET")
48-
SOCIAL_AUTH_LOGIN_REDIRECT_URL = "/"
48+
SOCIAL_AUTH_LOGIN_REDIRECT_URL = "/authorized"
4949
SOCIAL_AUTH_LOGIN_ERROR_URL = "/osm/error"
5050
SOCIAL_AUTH_URL_NAMESPACE = "osm"
5151
SOCIAL_AUTH_ADMIN_USER_SEARCH_FIELDS = ["username", "first_name", "email"]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mercantile~=0.10.0
1111
psycopg2
1212
python3-openid==3.2.0
1313
social-auth-app-django==5.4.0
14-
social-auth-core @ git+https://github.com/kshitijrajsharma/social-core.git ### Upgrade this to include osm oauth2 when released
14+
social-auth-core==4.7.0
1515
pytz
1616
pyyaml>=5.3
1717
raven

ui/app/actions/meta.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import axios from "axios";
2-
import { LOGIN_SUCCESS, login as _login, logout } from "redux-implicit-oauth2";
2+
import { LOGIN_SUCCESS, logout as _logout } from "redux-implicit-oauth2";
33

44
import { selectAuthToken } from "../selectors";
55
import types from ".";
@@ -32,7 +32,7 @@ if (window.OAUTH_CLIENT_ID == null) {
3232

3333
const oauthConfig = {
3434
// url: window.EXPORTS_API_URL + "/o/openstreetmap_oauth2",
35-
url: window.EXPORTS_API_URL + "/o/authorize?approval_prompt=auto",
35+
url: window.EXPORTS_API_URL + "/o/authorize?approval_prompt=auto&response_type=token",
3636
client: window.OAUTH_CLIENT_ID,
3737
redirect: `${window.location.protocol}//${hostname}/authorized`
3838
};
@@ -95,7 +95,13 @@ export const fetchGroups = () => (dispatch, getState) => {
9595
);
9696
};
9797

98-
export const login = () => _login(oauthConfig);
98+
export const login = () => {
99+
const { url, client, redirect } = oauthConfig;
100+
window.location.href =
101+
url +
102+
`&client_id=${client}` +
103+
`&redirect_uri=${encodeURIComponent(redirect)}`;
104+
};
99105

100106
export const loginSuccess = (token, expiresAt) => dispatch =>
101107
dispatch({
@@ -104,4 +110,8 @@ export const loginSuccess = (token, expiresAt) => dispatch =>
104110
expiresAt
105111
});
106112

107-
export { logout };
113+
export const logout = () => dispatch => {
114+
localStorage.removeItem("access_token");
115+
localStorage.removeItem("expires_at");
116+
dispatch(_logout());
117+
};

ui/app/components/Auth.js

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,63 @@
1-
import { Component } from "react";
1+
import React from "react";
22
import { connect } from "react-redux";
3+
import { withRouter } from "react-router-dom";
34

45
import { fetchPermissions, loginSuccess } from "../actions/meta";
56
import { selectIsLoggedIn, selectLocationHash } from "../selectors";
6-
import { history } from "../config/store";
77

8-
class Auth extends Component {
8+
class Auth extends React.Component {
99
componentDidMount() {
1010
const {
11-
fetchPermissions,
1211
hash: { access_token, expires_in },
1312
isLoggedIn,
14-
loginSuccess
13+
loginSuccess,
14+
fetchPermissions,
15+
history,
16+
location
1517
} = this.props;
1618

19+
if (access_token) {
20+
const expiresAt = expires_in
21+
? Date.now() + parseInt(expires_in, 10) * 1000
22+
: null;
23+
24+
loginSuccess(access_token, expiresAt);
25+
localStorage.setItem("access_token", access_token);
26+
if (expiresAt) localStorage.setItem("expires_at", expiresAt);
27+
28+
fetchPermissions();
29+
30+
window.location.hash = "";
31+
history.replace(location.pathname);
32+
return;
33+
}
34+
35+
36+
if (!isLoggedIn) {
37+
const storedToken = localStorage.getItem("access_token");
38+
const storedExpiry = localStorage.getItem("expires_at");
39+
if (storedToken) {
40+
const storedExpiresAt = storedExpiry
41+
? parseInt(storedExpiry, 10)
42+
: null;
43+
if (!storedExpiresAt || storedExpiresAt > Date.now()) {
44+
loginSuccess(storedToken, storedExpiresAt);
45+
} else {
46+
// expired
47+
localStorage.removeItem("access_token");
48+
localStorage.removeItem("expires_at");
49+
}
50+
}
51+
}
1752
if (isLoggedIn) {
1853
fetchPermissions();
19-
} else if (access_token != null) {
20-
loginSuccess(access_token, expires_in);
21-
history.replace("/");
2254
}
2355
}
2456

25-
componentWillUpdate(nextProps, nextState) {
26-
const { fetchPermissions, isLoggedIn: wasLoggedIn } = this.props;
27-
const { isLoggedIn } = nextProps;
57+
componentDidUpdate(prevProps) {
2858

29-
if (!wasLoggedIn && isLoggedIn) {
30-
fetchPermissions();
59+
if (!prevProps.isLoggedIn && this.props.isLoggedIn) {
60+
this.props.fetchPermissions();
3161
}
3262
}
3363

@@ -41,6 +71,9 @@ const mapStateToProps = state => ({
4171
isLoggedIn: selectIsLoggedIn(state)
4272
});
4373

44-
export default connect(mapStateToProps, { fetchPermissions, loginSuccess })(
45-
Auth
46-
);
74+
export default withRouter(
75+
connect(
76+
mapStateToProps,
77+
{ fetchPermissions, loginSuccess }
78+
)(Auth)
79+
);

ui/app/components/Authorized.js

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,41 @@
11
import React from "react";
2-
import { FormattedMessage } from "react-intl";
3-
4-
export default () =>
5-
<div>
6-
<FormattedMessage
7-
id="ui.authorized.thank_you"
8-
defaultMessage="Thank you for authorizing!"
9-
/>
10-
</div>;
2+
import { connect } from "react-redux";
3+
import { withRouter } from "react-router-dom";
4+
import { loginSuccess } from "../actions/meta";
5+
6+
class Authorized extends React.Component {
7+
componentDidMount() {
8+
// grab the hash fragment (e.g. "#access_token=…&expires_in=…")
9+
const hash = window.location.hash.replace(/^#/, "");
10+
const params = new URLSearchParams(hash);
11+
const token = params.get("access_token");
12+
const expiresIn = params.get("expires_in");
13+
14+
if (token) {
15+
16+
const expiresAt = expiresIn
17+
? Date.now() + parseInt(expiresIn, 10) * 1000
18+
: null;
19+
20+
21+
this.props.loginSuccess(token, expiresAt);
22+
23+
window.location.hash = "";
24+
this.props.history.replace("/");
25+
} else {
26+
// no token then bounce back ..
27+
this.props.history.replace("/");
28+
}
29+
}
30+
31+
render() {
32+
return null;
33+
}
34+
}
35+
36+
export default withRouter(
37+
connect(
38+
null,
39+
{ loginSuccess }
40+
)(Authorized)
41+
);

ui/app/components/Message.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ class Message extends Component {
2121
return null;
2222
}
2323
return (
24-
<div className="banner" style={{ backgroundColor: "#ffcc00", color: "black", textAlign: "center", padding: "10px", position: "relative" }}>
25-
<p>We have recently upgraded from OAuth 1.0 to 2.0. Please Logout and Login again before use!</p>
26-
<button onClick={this.handleClose} style={{ position: "absolute", top: "5px", right: "10px", cursor: "pointer" }}>
27-
×
28-
</button>
29-
</div>
30-
);
24+
<div className="banner" style={{ backgroundColor: "#ffcc00", color: "black", textAlign: "center", padding: "10px", position: "relative" }}>
25+
<p>If you are experiencing issues logging in after our fixes, please logout and login again to resolve the issue.</p>
26+
<button onClick={this.handleClose} style={{ position: "absolute", top: "5px", right: "10px", cursor: "pointer" }}>
27+
×
28+
</button>
29+
</div>
30+
);
3131
}
3232
}
3333

ui/views.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ def authorized(request):
2323
# be logged into the site (and it will be confusing if they are, since
2424
# "logging out" of the UI just drops the auth token)
2525
auth_logout(request)
26-
return render(request, "ui/authorized.html")
27-
26+
return v3(request)
2827

2928
def login(request):
3029
if not request.user.is_authenticated:

0 commit comments

Comments
 (0)